Browse Source

macOS: Add hint for blocking thread on OpenGL context update dispatch (#5708)

Salman Ahmed 3 years ago
parent
commit
b4660e9d8b
2 changed files with 34 additions and 1 deletions
  1. 12 0
      include/SDL_hints.h
  2. 22 1
      src/video/cocoa/SDL_cocoaopengl.m

+ 12 - 0
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"
 #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.
  *  \brief  A variable setting the double click radius, in pixels.
  */
  */

+ 22 - 1
src/video/cocoa/SDL_cocoaopengl.m

@@ -31,8 +31,10 @@
 #include <OpenGL/OpenGL.h>
 #include <OpenGL/OpenGL.h>
 #include <OpenGL/CGLRenderers.h>
 #include <OpenGL/CGLRenderers.h>
 
 
+#include "SDL_hints.h"
 #include "SDL_loadso.h"
 #include "SDL_loadso.h"
 #include "SDL_opengl.h"
 #include "SDL_opengl.h"
+#include "../../SDL_hints_c.h"
 
 
 #define DEFAULT_OPENGL  "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
 #define DEFAULT_OPENGL  "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
 
 
@@ -42,6 +44,14 @@
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
 #endif
 #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
 @implementation SDLOpenGLContext : NSOpenGLContext
 
 
 - (id)initWithFormat:(NSOpenGLPixelFormat *)format
 - (id)initWithFormat:(NSOpenGLPixelFormat *)format
@@ -52,6 +62,8 @@
         SDL_AtomicSet(&self->dirty, 0);
         SDL_AtomicSet(&self->dirty, 0);
         self->window = NULL;
         self->window = NULL;
     }
     }
+
+    SDL_AddHintCallback(SDL_HINT_MAC_OPENGL_SYNC_DISPATCH, SDL_OpenGLSyncDispatchChanged, NULL);
     return self;
     return self;
 }
 }
 
 
@@ -135,10 +147,19 @@
     if ([NSThread isMainThread]) {
     if ([NSThread isMainThread]) {
         [super update];
         [super update];
     } else {
     } 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
 @end