Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
400 sprites - FPS is too slow — Gideros Forum

400 sprites - FPS is too slow

zhiletkazhiletka Member
edited September 2012 in General questions
Hi guys,

In my project I need to draw about 400 tiles of the game map, each tile is 16x16 pixels. I wrote a simple code to test Gideros perfomance:
local texture = Texture.new("01.png")
for i=1,400 do
	local a = Bitmap.new(texture)
	a:setPosition(math.random(50,250),math.random(100,300))
	stage:addChild(a)
end
As you can see there's no texture switches and fillrate is 102400 pixels, but on my HTC Legend it runs at 13 FPS :(

I tried to figure out the reasons of this and got stucked.
For example, when I changed the texture to 300x400 and reduced the number of spites to 10 - I got 12 times greater fillrate, but FPS was 60!
local texture = Texture.new("02.png")
for i=1,10 do
	local a = Bitmap.new(texture)
	a:setPosition(0,0)
	stage:addChild(a)
end
Another experiment with font rendering runs at 30 FPS.
local font = Font.new("arial.txt", "arial.png")
for i=1,100 do
	local a = TextField.new(font, "Test string")
	a:setPosition(0, 0)
	a:setTextColor(0x306090)
	stage:addChild(a)
end
The only reason that comes to mind is that the low-level stage rendering code is not optimized.

Can anyone tell whats wrong and give the solution for my case?

Thanks!

Likes: theone10

+1 -1 (+1 / -0 )Share on Facebook

Comments

  • Use tiled map support!
  • i dont think texture switch or not will change fps. After adding 1500 sprite, i got fps 1 :D
  • MellsMells Guru
    edited September 2012
    @zhiletka
    I don't know what it's worth, but you should see a difference if you try the following :
    local texture = Texture.new("01.png")
    local a
    for i=1,400 do
    	a = Bitmap.new(texture)
    	a:setPosition(math.random(50,250),math.random(100,300))
    	stage:addChild(a)
    end
    It's advised to declare a local outside of a for loop because (I don't know the vocabulary, somebody will use the right words :) it has something to do with memory allocation (once versus 400 times).

    Is the change noticeable?
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • Hi,
    Again if you are using square tiles for a map. Use tiled map functions, as is it only draws what is on the screen. PLease explain in more detail what you are trying to achieve, not just randomly push sprites on screen. It will be easier to help Cheers z

    Likes: zhiletka

    +1 -1 (+1 / -0 )Share on Facebook
  • ScouserScouser Guru
    edited September 2012
    @zhiletka: you could also try
    local texture = Texture.new("01.png")
    local a
    local rnd = math.random
    for i=1,400 do
    	a = Bitmap.new(texture)
    	a:setPosition(rnd(50,250),rnd(100,300))
    	stage:addChild(a)
    end
    which adds a little speed boost due to the localising of the math.random function.
  • doesn't it is a normal with 400 sprites on the screen?
  • ScouserScouser Guru
    edited September 2012
    Doh. Ignore the last comment. I haven't had enough coffee yet this morning. That comment was just a follow on from @Mells, but @hgvyas123 quite right. :-/
  • Hi,

    Thanks for the answers.

    @Mells
    There's no difference in FPS, if declare local variable A outside the cycle. The code executes only once at application startup, not in frame update.

    @hnim
    @zakkwylde
    Texture switching is very slow operation on PC videocards. I suppose - mobile video chips have the same working principles. As you can see there's no need to change texture 400 times in my case, because all sprites are displayed sequentially.

    Using the tiled map helped me, the fps was increased to 60. I had a lot of things to rewrite, because each "tile" in my game will be animated, and tiled map can draw only static.

    I think that developers should look for some bug in stage rendering code. Because there's no difference between drawing 400 small pieces of tiled map from one texture and drawing 400 small sprites using the same texture. Am I right?
  • I wouldn't say it's a bug but... I don't think the current high level rendering engine uses any form of sprite batching so you might get context switching going on anyway.

    The low level tile renderer is batched and is therefore more efficient.

    I believe that this is on the TODO list for the developers.

    How many of your 400 objects are actually on screen at the same time ? - that seems a lot for a mobile game. If you know which of your objects are offscreen then you can call Sprite:setVisible(false) which might make processing them more efficient.

    Likes: zhiletka

    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 )Share on Facebook
  • @techdojo
    All 400 objects (after rewriting the code - tiles of the tiled map) are visible. I don't think that this is a lot for mobile game, take a look at different "Match 3" games for example.

    I hope, developers will look this discussion and confirm that batching for stage rendering will be added in future :)
  • I also notice slowdown but i need to render many mostly transparent sprites, yet they are usually more-or-less screen-sized. as i need to draw on them on the fly, they are shapes, thus the workaround with tiled maps is not an option for me.
    is there a chance that there can be a speed increase in a later version of gideros?
  • atilimatilim Maintainer
    edited September 2012
    @zhiletka Currently batching is not implemented yet. 400 independent sprites means traversing 400 sprites, 400 matrix multiplications, 400 transforms and 400 independent drawing calls (but one texture bind). Although fill rate is the major factor, when the number of sprites increases, traversal/matrix multiplication/drawing call, etc starts to dominate.

    @keszegh About fill rate, if you draw _only_ 4 full size rectangles on iPad 1, framerate starts to drop from 60. Therefore you should be careful about not to draw big sprites with mostly transparent areas. If you can, remove the transparent areas or divide your big rectangle into smaller ones.
  • atilimatilim Maintainer
    edited September 2012
    Also, I know it's not fair to compare HTC Legend with Samsung S2 but here is a speed comparison:
    http://www.glbenchmark.com/phonedetails.jsp?benchmark=glpro21&D=HTC+Legend&testgroup=overall
    http://www.glbenchmark.com/phonedetails.jsp?benchmark=glpro21&D=Samsung+GT-i9100+Galaxy+S2&testgroup=overall

    If you want to develop a game with many sprites displayed, one option is opting-out the old/slow devices by:
    1. Remove armv6 support by deleting libs/armeabi folder and keep only libs/armeabi-v7a.
    2. Change this line in AndroidManifest.xml
    <uses-feature android:glEsVersion="0x00020000" />
    to run on devices with OpenGL ES 2.0 support.

    For example, although HTC Legend supports OpenGL ES 2.0, it has an armv6 CPU (which explains why 400 sprites run at 13 fps).

    Likes: fxone

    +1 -1 (+1 / -0 )Share on Facebook
  • @zhiletka Currently batching is not implemented yet. 400 independent sprites means traversing 400 sprites, 400 matrix multiplications, 400 transforms and 400 independent drawing calls (but one texture bind). Although fill rate is the major factor, when the number of sprites increases, traversal/matrix multiplication/drawing call, etc starts to dominate.

    @keszegh About fill rate, if you draw _only_ 4 full size rectangles on iPad 1, framerate starts to drop from 60. Therefore you should be careful about not to draw big sprites with mostly transparent areas. If you can, remove the transparent areas or divide your big rectangle into smaller ones.
    Interesting info thanks, so potentially there could be room for some significant increases in rendering speed - this is GOOD news :)
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • @atilim
    Thanks for the explanations. Anyway I solved the problem with tiled map. Looking forward to the next Gideros versions :)
Sign In or Register to comment.