为什么当我添加线程时 Android OpenGL ES 渲染会得到改善?

问题描述 投票:0回答:1

在我提出问题之前,如果你想查看所有代码,就在这里......

https://github.com/spencerparkin/GravityMaze

(尽量不要因为这是一个愚蠢的应用程序这一事实而烦恼。)

现在回答问题...

我的应用程序只不过是绘制各种颜色的线条。事实上,所有这些都是在一次绘制调用中完成的。此外,如果我注释掉该绘制调用并仅清除颜色缓冲区和交换,我的渲染仍然很慢。我的 FPS 计数器显示我通常在 100 FPS 左右,但动画无疑证明我的渲染速度很慢。

快进几天。我决定押注于性能并添加一些 MIDI 音乐。 MIDI 播放器除了向端口发送 MIDI 消息外什么也不做。它添加到主线程的开销非常小,我不相信它会影响性能。然而,这证实了我的主循环很慢,因为这样做之后,不仅渲染仍然很慢(这并不奇怪),而且音乐播放也很慢,而且节奏不恒定。我再次注释掉了渲染代码(只留下了eglSwapBuffers()调用),这样就没有渲染任何东西,而且音乐仍然很慢。 (这并不奇怪,缓慢的音乐只是证实了主线程缓慢的问题。)

好的,现在明白了。我决定妥协。我的渲染速度很慢,但我希望音乐以正确且一致的速率播放。因此,我努力将 MIDI 播放卸载到自己的线程,这样它就不会受到主线程当前存在的缓慢问题的影响。好吧你猜怎么着?完成此操作后,我的主线程和 MIDI 线程现在都以合理的帧速率运行!现在渲染速度已经达到了我想要的速度!我的 FPS 现在约为 40(低于 100?!),但渲染速度确实快得多。 >大脑爆炸! 有谁知道这里到底发生了什么事吗?将 MIDI 播放卸载到其自己的线程并不能提高渲染性能。 (同样,当渲染性能仍然很慢时,MIDI 并不存在。)似乎唯一“真正”的区别是附加线程的存在。为什么额外的线程会导致我的主线程更快地渲染 OpenGL ES?<

在我的分析中,我怀疑 eglSwapBuffers() 调用是瓶颈。 我相信,我正在 API 级别 29 的 Android 10 上进行测试。

有什么想法吗?

谢谢, ——斯宾塞

@Morrison Change 给我指出了正确的答案。

android c++ opengl-es android-ndk
1个回答
0
投票

这就是我所做的...

我在 android_main() 的开头创建了一个新线程,它绝对不执行任何操作!严重地!它绝对没有做任何事情!这导致我的渲染和动画性能显着提高(出于尚不清楚的原因),但我并没有就此止步。

  1. 我将所有游戏逻辑移至新线程(我现在将其称为“游戏”线程)。这包括物理、动画、游戏逻辑和碰撞检测。音频输出、传感器输入和渲染保留在 android_main() 线程中,我现在将其称为“渲染”线程。

  2. 根据视频,当我的游戏线程进入“渲染”状态时,它只是将帧对象添加到由渲染线程消耗的线程安全列表中。同样,从视频中,我采取的策略是,如果渲染线程太慢,则让渲染线程丢弃帧,或者如果渲染线程太快,则将同一帧渲染两次,与游戏线程相关。

  3. 就是这样。这看起来效果非常好。然而,所有这一切需要注意的是,由于这从一开始就不是我的策略,因此我必须非常厌倦无意中引入线程问题。到目前为止一切似乎都很稳定。

  4. 再次感谢。

© www.soinside.com 2019 - 2024. All rights reserved.