Kaynağa Gözat

cocoa: Backed out CVDisplayLink code for macOS vsync.

This was to deal with broken vsync support in macOS 10.14, which we assumed
would remain broken indefinitely, but a later 10.14 released fixed it.

This is a loss of late-swap support, but there are several subtle problems
in our CVDiplayLink code that are also evaporating, to be fair.

Fixes Bugzilla #4575.

(Backed out changeset 8760fed23001)
Ryan C. Gordon 5 yıl önce
ebeveyn
işleme
04b50f6c6b

+ 1 - 6
src/video/cocoa/SDL_cocoaopengl.h

@@ -36,11 +36,6 @@ struct SDL_GLDriverData
 @interface SDLOpenGLContext : NSOpenGLContext {
     SDL_atomic_t dirty;
     SDL_Window *window;
-    CVDisplayLinkRef displayLink;
-    @public SDL_mutex *swapIntervalMutex;
-    @public SDL_cond *swapIntervalCond;
-    @public SDL_atomic_t swapIntervalSetting;
-    @public SDL_atomic_t swapIntervalsPassed;
 }
 
 - (id)initWithFormat:(NSOpenGLPixelFormat *)format
@@ -48,7 +43,7 @@ struct SDL_GLDriverData
 - (void)scheduleUpdate;
 - (void)updateIfNeeded;
 - (void)setWindow:(SDL_Window *)window;
-- (void)dealloc;
+
 @end
 
 

+ 23 - 78
src/video/cocoa/SDL_cocoaopengl.m

@@ -36,23 +36,6 @@
 
 #define DEFAULT_OPENGL  "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
 
-static CVReturn
-DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
-{
-    SDLOpenGLContext *nscontext = (SDLOpenGLContext *) displayLinkContext;
-
-    /*printf("DISPLAY LINK! %u\n", (unsigned int) SDL_GetTicks()); */
-    const int setting = SDL_AtomicGet(&nscontext->swapIntervalSetting);
-    if (setting != 0) { /* nothing to do if vsync is disabled, don't even lock */
-        SDL_LockMutex(nscontext->swapIntervalMutex);
-        SDL_AtomicAdd(&nscontext->swapIntervalsPassed, 1);
-        SDL_CondSignal(nscontext->swapIntervalCond);
-        SDL_UnlockMutex(nscontext->swapIntervalMutex);
-    }
-
-    return kCVReturnSuccess;
-}
-
 @implementation SDLOpenGLContext : NSOpenGLContext
 
 - (id)initWithFormat:(NSOpenGLPixelFormat *)format
@@ -62,20 +45,6 @@ DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const
     if (self) {
         SDL_AtomicSet(&self->dirty, 0);
         self->window = NULL;
-        SDL_AtomicSet(&self->swapIntervalSetting, 0);
-        SDL_AtomicSet(&self->swapIntervalsPassed, 0);
-        self->swapIntervalCond = SDL_CreateCond();
-        self->swapIntervalMutex = SDL_CreateMutex();
-        if (!self->swapIntervalCond || !self->swapIntervalMutex) {
-            [self release];
-            return nil;
-        }
-
-        /* !!! FIXME: check return values. */
-        CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink);
-        CVDisplayLinkSetOutputCallback(self->displayLink, &DisplayLinkCallback, self);
-        CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink, [self CGLContextObj], [format CGLPixelFormatObj]);
-        CVDisplayLinkStart(displayLink);
     }
     return self;
 }
@@ -145,19 +114,6 @@ DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const
     }
 }
 
-- (void)dealloc
-{
-    if (self->displayLink) {
-        CVDisplayLinkRelease(self->displayLink);
-    }
-    if (self->swapIntervalCond) {
-        SDL_DestroyCond(self->swapIntervalCond);
-    }
-    if (self->swapIntervalMutex) {
-        SDL_DestroyMutex(self->swapIntervalMutex);
-    }
-    [super dealloc];
-}
 @end
 
 
@@ -208,7 +164,6 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
     const char *glversion;
     int glversion_major;
     int glversion_minor;
-    int interval;
 
     if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
 #if SDL_VIDEO_OPENGL_EGL
@@ -320,10 +275,6 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
         return NULL;
     }
 
-    /* vsync is handled separately by synchronizing with a display link. */
-    interval = 0;
-    [context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
-
     if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
         Cocoa_GL_DeleteContext(_this, context);
         SDL_SetError("Failed making OpenGL context current");
@@ -417,17 +368,21 @@ int
 Cocoa_GL_SetSwapInterval(_THIS, int interval)
 { @autoreleasepool
 {
-    SDLOpenGLContext *nscontext = (SDLOpenGLContext *) SDL_GL_GetCurrentContext();
+    NSOpenGLContext *nscontext;
+    GLint value;
     int status;
 
-    if (nscontext == nil) {
-        status = SDL_SetError("No current OpenGL context");
-    } else {
-        SDL_LockMutex(nscontext->swapIntervalMutex);
-        SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0);
-        SDL_AtomicSet(&nscontext->swapIntervalSetting, interval);
-        SDL_UnlockMutex(nscontext->swapIntervalMutex);
+    if (interval < 0) {  /* no extension for this on Mac OS X at the moment. */
+        return SDL_SetError("Late swap tearing currently unsupported");
+    }
+
+    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+    if (nscontext != nil) {
+        value = interval;
+        [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
         status = 0;
+    } else {
+        status = SDL_SetError("No current OpenGL context");
     }
 
     return status;
@@ -437,8 +392,17 @@ int
 Cocoa_GL_GetSwapInterval(_THIS)
 { @autoreleasepool
 {
-    SDLOpenGLContext *nscontext = (SDLOpenGLContext *) SDL_GL_GetCurrentContext();
-    return nscontext ? SDL_AtomicGet(&nscontext->swapIntervalSetting) : 0;
+    NSOpenGLContext *nscontext;
+    GLint value;
+    int status = 0;
+
+    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+    if (nscontext != nil) {
+        [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
+        status = (int)value;
+    }
+
+    return status;
 }}
 
 int
@@ -447,25 +411,6 @@ Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
 {
     SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext();
     SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
-    const int setting = SDL_AtomicGet(&nscontext->swapIntervalSetting);
-
-    if (setting == 0) {
-        /* nothing to do if vsync is disabled, don't even lock */
-    } else if (setting < 0) {  /* late swap tearing */
-        SDL_LockMutex(nscontext->swapIntervalMutex);
-        while (SDL_AtomicGet(&nscontext->swapIntervalsPassed) == 0) {
-            SDL_CondWait(nscontext->swapIntervalCond, nscontext->swapIntervalMutex);
-        }
-        SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0);
-        SDL_UnlockMutex(nscontext->swapIntervalMutex);
-    } else {
-        SDL_LockMutex(nscontext->swapIntervalMutex);
-        do {  /* always wait here so we know we just hit a swap interval. */
-            SDL_CondWait(nscontext->swapIntervalCond, nscontext->swapIntervalMutex);
-        } while ((SDL_AtomicGet(&nscontext->swapIntervalsPassed) % setting) != 0);
-        SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0);
-        SDL_UnlockMutex(nscontext->swapIntervalMutex);
-    }
 
     /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
        threads try to swap at the same time, so put a mutex around it. */