3
votes

I'm working on a game for Android platform, using Java and LibGDX engine.

I've run into an odd issue where FPS in my game drops contantly every 30-40 seconds from 57-60 to 40-45 frames and then gets back. Below are screenshots of logcat output. Garbage Collector is not working at these moments (there is nothing filtered from the log):

LogCat part 1

LogCat part 2

I've done some profiling and found out that the problem occurs because of EGLImpl.eglSwapBuffers calls that every 30-40 seconds take more time than usual. On the screenshot below (taken while profiling game menu when nothing happens at all) it takes 3,7ms:

Profiling of game menu

In my rendeing cycle for the menu I just call MyStage.act() and MyStage.draw() which draw a set of ImageButtons - nothing special. My frame render time for the menu (17ms average) also seems too long for such simple rendering, but these stange periodic long buffer swap calls are my main concern now.

By the way if I profile during the gameplay it becomes worse - these EGLImpl.eglSwapBuffers calls take 15ms and more and drop FPS to 30 and keep it there constantly:

profiling during the gameplay

I could really use some advice on how to investigate this.

1
Update: I have optimized menu rendering frame - now it takes just 7ms, but still EGLImpl.eglSwapBuffers takes 11ms for some reason and keeps FPS around 50 with periodic drops to 44-46. From what I have read on the Internet I have assumed that eglSwapBuffers should "align" graphic output to 16ms per frame, hence if frame is rendered faster than 16ms, resulting FPS should be 60...Lez77

1 Answers

4
votes

You need to understand what what swapping the buffers means. It means that you tell OpenGL that you are done with sending all "rendering commands" and that it may now send the finished rendered image to the screen to display it.

What does that imply? It implies that your graphics card has finished rendering everything! Most GL calls will immediately return without blocking. That means that your CPU and keep working and the GPU will work in parallel, processing its queue of received rendering commands from the CPU.

Now in case your CPU is able to finish much faster than your GPU, swapping the buffers means that the GPU has to finish processing the whole queue before it can actually swap the buffers and return.

In total that means that the problem is not the actual eglSwapBuffers that takes so much time, but just that your GPU cannot keep up with the CPU. It means that your scene is just too complex for example, that you have too many state changes, like texture bindings, shader switches or things like that.

So by profiling the CPU side, you won't really find the real problem. But I can't really tell you where the problem is. Since you are using libGDX, GLProfiler might help you here.

PS: A sudden change in the FPS might also be cause due to your device switching to energy saving mode.