CVDisplayLink instead of NSTimer

Member
Posts: 86
Joined: 2008.04
Post: #1
I have started to implement cvDisplayLink to drive the render loop instead of nstimer, as detailed in this technical note http://developer.apple.com/mac/library/q...a1385.html

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: http://www.idevgames.com/forum/showthrea...291&page=3

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....
Quote this message in a reply
Member
Posts: 86
Joined: 2008.04
Post: #2
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:

Code:
-(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....
Quote this message in a reply
Moderator
Posts: 3,577
Joined: 2003.06
Post: #3
Interesting idea. I'll have to try that when I get a chance.
Quote this message in a reply
⌘-R in Chief
Posts: 1,260
Joined: 2002.05
Post: #4
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.
Quote this message in a reply
Moderator
Posts: 3,577
Joined: 2003.06
Post: #5
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.
Quote this message in a reply
Moderator
Posts: 3,577
Joined: 2003.06
Post: #6
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.
Quote this message in a reply
⌘-R in Chief
Posts: 1,260
Joined: 2002.05
Post: #7
Sounds interesting.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  CVDisplayLink - ObjectiveC & C++ JordanReed 19 18,164 Oct 4, 2012 01:35 PM
Last Post: OneSadCookie
  Interesting Articel on CVDisplayLink OptimisticMonkey 1 4,097 Dec 28, 2008 11:15 PM
Last Post: AnotherJake
  NSTimer and recursive drawing jamil5454 3 3,178 Dec 5, 2005 10:21 AM
Last Post: TomorrowPlusX