From d67e8667886329ad4717178e8e09ceef1a42af34 Mon Sep 17 00:00:00 2001 From: Rhody Lugo Date: Tue, 10 Feb 2015 15:24:22 -0430 Subject: [PATCH] add support for CADisplayLink --- platform/iphone/gl_view.h | 8 ++++++++ platform/iphone/gl_view.mm | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index 8ae7c2f87db..a5b1b8731f1 100755 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -34,6 +34,8 @@ #import #import +#define USE_CADISPLAYLINK 1 //iOS version 3.1+ is required + @protocol GLViewDelegate; @interface GLView : UIView @@ -51,8 +53,14 @@ // OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) GLuint depthRenderbuffer; +#if USE_CADISPLAYLINK + // CADisplayLink available on 3.1+ synchronizes the animation timer & drawing with the refresh rate of the display, only supports animation intervals of 1/60 1/30 & 1/15 + CADisplayLink *displayLink; +#else // An animation timer that, when animation is started, will periodically call -drawView at the given rate. NSTimer *animationTimer; +#endif + NSTimeInterval animationInterval; // Delegate to do our drawing, called by -drawView, which can be called manually or via the animation timer. diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index bee01d3c723..0625361b968 100755 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -413,7 +413,19 @@ static void clear_touches() { return; active = TRUE; printf("start animation!\n"); +#if USE_CADISPLAYLINK + // Approximate frame rate + // assumes device refreshes at 60 fps + int frameInterval = (int) floor(animationInterval * 60.0f); + + displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)]; + [displayLink setFrameInterval:frameInterval]; + + // Setup DisplayLink in main thread + [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; +#else animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES]; +#endif if (video_playing) { @@ -427,8 +439,13 @@ static void clear_touches() { return; active = FALSE; printf("******** stop animation!\n"); +#if USE_CADISPLAYLINK + [displayLink invalidate]; + displayLink = nil; +#else [animationTimer invalidate]; animationTimer = nil; +#endif clear_touches(); if (video_playing) @@ -441,7 +458,11 @@ static void clear_touches() { { animationInterval = interval; +#if USE_CADISPLAYLINK + if(displayLink) +#else if(animationTimer) +#endif { [self stopAnimation]; [self startAnimation]; @@ -451,6 +472,17 @@ static void clear_touches() { // Updates the OpenGL view when the timer fires - (void)drawView { +#if USE_CADISPLAYLINK + // Pause the CADisplayLink to avoid recursion + [displayLink setPaused: YES]; + + // Process all input events + while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource); + + // We are good to go, resume the CADisplayLink + [displayLink setPaused: NO]; +#endif + if (!active) { printf("draw view not active!\n"); return;