macOS: Add hint for blocking thread on OpenGL context update dispatch (#5708)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 1cb2cc2..b0e7338 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -978,6 +978,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.
*/
#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS"
diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m
index 5b41b18..31fe948 100644
--- a/src/video/cocoa/SDL_cocoaopengl.m
+++ b/src/video/cocoa/SDL_cocoaopengl.m
@@ -31,8 +31,10 @@
#include <OpenGL/OpenGL.h>
#include <OpenGL/CGLRenderers.h>
+#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