Android LibGDX游戏:由于长EGLImpl.eglSwapBuffers调用,FPS下降

时间:2014-09-15 15:42:30

标签: java android opengl-es libgdx frame-rate

我正在使用Java和LibGDX引擎开发Android平台游戏。

我遇到了一个奇怪的问题,我的游戏中的FPS每隔30-40秒从57-60帧下降到40-45帧,然后又回来了。下面是logcat输出的截图。垃圾收集器在这些时刻没有工作(没有从日志中过滤掉任何内容):

LogCat part 1

LogCat part 2

我做了一些分析,发现问题的发生是因为EGLImpl.eglSwapBuffers调用每30-40秒比平常花费更多时间。在下面的屏幕截图中(在没有任何反应时分析游戏菜单时拍摄)需要3,7毫秒:

Profiling of game menu

在我的渲染循环菜单中,我只调用MyStage.act()和MyStage.draw()绘制一组ImageButtons - 没什么特别的。菜单的帧渲染时间(平均17ms)对于这种简单的渲染来说似乎也太长了,但是这些stange周期性长缓冲区交换调用现在是我主要考虑的问题。

顺便说一句,如果我在游戏过程中进行分析会变得更糟 - 这些EGLImpl.eglSwapBuffers调用需要15ms甚至更多时间并将FPS降至30并且不断地将其保持在那里:

profiling during the gameplay

我真的可以就如何调查此问题提出一些建议。

1 个答案:

答案 0 :(得分:4)

您需要了解交换缓冲区的含义。这意味着您告诉OpenGL您已完成发送所有“渲染命令”,并且现在可以将完成的渲染图像发送到屏幕以显示它。

这意味着什么?这意味着你的显卡已经完成了渲染!大多数GL呼叫将立即返回而不会阻塞。这意味着你的CPU继续工作,GPU将并行工作,处理从CPU接收到的渲染命令队列。

现在,如果您的CPU能够比GPU快得多,交换缓冲区意味着GPU必须先完成处理整个队列才能实际交换缓冲区并返回。

总的来说,这意味着问题不是实际的eglSwapBuffers需要花费很多时间,而是因为你的GPU无法跟上CPU。这意味着您的场景太复杂,例如,您有太多的状态更改,如纹理绑定,着色器切换或类似的事情。

因此,通过剖析CPU端,您将无法真正找到真正的问题。但我无法真正告诉你问题出在哪里。由于您使用的是libGDX,GLProfiler可能会对您有帮助。

PS:由于您的设备切换到节能模式,FPS也可能会突然发生变化。