Finding possible performance bottleneck

Hey, recently I have been trying to play the game I am developing on the phone and I have noticed that at some point the FPS start to drop (the game itself is being made in LibGDX and currently with all assets is around 25MB). On the desktop version I do not see that it drop FPS… In order to start finding the source of the problem I enabled GLProfiler and started to collect Heap and Native memory data. The memory does not seem to grow (which I believe is already a good sign). However the GLProfiler reports different things on Desktop and Android application versions. On Desktop version I can see that number of calls, draw calls and texture bindings remains constant while I am playing the game. On Android, on another hand, I see the same metrics increasing very fast… I would like to know is that is anyhow the indicator that I have some problem with the Android version? What else I can use to determine the possible source of the downgrading performance? Any feedback is highly appreciated :).

After not being able to sleep a night I managed to solve some performance issues with culling (I was imagining the existence of such feature but did not even bother to search and experiment before I hit some performance issues…). Nevertheless the question on GLProfiler still remains open…

[quote]What else I can use to determine the possible source
[/quote]
Shave off stuff stuff until the problem stops, then you know what to examine further.
You can’t debug if there’s to much going on at once.

Shave off stuff stuff until the problem stops, then you know what to examine further.
You can’t debug if there’s to much going on at once.
[/quote]
Following your advice I think I found the reason. I have basically the archers shooting the arrows and I calculate the rotation angle every frame (the respective image actor is rotated also every frame). I will try to cut the number of rotation, not like every frame but every N frames.

That doesn’t sound like you found the real reason, are you sure that the problem you encountered is really linked to rotating actors?
Rotating actors/sprites should not use any extra gl calls, since it’s done on the CPU if you use the spritebatch.

Are you sure you aren’t just spawning stuff somewhere? Maybe duplicates of the arrows, etc?

I have been around performance issues the whole day… Several things which I believe I made which improved the situation:

  1. I merged several texture atlases into the same one, so the application is using a single atlas with multiple pages now
  2. I reduced the number of collision detection calculations (by a lot) with a simple condition (this was actually a huge improvement)
  3. In some places I was creating a new font instead of reusing the pre-defined one

Finally, I still was not happy with performance so I did a simple benchmark. I have quite crappy Android phone (one of the cheapest Samsung ones, simply because I have not been using phone for the last three years, I just bought something to test the game). So I basically created a screen with a stage and added to it 150 Image objects in the visible screen (something which the game was struggling with)… Well, the simple benchmark application was also struggling with this number of actors on the screen (running at aprox 20 FPS)… The benchmarks with SpriteBatch instead of Stage has shown similar results… On one side I am happy because I observe very similar performance limitation, on another hand I am not, because it means that I will need to thing about game mechanics which will prevent the user from maintaining that many actors in the same location. On PC I observed the same performance drop at around 500 actors on the same screen, which makes sense, because the hardware of the phone is much less powerful…

Do these conclusions make any sense now :P? Or I am still missing something?

Didn’t you say the number of gl calls were constanty increasing on android while they were stable on pc?

Is this still occuring or did you mean something else with that?

Ahh yeah I forgot about that… I was going to post but decided to do more test instead of constantly bothering… This is still something I do not understand… The simple code as the following:


public class BenchmarkScreen implements Screen, InputProcessor {

	private BitmapFont font;
	private SpriteBatch spriteBatch;
	
	public BenchmarkScreen() {
		font = new BitmapFont();
		spriteBatch = new SpriteBatch();
		
		GLProfiler.enable();
	}

	@Override
	public void render(float delta) {
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		
		spriteBatch.begin();
		font.draw(spriteBatch, "FPS: " + Gdx.graphics.getFramesPerSecond(), 20, Gdx.graphics.getHeight() - 20);
		font.draw(spriteBatch, "Objects: " + count, 20, Gdx.graphics.getHeight() - 40);
		font.draw(spriteBatch, "Calls: " + GLProfiler.calls, 20, Gdx.graphics.getHeight() - 60);
		font.draw(spriteBatch, "Draw calls: " + GLProfiler.drawCalls, 20, Gdx.graphics.getHeight() - 80);
		font.draw(spriteBatch, "Texture bindings: " + GLProfiler.textureBindings, 20, Gdx.graphics.getHeight() - 100);
		spriteBatch.end();
	}
}

On the PC shows 22 calls, 1 draw call and 1 texture binding, while on Android all of those are constantly increasing…
The main class is:


public class Main extends Game {
	@Override
	public void create() {
		setScreen(new BenchmarkScreen());
	}
	
	@Override
	public void render() {
		super.render();
	}
}

And the Android launcher as simple as:


public class AndroidLauncher extends AndroidApplication {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
		initialize(new Main(), config);
	}
}

I have no idea what can cause such a difference if GLProfiler behavior…

Maybe the gl profiler just doesn’t get reset on android ;D
If the gl calls would really increase constantly you would always see a slowdown after a certain time, no matter how little or much you draw each frame.

From what I see you never call GLProfiler.reset().

-ClaasJG

Yes I never do, but in this case shouldn’t it also accumulate the counts on the PC? Because on PC the counts remain constant after I start the application…