It seems that my 2D platformer game is becoming slower over time. I decided to check out LibGDX since it was up to date with newer versions of opengl, runs smoothly, and acts as more of an optional abstraction around the pipeline. I haven’t run into any noticeable performance issues, but I have seen my cpu reach 19% over time. To be specific, when I first launch the game, it runs quickly and efficiently. Only about 2% of the cpu is being used at most. After about 30 seconds, it’s 4%. Then, after a minute, it peaks to about 19%. It never goes beyoind that number, and the fps never drops. I can hear my fan going nuts, though, so it is still a problem.
I made a simple but effective performance logger that records the amount of time it takes to complete a task. After about, say, 60 recordings, since my game’s fps is 60, I log a message to a PrintStream regarding the average amount of time it took to complete the task. I narrowed down where the performance degrades, and it’s in LibGDX’s SpriteBatch class. Invocations of end() start to become slow after a while, but I am not sure why. Here the the method utilizing SpriteBatch that sees performance issues.
public void render(Matrix4 m, float parentAlpha)
{
// Optimizes the grid so that only the tiles that are visible are displayed
if(optimized)
optimize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
// Grabs SpriteBatch from globally accessible Renderer
SpriteBatch batch = Renderer.getSpriteBatch();
// Sets alpha to the one accumulated through the scene graph
batch.setColor(1, 1, 1, parentAlpha);
// Begins drawing
batch.begin();
// Renders all tiles within optimized range. Mins and maxes were determine when optimize() was invoked
for(int y=minY; y<maxY; y++)
{
for(int x=minX; x<maxX; x++)
{
TextureRegion reg = get(x, y);
if(reg != null)
{
batch.draw(reg, x*regWidth, y*regHeight);
}
}
}
// Ends drawing
logger.begin(); // Begins recording the amount of time it takes to complete batch.end()
batch.end();
logger.end(); // Ends recording, and outputs the average amount of time it took to complete after 60 invocations.
}
Ok, not all variables are defined in this example, but I think what is happening here should be clear. I have a matrix of tiles that I want to render, and the tiles are an array of TextureRegions. When rendering, I iterate through the matrix from the top left to the bottom right horizontally before vertically. When I am done rendering this batch, I invoke batch.end(). I have proven that the degredation occurs specifically at the invocation of batch.end(), because the amount of time it takes to do this after about a minute is 17-18 milliseconds, which composes the majority of the aforementioned slowdown.
Why would this method behave like an angel, and then suddenly slow down later? I can’t really focus my logger on a particular part of this method since it’s part of LibGDX. Is there some way that I could be misusing SpriteBatch here, or somewhere else? I’m still fairly new to LibGDX, so I would not be surprised.
Edit: I am aware that SpriteBatch’s end() method uploads vertices and texture ids to opengl that were gathered earlier. I feel like somehow, my batch is accumulating vertices/id’s/SOMETHING, and perhaps I am forgetting to clear that something.