diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 1cb2cc2bd..b0e73386c 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -977,6 +977,18 @@ extern "C" { */ #define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" +/** + * \brief A variable controlling whether dispatching OpenGL context updates should block the dispatching thread until the main thread finishes processing + * + * This variable can be set to the following values: + * "0" - Dispatching OpenGL context updates will allow the dispatching thread to continue execution. + * "1" - Dispatching OpenGL context updates will block the dispatching thread until the main thread finishes processing. + * + * This hint only applies to Mac OS X + * + */ +#define SDL_HINT_MAC_OPENGL_SYNC_DISPATCH "SDL_MAC_OPENGL_SYNC_DISPATCH" + /** * \brief A variable setting the double click radius, in pixels. */ diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m index 5b41b1822..31fe948a8 100644 --- a/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/video/cocoa/SDL_cocoaopengl.m @@ -31,8 +31,10 @@ #include #include +#include "SDL_hints.h" #include "SDL_loadso.h" #include "SDL_opengl.h" +#include "../../SDL_hints_c.h" #define DEFAULT_OPENGL "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib" @@ -42,6 +44,14 @@ #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif +static SDL_bool SDL_opengl_sync_dispatch = SDL_FALSE; + +static void SDLCALL +SDL_OpenGLSyncDispatchChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_opengl_sync_dispatch = SDL_GetStringBoolean(hint, SDL_FALSE); +} + @implementation SDLOpenGLContext : NSOpenGLContext - (id)initWithFormat:(NSOpenGLPixelFormat *)format @@ -52,6 +62,8 @@ SDL_AtomicSet(&self->dirty, 0); self->window = NULL; } + + SDL_AddHintCallback(SDL_HINT_MAC_OPENGL_SYNC_DISPATCH, SDL_OpenGLSyncDispatchChanged, NULL); return self; } @@ -135,10 +147,19 @@ if ([NSThread isMainThread]) { [super update]; } else { - dispatch_async(dispatch_get_main_queue(), ^{ [super update]; }); + if (SDL_opengl_sync_dispatch) { + dispatch_sync(dispatch_get_main_queue(), ^{ [super update]; }); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ [super update]; }); + } } } +- (void)dealloc +{ + SDL_DelHintCallback(SDL_HINT_MAC_OPENGL_SYNC_DISPATCH, SDL_OpenGLSyncDispatchChanged, NULL); +} + @end