[Solved] Extremely slow when using TextureAtlas, Why?

Anything libgdx related goes here!

[Solved] Extremely slow when using TextureAtlas, Why?

Postby gamefish » Sat Dec 18, 2010 4:34 am

Hey guys:
Thanks to the great libgdx, we can start our fancy small game development on android now.
But in day 1, I encountered a problem.
I used TextureAtlas to render a 800x480 background sprite and a car sprite.
Then I added some physics stuff into the scene.
When I run this test on my HTC G2(with a 2.2 rom), I get only 4-5 fps enabling eclipse debugger attach and 5-6 fps without eclipse debugger attach. I scratched my head through all night but can't figure out why it is so slow.
Here is my rendering code:
Code: Select all
GL10 gl = Gdx.graphics.getGL10();
   gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
   // ui
   spriteBatch.begin();
   bgSprite.draw(spriteBatch);
   hammer.draw(spriteBatch);
   font.draw(spriteBatch, "fps:" + Gdx.graphics.getFramesPerSecond(), 0, 20);
   spriteBatch.end();
   
   // render the world using the debug renderer
   orthoCamDebug.setMatrices();
   renderer.render(world);


Basically like the the TextureAtlasTest.java in libgdx test project.

This morning I wake up and come to an idea that why not try not to use TextureAtlas but simply using Texture.
Then I changed those 2 sprites to loaded from single texture file.
The result is I get 20-25 fps with debugger attached and 40 fps without debugger attached.

I'm a newbie and didn't check out the internal magic of libgdx.
Can someone tell me what did I missed here? ( I haven't try out SpriteCache yet)
More fancy android games at http://www.html5game.com
gamefish
 
Posts: 18
Joined: Sat Dec 18, 2010 4:20 am

Re: Extremely slow when using TextureAtlas, Why?

Postby NateS » Sat Dec 18, 2010 8:02 am

Go back to TextureAtlas, in Eclipse, Devices view, click your process, click the Start Method Profiling button. Wait a minute or so. Click it again. Where is the time being taken?

Always detach the debugger (unless you are debugging). I get ~10 fps with it attached and ~45 fps without it.

What resolution are the texture(s) being loaded into the TextureAtlas?
NateS
 
Posts: 1980
Joined: Fri Nov 12, 2010 11:08 am

Re: Extremely slow when using TextureAtlas, Why?

Postby gamefish » Sat Dec 18, 2010 12:02 pm

Hi Nates thanks for the reply.
I did some profiling using your method, here is the result image

Using atlas
Image

Using sprite created from single texture file
Image

Actually I didn't get any result from these data.
The only thing I noticed is the AndroidGraphics.onDrawFrame method (green No.1 line) only takes 49% in total when using atlas, comparing a 82% in total when using sprite from single texture.

Can this be a threading issue? I really don't know.

By the way in my atlas it's a 853x480 32 bit png, and the atlas img is 1024x1024 (generated by image-packer).

I also tried to draw only a small sprite using atlas, like a 100x100 car sprite, the performance is still significantly lower than using sprite from a single texture
More fancy android games at http://www.html5game.com
gamefish
 
Posts: 18
Joined: Sat Dec 18, 2010 4:20 am

Re: Extremely slow when using TextureAtlas, Why?

Postby mzechner » Sat Dec 18, 2010 3:09 pm

According to that output above the issue is not in SpriteBatch but in Tank.render(). What are you doing in there?
mzechner
Site Admin
 
Posts: 4879
Joined: Sat Jul 10, 2010 3:50 pm

Re: Extremely slow when using TextureAtlas, Why?

Postby gamefish » Sat Dec 18, 2010 3:51 pm

mzechner wrote:According to that output above the issue is not in SpriteBatch but in Tank.render(). What are you doing in there?

As you can see I posted all the code in render() in the topic post, nothing more
More fancy android games at http://www.html5game.com
gamefish
 
Posts: 18
Joined: Sat Dec 18, 2010 4:20 am

Re: Extremely slow when using TextureAtlas, Why?

Postby mzechner » Sat Dec 18, 2010 4:09 pm

From your snippet above:

Code: Select all
   // render the world using the debug renderer
   orthoCamDebug.setMatrices();
   renderer.render(world);


what does renderer.render(world) do?
mzechner
Site Admin
 
Posts: 4879
Joined: Sat Jul 10, 2010 3:50 pm

Re: Extremely slow when using TextureAtlas, Why?

Postby gamefish » Sat Dec 18, 2010 4:50 pm

mzechner wrote:From your snippet above:

Code: Select all
   // render the world using the debug renderer
   orthoCamDebug.setMatrices();
   renderer.render(world);


what does renderer.render(world) do?


This is box2d debug renderer, which renders box2d world for debugging.

The performance issue have nothing to do with these two lines, I've tested with or without these lines.
Here is the main methods in my code:
Code: Select all
public void create()
    {
   spriteBatch = new SpriteBatch();
   spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho(0, 800,
      0, 480, 0, 1));
   font = new BitmapFont(Gdx.files.getFileHandle("data/microsoft.fnt", FileType.Internal),
      Gdx.files.getFileHandle("data/microsoft.png", FileType.Internal), false);

   orthoCamDebug = new OrthographicCamera();
   orthoCamDebug.setViewport(WorldW, WorldH);
   orthoCamDebug.getPosition().set(WorldW / 2, WorldH / 2, 0);

   // create textures from atlas
   atlas = new TextureAtlas(Gdx.files.internal("data/tex"), false);
   bgSprite = atlas.getSprite("map");
        // create test sprite from single texture file
   testSprite = new Sprite(Gdx.graphics.newTexture(Gdx.files.getFileHandle("data/map.png", FileType.Internal),
      TextureFilter.Linear, TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge));
   // create the debug renderer
   renderer = new Box2DDebugRenderer();
   // next we create out physics world.
   createPhysicsWorld();

   // register ourselfs as an InputProcessor
   Gdx.input.setInputProcessor(this);
    }

public void render()
    {
   update();
   draw();
    }

    public void update()
    {
   long start = System.nanoTime();
   world.step(Gdx.graphics.getDeltaTime(), 3, 3);
   float updateTime = (System.nanoTime() - start) / 1000000000.0f;
    }

    public void draw()
    {
   GL10 gl = Gdx.graphics.getGL10();
   gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

   spriteBatch.begin();
//// here goes the magic  ////////////////////////////////////
        // if I use this line, 40-50 fps can be achieved
 //       testSprite.draw(spriteBatch);
        // if I use this line, I can't get more than 10 fps
   bgSprite.draw(spriteBatch);
//////////////////////////////////////////////////////////
   font.draw(spriteBatch, "fps:" + Gdx.graphics.getFramesPerSecond(), 0, 20);
   spriteBatch.end();
   
   // render the world using the debug renderer
   orthoCamDebug.setMatrices();
   renderer.render(world);
    }
More fancy android games at http://www.html5game.com
gamefish
 
Posts: 18
Joined: Sat Dec 18, 2010 4:20 am

Re: Extremely slow when using TextureAtlas, Why?

Postby mzechner » Sat Dec 18, 2010 5:04 pm

Ok, my first guess is that you are heavily fillrate limited. Drawing a sprite that fills the entire screen is something no current phone likes. It gets worse when you use blending. So try this before rendering your background:

Code: Select all
spriteBatch.disableBlendind();
... render your background sprite
spriteBatch.enableBlending();
.. rest of your SpriteBatch rendering code


Why it would work faster with Texture instead of TextureAtlas is a little beyond me. I'll throw together some tests asap and see what's wrong there. Nate, any ideas?
mzechner
Site Admin
 
Posts: 4879
Joined: Sat Jul 10, 2010 3:50 pm

Re: Extremely slow when using TextureAtlas, Why?

Postby gamefish » Sun Dec 19, 2010 4:29 am

mzechner wrote:Ok, my first guess is that you are heavily fillrate limited. Drawing a sprite that fills the entire screen is something no current phone likes. It gets worse when you use blending. So try this before rendering your background:

Code: Select all
spriteBatch.disableBlendind();
... render your background sprite
spriteBatch.enableBlending();
.. rest of your SpriteBatch rendering code


Why it would work faster with Texture instead of TextureAtlas is a little beyond me. I'll throw together some tests asap and see what's wrong there. Nate, any ideas?


I've tried the disableBlending(), but it is still slow.
Actually I think this is not about fillrate limit, because even if I draw a very small sprite, like 100x100, it is still significant slower than using sprite from single file.
In the traceview when using atlas the onDrawFrame method only occupied 49% of CPU time, that's strange. It seems the video memory is somehow not big enough so the texture atlas needs to keep moving in and out, just guess.

I've also tried the scene2d package, the Stage and Image class. The result is the same as using atlas. So what's the additional work in these two systems, atlas and scene2d.

By the way maybe you should try using 32bit png texture in some tests.
More fancy android games at http://www.html5game.com
gamefish
 
Posts: 18
Joined: Sat Dec 18, 2010 4:20 am

Re: Extremely slow when using TextureAtlas, Why?

Postby gamefish » Sun Dec 19, 2010 5:28 am

Hey guys, big progress here.
First of all, it is my mistake.
When I use single file texture, I used a 1024x1024 texture that don't have alpha channel, that's why it is still slow even if spriteBatch.disableAlphBlending() :cry: I'm sorry for this, last time I deal with OpenGL things is 2 years ago, seems I forgot many things.

As mzechner said, it is the fillrate problem with blending.

BUT, there is another problem.
This time I draw a non-blending background using single texture file, and a 140x100 car using texture atlas, I get only 6-7 fps, if I remove the car, I get 40 fps. So the problem is why would such a small blending sprite affects so much? (ps: I enabled box2d debug renderer in both circumstances)
It's like the whole 1024x1024 atlas with blending is rendering, not just the 140x100 region(the car).

Am I missed something again?
More fancy android games at http://www.html5game.com
gamefish
 
Posts: 18
Joined: Sat Dec 18, 2010 4:20 am

Next

Return to Libgdx

Who is online

Users browsing this forum: Google [Bot], MSN [Bot] and 1 guest