diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m index c7d0c60e5..9539c1779 100644 --- a/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/video/cocoa/SDL_cocoaopengl.m @@ -410,8 +410,14 @@ Cocoa_GL_SwapWindow(_THIS, SDL_Window * window) { @autoreleasepool { SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext(); + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + /* 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. */ + SDL_LockMutex(videodata->swaplock); [nscontext flushBuffer]; [nscontext updateIfNeeded]; + SDL_UnlockMutex(videodata->swaplock); return 0; }} diff --git a/src/video/cocoa/SDL_cocoavideo.h b/src/video/cocoa/SDL_cocoavideo.h index 05bbd3483..b1c26fa7e 100644 --- a/src/video/cocoa/SDL_cocoavideo.h +++ b/src/video/cocoa/SDL_cocoavideo.h @@ -107,7 +107,7 @@ typedef struct SDL_VideoData Uint32 screensaver_activity; BOOL screensaver_use_iopm; IOPMAssertionID screensaver_assertion; - + SDL_mutex *swaplock; } SDL_VideoData; /* Utility functions */ diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 977022494..20bdfa791 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -175,15 +175,23 @@ Cocoa_VideoInit(_THIS) /* The IOPM assertion API can disable the screensaver as of 10.7. */ data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6; + data->swaplock = SDL_CreateMutex(); + if (!data->swaplock) { + return -1; + } + return 0; } void Cocoa_VideoQuit(_THIS) { + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; Cocoa_QuitModes(_this); Cocoa_QuitKeyboard(_this); Cocoa_QuitMouse(_this); + SDL_DestroyMutex(data->swaplock); + data->swaplock = NULL; } /* This function assumes that it's called from within an autorelease pool */