iPad (1st generation) performance issue on large textures

Topics: iOS, Performance
Dec 15, 2013 at 6:56 AM
I'm developing a strategy game with Cocos2d-XNA and I am really satisfied with the library! I have only a problem with a large background image that I put as background: on Android performances are absolutely fine (60fps on different devices), whereas on first generation iPad I can not get more than 40fps (if I remove the background I've got 60fps). I have reproduced the problem using the base Cocos2d-XNA template and adding only a 1024x1024 sprite to the base layer, and I get exactly the same results (I've got 33fps if I cover the entire viewable area of the screen, more fps if the covered area is less). I suspect that the problem is caused by the shaders used in MonoGame (somehow are not optimized for older generations of iOS devices?). Does anyone know a way to solve the problem? Thanks (and sorry for my english!)
Dec 16, 2013 at 4:44 AM
There are many issues with the iPad G1 that I have found. Most notably is the poor performing GPU on those devices.

iPad G1 is 1024 x 768. Your 1024 x 1024 sprite would then be doing some scaling of the texture to make it fit in 1024 x 768. Try using a 1024 x 768 texture and see if that makes it go 60 fps. I bet your are correct that the older scaling operations on the GPU are making it slow.
Dec 16, 2013 at 12:09 PM
I've tryied just now with the modified base template (only one sprite on screen):
  • 1024x768 texture, not scaled (the full screen is filled) : 33fps
  • 2048x1536 texture, not scaled (only the lower-left quarter of the texture is visible with anchorpoint = zero, the full screen is filled) : 33fps
  • 512x384 texture, not scaled (only a quarter of the screen is filled) : 60fps
  • 1024x768 texture, scaled 0.5 (only a quarter of the screen is filled) : 60fps
  • 2048x1536 texture, scaled 0.5 (the full screen is filled) : 31fps
  • 512x384 texture, scaled 2.0 (the full screen is filled) : 33fps
The measurements seem to be consistent: the fps depend on the portion of the screen that is filled and not on the texture size... do you think that I can get more fps doing some tweaking?

Thank you very much!
Dec 17, 2013 at 3:01 AM
This seems to be a full screen anti-aliasing performance problem on older GPUs. I bet if you disable the multisampling the FPS will improve.
Dec 17, 2013 at 3:39 AM
Gena proposes that Cocos2d-XNA's constant use of RenderTarget.PreseveContents may be the cause of this performance. That is controlled by the CCDrawManager. You can hack at the draw manager and see if changing the RT usage to DiscardContents helps with performance.

Note that if you start to discard your RT rendering then you will need to make sure you do good house keeping on when to keep and when to discard your RT contents.
Dec 17, 2013 at 4:58 AM
also, if you are not using a mask then you can disable the depth buffer and stencil. For instance, if you are not going to use the clipping node, then you can disable the depth buffer and stencil options on the render targets.

Furthermore, if you change from using SurfaceFormat.Color to SurfaceFormat.Bgr565 you might see another boost in performance.
Dec 17, 2013 at 7:44 AM
I'll try them all and let you know the results as soon as possible. Thank you again!
Dec 17, 2013 at 3:07 PM
Hi, I've done all the hacks that you suggested (I hope correctly, I haven't a deep knowledge of opengl and xna), but the only thing that has affected the performance (+2 fps) was to use the SurfaceFormat.Bgr565. No changes disabling multisampling, using DiscardContents instead of PreserveContents in CCDrawManager, disabling depth buffer and stencil. For now I continue to investigate and let you know if I find something, but if you have any other suggestions they are always welcome!