@@ -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 @@ - (id)initWithFormat:(NSOpenGLPixelFormat *)format
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 @@ - (void)setWindow:(SDL_Window *)newWindow
}
}
- (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 @@ - (void)dealloc
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 @@ - (void)dealloc
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 @@ - (void)dealloc
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 @@ - (void)dealloc
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 @@ - (void)dealloc
{
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. */