我正在使用OpenGL ES 3.0开发动态壁纸。我根据http://www.learnopengles.com/how-to-use-opengl-es-2-in-an-android-live-wallpaper/的优秀教程进行设置,调整GLSurfaceView并在动态壁纸中使用它。
我对OpenGL / GLSL最佳实践有很好的了解,并且我已经设置了一个简单的渲染管道,其中绘制循环尽可能紧密。没有重新分配,使用一个静态VBO用于非变化数据,一个动态VBO用于更新,仅使用一个绘制调用,在着色器等中没有分支。我通常会获得非常好的表现,但在看似随机但又重复的时候,帧速率会下降。
使用屏幕上的条形图进行分析可以得到黄色条("等待命令完成")的间隔,并将所有内容都高于关键的60fps阈值。
我已经阅读了有关分析和解释我可以获得的数字的任何资源,包括深入的SO question here。但是,该问题的主要内容似乎是黄色条表示花费在等待阻止操作完成和帧依赖性上的时间。我不相信我有任何这些,我只是在每一帧画出一切。 没有阅读。
我的问题很广泛 - 但我想知道什么事情会导致这种类型的帧率下降,以及如何在确定问题时继续前进。
以下是可能会或可能不会产生影响的一些细节:
更新 作为实验,我尝试仅渲染每隔一帧,而不是每次onOffsetsChanged(向左/向右滑动)请求渲染。这对于外观和感觉来说太可怕了,但几乎完全摆脱了黄色的滞后尖峰。这似乎告诉我每帧60次请求太多了,但我无法弄清楚原因。
答案 0 :(得分:1)
我的问题很广泛 - 但我想知道会有什么因素导致这种情况发生 帧率下降的类型,以及如何向下移动 问题。
(1)渲染状态的累积。确保在开始每个渲染过程之前“glClear”颜色/深度/模板缓冲区(尽管如果直接渲染到窗口表面,这不太可能是问题,因为除非您设置状态,否则保证每帧都清除状态EGL_BUFFER_PRESERVE)。
(2)缓冲/纹理重影。渲染是深度流水线的,但OpenGL ES试图呈现同步编程抽象。如果您尝试写入缓冲区(SubBuffer更新,SubTexture更新,MapBuffer等)仍在“待定”中使用仍然在管道中排队的GPU操作,那么您必须要阻止并等待,或者您强制复制要创建的资源。对于大型资源,此复制过程可能“非常昂贵”。
(3)设备DVFS(动态频率和电压缩放)在某些设备上可能非常敏感,尤其是对于恰好位于两个频率之间的水平决策点附近的内容。如果GPU或CPU频率下降,那么您可能会在帧处理的时间内出现峰值。出于调试目的,某些设备提供了通过sysfs修复频率的方法 - 尽管没有标准的机制。
(4)散热限制 - 如果一切都以高频率运行,大多数现代移动设备可以产生比散热更多的热量,因此最大性能点无法持续。如果您的内容特别沉重,那么您可能会发现热管理在“一段时间”后开始(根据我的经验,1-10分钟取决于设备)并强制降低频率,直到热量水平下降到安全范围内。这表示帧处理时间有点随机增加,并且一旦设备达到“暖”状态,通常是不可预测的。如果可以共享再现问题的API序列,那么提供更有针对性的建议会更容易 - 这个问题非常普遍,OpenGL ES是一个非常广泛的API;)