Search code examples
iphoneopengl-estouchframe-ratelag

Choppy touch response on lower FPS


I'm making an iPhone game which has a quite intense use of pixel shaders. Some effects make my fps rate sometimes drop down to ~22 FPS in the 3GS, but it is around ~27 most of the time. When the FPS rate is down there, the touch gesture response becomes extremely choppy. In other words, the gesture update time reaches nearly 5hz, which is much slower than the game itself.

Has anyone experienced similar problems? Is there any way around it?

Note1: I'm already using CADisplayLink

EDIT: I had a significant improvement by manually skipping even frames. I'm not sure if that is a good thing to do but the game remained quite playable and I'm sure it is using much less CPU now.


Solution

  • I have a similar situation in one of my applications, where I have very heavy shaders that can lead to slower rendering on older devices, but I still want to have the framerate be as fast as it can on more powerful hardware.

    What I do is use a single GCD serial queue for all OpenGL ES rendering-related actions, combined with a dispatch semaphore. I use CADisplayLink to fire at 60 FPS, then within the callback I dispatch a block for the actual rendering action. I use a dispatch semaphore so that if the CADisplayLink tries to add another block to the rendering queue while one is running, that new block is dropped and never added.

    I describe this approach in detail in this answer, and you can download the source code for my application which uses this here.

    The GCD queue lets you move this rendering to a background thread, which leaves your interface responsive, while scaling the FPS so that your rendering runs as fast as your hardware supports. This has particular advantages on the new dual core iOS devices, because I noticed significant rendering speed increases just by performing my OpenGL ES updates on this background queue.

    However, as I describe in that answer, you'll need to funnel all of your OpenGL ES updates through this queue to avoid the potential for more than one thread from simultaneously accessing an OpenGL ES context (which causes a crash).