Why is my touch event frequency slower on iOS 4.0? - iphone

I'm writing a finger sketch type app and had the app working great on iOS 3.0. However, running the app under iOS 4.0 or greater is causing problems. Specifically, I am receiving touch events to my app approximately 5x slower on the new OS than on the old. This obviously causes my app to draw poorly because I'm capturing 5x less data points to draw between.
Any ideas on how to speed up touch event frequency on iOS4?

Certain graphics operations take a lot longer in iOS4.x than in 3.x (somewhere between 2X to 10X slower). The longer graphics execution times could be blocking the main UI thread, and not leaving enough time for the main thread run loop to handle user (touch) events.
Profile your drawRect code and see if it's now taking longer that one refresh rate tick time. If so, try speeding up or breaking up your graphics renders, or try a lower frame rate, and see if any of that helps.

You should profile your code with Shark to see where the bottleneck is. What is probably happening is some of your code that executes on the main thread (most likely something that runs in response to a touch) is taking longer than expected which is preventing your app from receiving touch events

Block the main thread less.

Related

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.
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).
If your app's game loop run at 22 fps, but is requesting 30 fps, that means that the app is oversubscribing the total number of CPU cycles available per second in the UI run loop. Either try putting more stuff in background threads, or turn your requested frame rate down to below what you can actually get (e.g. set it to 20 fps), so that there is more time left for UI stuff, such as touch event delivery.

Weird CPU usage problem when app is backgrounded

I'm experiencing a very weird CPU usage bug with my audio streaming app.
When the app is in the foreground and playing music, the total device CPU usage is only about 15%. However, as soon as the app is put in the background, the CPU usage spikes to 100% and stays there.
About 40% of this is coming from the app process itself, and roughly the other 60% is coming from the SpringBoard process, which apparently handles all Core Animation calls (though I'm not explicitly using Core Animation, I assume that it also handles other UI related activity). Also, according to the "CPU Activity" instrument, most of the additional CPU usage from the app process itself falls into the "graphics" category, though I do see an increase in both the "audio processing" and (strangely) the "foreground app activity" category.
How can I figure out what is causing this problem? Instruments is telling me at high level what is happening, but not why it's happening.
That's extremely odd. However, without any code, it makes it really hard to say anything about anything. Purely based on speculation, I'd say you're updating the UI without knowing it in the background. Perhaps an animation call on -(void)applicationDidEnterBackground? Give us some more to work with! I'm really curious about this now :)
Mystery solved!
Of course I missed the obvious, thank you to Dylan G for pointing me in the right direction. I was running a loop to check the remaining background time. I wasn't sleeping the loop thread at all so it was apparently just running full speed sucking up all CPU power.
I'm not sure why it was looking like it was graphics related and involving the SpringBoard process, but as soon as I added a sleep(1) at the end of the loop, the CPU usage no longer rose when the app was placed in the background. The strange thing is that I'm not calling any UI or graphic related methods in that loop, just calls to [[UIApplication sharedApplication] backgroundTimeRemaining] and accessing some integer and bool properties.
There is still a quick spike of CPU for the second or so after it's placed in the background, and SpringBoard spikes as well, but just for a second, then CPU usage drops back to the same as when the app is running.

Strange delay for touch events in UIView

I am working on an OpenGL application for the iPhone...
My app has only 2 views:
An OpenGL view and, as a subview for the OpenGL view, a view with the sole purpose of catching touch events...
The problem is that after about 10-15 minutes of keeping the app running on the device, I get a big (0.5s-1s) delay between every touchesMoved:withEvent: call
The animation runs smooth, and CPU usage is also not the problem (10% at most)
I have no idea what might be causing this
That is weird, eh.
This happens ON THE DEVICE right? When you are not running tethered from XCode?
I would guess you are using up a lot of memory, either a leak or just in some way using up more and more memory as time goes on.
Are you familiar with the various memory tools to watch what is going on?
Also, what about this: launch a few other large apps that remain in the background. Run your app until the problem exhibits. Then, kill the other apps. Does the problem suddenly go away? If so that would suggest you're low on memory.
Would be interested to hear.

Getting Framerate Performance on iPhone

I've just come off the PSP where performance testing was easy. You just turned off 'vsync' and printed out the frameratem, then change something and see whether the frame rate goes up or down...
Is there any way to do the same thing on the iPhone? How do you turn vsync off? The Instruments tool is next to useless. Its chief problem being that it running it adversely affects the performance of the app! Also, the frame rate it reports is extremely sporadic.
I don't want any fancy tool that reports call trees and time spent in each function. I just want an unrestricted frame rate and some way to see what it is. Is there a high precision counter that you can use on the iPhone? Something like QueryPerformanceCounter in windows?
Also, is there anyway for you to somehow KILL backround processes so you know they can't effect the performance, perhaps solving the sporatic frame rate problem?
Profile your app with Instruments and use the Core Animation instrument. It gives a frame rate.
You're taking the try-something-and-measure approach. Very indirect. It's easy to tell exactly what is taking the time; it doesn't depend on what else is going on and doesn't require learning a new tool. All you need is a debugger that you can interrupt.
You can't kill background processes on the iPhone. That would make it possible for a buggy or malicious app to interfere with the phone function and the needs of all other functions on the iPhone are subordinated to the phone.
Try QuartzDebug or OpenGL Profiler.
Use instruments to get the frame rate.
To do this, run profile on your app (click and hold on the run button in xcode and choose profile). Make sure you are running your app on device. Choose openGL ES analysis. Look at the data display under core animation frames per second.
You want to aim for 60fps.

OpenGL ES on iPhone: timer-based painting problems, jitteryness

I have an OpenGL ES 1.1 project on iPhone, based heavily on the empty OpenGL ES application given here:
http://iphonedevelopment.blogspot.com/2009/06/empty-opengl-es-application-project.html
I'm testing on a 3G (not 3GS) device, 8GB.
The paint loop in my app which does openGL operations is doing quite a lot each time it renders the screen. However, in situations with it doing the same thing each paint cycle, I'm seeing variable frame rates. I have set the NSTimer which fires the paint code to fire 30 times a second -- i.e. every 0.0333 of a second. The main problem is that whereas my actual paint code often takes approximately that amount of time to execute one paint (in terms of wall time), it varies, and sometimes it takes far longer, for no apparent reason. Using careful logging to report maximum time intervals when they occur, I can see that sometimes my paint has taken as long as 0.23 sec to complete - that's like 4FPS, which compared to 30FPS is like skipping 5 frames of animation/ user interaction, which isn't very acceptable.
At first I suspected my paint loop was snagging on some lock (there aren't many in there, because the GL render stuff in on the main thread (which is necessary AFAIK), as is incoming event handling) but some logging with finer granularity revealed that, in one paint code execution cycle, a large time elapsing over a bit of code that was doing basically hardly anything, and certainly not a GL operation.
So it seems a bit like my GL drawing thread (i.e. the main thread) just takes longer sometimes for no good reason. I have comms in my application and I disabled comms to see if that was the problem -- but I still see some "spikes" in execution time of my painting, when it's doing the same painting each time.
It's seems like another thread is just being switched to, mid-paint code, for ages, before returning to my paint code, on occaison.
Any ideas with how to analyse further what is going on? I know NSTimers aren't perfect and aren't at a guaranteed frequency, but the main issue here is that my actual paint cycle sometimes just takes forever, presumably because some other thread gets switched to....
Keep in mind that your application can seem to "hang" for no reason that has nothing to do with your "main loop". That's because you are multitasking... and in paticular, something as simple as your phone checking email can cause this sort of problem. One big cause, on the iPhone anyway, is when you move through different cell sites (like if you are on a subway or in a car) you can sometimes get spikes as it does... whatever it does.
If you are on an iPhone, try airplane mode and see if the problems go away.
-- David