CADisplayLink behaves similar to NSTimer, framerate bug - iphone

I have implemented CADisplayLink, but yet it behaves similar to NSTimer in that when there are a lot of draws it locks the fps to 40 and never gets out of there, even if there are a lot fewer draws afterward. This happens on the itouch 3 and itouch 4. I'm using openGL to render, and openAL for sounds. What's going on. Help Please!!!

I would start by profiling the app. I wouldn't suspect CADisplayLink weirdness till it's demonstrated that the app should in fact be running faster than it is.

Related

iOS frame-by-frame animation with Quartz

I'm working on an iPhone game that involves only two dimensional, translation-based animation of just one object. This object is subclassed from UIView and drawn with Quartz-2D. The translation is currently put into effect by an NSTimer that ticks each frame and tells the UIView to change its location.
However, there is some fairly complex math that goes behind determining where the UIView should move during the next frame. Testing the game on the iOS simulator works fine, but when testing on an iPhone it definitely seems to be skipping frames.
My question is this: is my method of translating the view frame by frame simply a bad method? I know OpenGL is more typically used for games, but it seems a shame to set up OpenGL for such a simple animation. Nonetheless, is it worth the hassle?
It's hard to say without knowing what kind of complex math is going on to calculate the translations. Using OpenGL for this only makes sense if the GPU is really the bottleneck. I would suspect that this is not the case, but you have to test which parts are causing the skipped frames.
Generally, UIView and CALayer are implemented on top of OpenGL, so animating the translation of a UIView already makes use of the GPU.
As an aside, using CADisplayLink instead of NSTimer would probably be better for a game loop.
The problem with the iPhone simulator is it has access to the same resources as your mac. Your macs ram, video card etc. What I would suggest doing is opening instruments.app that comes with the iPhone SDK, and using the CoreAnimation template to have a look at how your resources are being managed. You could also look at allocations to see if its something hogging ram. CPU could also help.
tl;dr iPhone sim uses your macs ram and GFX card. Try looking at the sequence in Instruments to see if theres some lag.

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.

iPhone/iPad, OpenGL ES, CADisplayLink

I've just started playing with OpenGL ES, mostly on iPad and have noticed some problems I cannot find the answer to. First I've tried using two EAGLViews using separate renderers in the same window. Basically think the OpenGL ES example project in XCode but with two EAGLViews and two renderers etc. Now this does not seem to work in the simulator, it only shows one of the views (it seems to run the rendering code, but only one view is displayed with openGL) but when run on the device (an iPad using iOS 4.2) it does work, at least kind of which leads to the next question.
The updates to the rendering is triggered using CADisplayLink on both these views. This does however cause some problems. Most of the time, after just a short while, the updates on one of the views stops, its CADisplayLink stops triggering. This only happens on the device and not in simulator. It can be "fixed" by using timers instead of CADisplayLink, or timer on one view and DisplayLink on the other, I would like to know what is causing this though. I'm creating the display link like this (in both views):
self.displayLink = [NSClassFromString(#"CADisplayLink") displayLinkWithTarget:self selector:#selector(drawView:)];
[displayLink setFrameInterval:animationFrameInterval];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
Now the last question is about an odd thing I have noticed. When running the OpenGL ES example project provided in Xcode in the iPad simulator with the view resized below 760 in width, it does not render anything to screen, It only concerns the width though, the height can be resized in any way. It only happens in the simulator, not on the device.
So the questions are basically if the things mentioned above are bugs, features or if I'm just doing it wrong?
Thanks
/j0h
I found a similar problem running two OpenGL views at once, each running on a separate CADisplayLink, both running forMode: NSDefaultRunLoopMode. When testing on an iPhone 4S running iOS 5.1, there were no issues except for when exiting the MPMediaPickerController, one of the views would stop rendering. However, on the iPod Touch 3rd gen running iOS 5.0.1, I did notice the issue where one or the other view would stop rendering randomly (due to CADisplayLink not firing). I was able to fix it by switching to NSTimer for both views (just doing it for one or the other wouldn't work). Sizing to multiples of 32 did not make any difference for me.

Why is my touch event frequency slower on iOS 4.0?

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.

iPhone + OpenGL + Touches: FPS drop

Recently I ran into a very strange issue: touching the screen of the iPhone and moving a finger around can eat up to 50% of my FPS. Yeah, I checked my code for possible bottlenecks – not the issue. The last resort I tried before writing this post – commenting out all the touch processing code and looking at FPS then. Results are: no touches – 58-60. Touching and moving the finger – 35-40 FPS instantly.
The rendering is done in a separate thread, so that no main runloop events shall collide with it. However, it's very crushial for me (and the game I develop) to resolve this issue, because such FPS drop is really noticeable.
Thank you for your help in advance.
UPDATE: seems that setting rendering thread's priority to higher value helps a bit...
The iPhone, iPod Touch, and iPad are all single-processor, single-core devices. Simply putting your rendering code on a separate thread from touch event handling—though a good idea—won't prevent the touch processing from eating up CPU cycles. The only way to make your framerates go up will be to either make the touch handling code faster or make the rendering faster. Which you pursue depends on the specifics of your application.