iDevGames Forums
CVDisplayLink instead of NSTimer - Printable Version

+- iDevGames Forums (
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: CVDisplayLink instead of NSTimer (/thread-584.html)

CVDisplayLink instead of NSTimer - OptimisticMonkey - Nov 18, 2009 10:13 AM

I have started to implement cvDisplayLink to drive the render loop instead of nstimer, as detailed in this technical note

Is it better to do the actual rendering within the displaylink callback itself, or should I instead call setNeedsDisplay on the view and let the main thread do the rendering?

In order to render directly in the callback, I need to lock the opengl context, which I was hoping to avoid.

AnotherJake posted some great info here in another post:

Does anyone have any other feedback about using cvDisplayLink?

Is it possible to use cvDisplayLink for timing and still render on the main thread?

Thanks in advance for any feedback....

CVDisplayLink instead of NSTimer - OptimisticMonkey - Nov 18, 2009 10:49 AM

AnotherJake - I believe the infrequent
<Error>: kCGErrorIllegalArgument: CGSUnionRegionWithRect : Invalid region

errors were caused by trying to render from the non-main thread....maybe from within the setNeedsDisplay ?

Anyway, I eliminated them with the following approach which schedules the setNeedsDisplay to occur on the next main runloop pass:

-(void) queueRender
    [self setNeedsDisplay:YES];    

- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
    [self performSelectorOnMainThread:@selector(queueRender) withObject:nil waitUntilDone:NO ];
    return kCVReturnSuccess;

I am able to render using the main thread with no context locking and using cvDisplayLink for timing - let me know if anyone is interested and I will post more complete sample code....

CVDisplayLink instead of NSTimer - AnotherJake - Nov 18, 2009 11:55 AM

Interesting idea. I'll have to try that when I get a chance.

CVDisplayLink instead of NSTimer - SethWillits - Nov 18, 2009 12:30 PM

Well the problem with this is that you have no idea when the drawing will actually happen. CVDisplayLink is sending the callback, saying "ok application, you should render now", and then you're just saying "hey, main thread, render this when you get a chance." If the main thread is busy, you lose the timing accuracy of the display link which is the whole point of it being there. Frames could be drawn faster or slower than the refresh rate. You've essentially just gone back to an unsynchronized timer.

If the main thread is basically doing nothing, you may not notice much of anything at all though since it can possibly respond pretty quickly. But if it's ever doing anything, it's basically a roulette game. Sometimes it'll work fine, other times you might lose out.

CVDisplayLink instead of NSTimer - AnotherJake - Nov 18, 2009 01:31 PM

I just tried it and it appears to work so far. Definitely got rid of the errors.

Like I mentioned before though, it's not as smooth as rendering in the display link thread (for the reason FreakSoftware outlined) and does still drop a few frames. However, it does appear to offer somewhat better timing consistency than a 1kHz timer on the main thread. The dropped frames are still unfortunate though.

As far as being a technically solid way to go about using a display link, I don't know. It still seems rather awkward to me, but like I said before, hey if it works then why not? Personally I'm okay with the threading thing and don't want to give up the full timing advantage so I won't choose this route, but it's interesting that it seems to work and appears to offer a little better timing than a regular timer.

CVDisplayLink instead of NSTimer - AnotherJake - Nov 18, 2009 02:05 PM

BTW, I've still been using display link since that last thread, along with using state interpolation, and the results have been unbelievably smooth! I don't think it can be beat -- I don't think even direct video irq could produce better results. The "state interpolation" thing I'm talking about is essentially the same as what would be referred to in multiplayer networking as "client-side entity interpolation" in-between server snapshots. Instead of interpolating between server snapshots, I'm interpolating state between updates to match the exact time of rendering. I had done this previously, but only experimentally and didn't quite see the point of it since the NSTimer inaccuracies threw me off. Adding state interpolation on top of display link is absolutely amazing though. I used to use 110 Hz for update as a sort of compromise across different display refresh rates, but with state interpolation it totally doesn't matter at all. I can go as low as I can stand in terms of input lag (as low as 10 Hz might be playable sometimes), and as high as the sky, and the animation is always as smooth as glass. This has me wanting to take a stab at doing multiplayer networking now.

CVDisplayLink instead of NSTimer - SethWillits - Nov 18, 2009 02:49 PM

Sounds interesting.