mirror of
https://github.com/ZDoom/zdoom-macos-deps.git
synced 2025-04-23 00:40:58 +00:00
191 lines
6.7 KiB
Diff
191 lines
6.7 KiB
Diff
|
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
||
|
index 1057a6f9..36b3fe0b 100644
|
||
|
--- a/src/CMakeLists.txt
|
||
|
+++ b/src/CMakeLists.txt
|
||
|
@@ -151,10 +151,11 @@ endif()
|
||
|
if (GLFW_BUILD_COCOA)
|
||
|
target_link_libraries(glfw PRIVATE "-framework Cocoa"
|
||
|
"-framework IOKit"
|
||
|
- "-framework CoreFoundation")
|
||
|
+ "-framework CoreFoundation"
|
||
|
+ "-framework CoreVideo")
|
||
|
|
||
|
set(glfw_PKG_DEPS "")
|
||
|
- set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
|
||
|
+ set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
|
||
|
endif()
|
||
|
|
||
|
if (GLFW_BUILD_WAYLAND)
|
||
|
diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h
|
||
|
index 39914554..ad32e83d 100644
|
||
|
--- a/src/cocoa_platform.h
|
||
|
+++ b/src/cocoa_platform.h
|
||
|
@@ -37,8 +37,10 @@
|
||
|
|
||
|
#if defined(__OBJC__)
|
||
|
#import <Cocoa/Cocoa.h>
|
||
|
+#import <CoreVideo/CoreVideo.h>
|
||
|
#else
|
||
|
typedef void* id;
|
||
|
+typedef void* CVDisplayLinkRef;
|
||
|
#endif
|
||
|
|
||
|
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||
|
@@ -124,6 +126,10 @@ typedef struct _GLFWcontextNSGL
|
||
|
{
|
||
|
id pixelFormat;
|
||
|
id object;
|
||
|
+ int swapInterval;
|
||
|
+ int swapIntervalsPassed;
|
||
|
+ id swapIntervalCond;
|
||
|
+ CVDisplayLinkRef displayLink;
|
||
|
} _GLFWcontextNSGL;
|
||
|
|
||
|
// NSGL-specific global data
|
||
|
@@ -299,4 +305,5 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||
|
const _GLFWctxconfig* ctxconfig,
|
||
|
const _GLFWfbconfig* fbconfig);
|
||
|
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||
|
+void _glfwUpdateDisplayLinkNSGL(_GLFWwindow* window);
|
||
|
|
||
|
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
|
||
|
index 0dcf0a38..a4a7ae41 100644
|
||
|
--- a/src/cocoa_window.m
|
||
|
+++ b/src/cocoa_window.m
|
||
|
@@ -320,6 +320,12 @@ - (void)windowDidChangeOcclusionState:(NSNotification* )notification
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
+- (void)windowDidChangeScreen:(NSNotification *)notification
|
||
|
+{
|
||
|
+ if (window->context.source == GLFW_NATIVE_CONTEXT_API)
|
||
|
+ _glfwUpdateDisplayLinkNSGL(window);
|
||
|
+}
|
||
|
+
|
||
|
@end
|
||
|
|
||
|
|
||
|
diff --git a/src/nsgl_context.m b/src/nsgl_context.m
|
||
|
index daa8367a..b2c109d2 100644
|
||
|
--- a/src/nsgl_context.m
|
||
|
+++ b/src/nsgl_context.m
|
||
|
@@ -45,30 +45,42 @@ static void makeContextCurrentNSGL(_GLFWwindow* window)
|
||
|
} // autoreleasepool
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+static CVReturn nsglDisplayLinkCallback(CVDisplayLinkRef displayLink,
|
||
|
+ const CVTimeStamp* now,
|
||
|
+ const CVTimeStamp* outputTime,
|
||
|
+ CVOptionFlags flagsIn,
|
||
|
+ CVOptionFlags* flagsOut,
|
||
|
+ void* userContext)
|
||
|
+{
|
||
|
+ _GLFWcontextNSGL* nsgl = (_GLFWcontextNSGL*)userContext;
|
||
|
+ NSCondition* intervalCond = nsgl->swapIntervalCond;
|
||
|
+
|
||
|
+ [intervalCond lock];
|
||
|
+ ++nsgl->swapIntervalsPassed;
|
||
|
+ [intervalCond signal];
|
||
|
+ [intervalCond unlock];
|
||
|
+
|
||
|
+ return kCVReturnSuccess;
|
||
|
+}
|
||
|
+
|
||
|
static void swapBuffersNSGL(_GLFWwindow* window)
|
||
|
{
|
||
|
@autoreleasepool {
|
||
|
|
||
|
- // HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
|
||
|
- // windows with a non-visible occlusion state
|
||
|
- if (window->ns.occluded)
|
||
|
+ if (window->context.nsgl.swapInterval > 0)
|
||
|
{
|
||
|
- int interval = 0;
|
||
|
- [window->context.nsgl.object getValues:&interval
|
||
|
- forParameter:NSOpenGLContextParameterSwapInterval];
|
||
|
+ [window->context.nsgl.swapIntervalCond lock];
|
||
|
|
||
|
- if (interval > 0)
|
||
|
+ do
|
||
|
{
|
||
|
- const double framerate = 60.0;
|
||
|
- const uint64_t frequency = _glfwPlatformGetTimerFrequency();
|
||
|
- const uint64_t value = _glfwPlatformGetTimerValue();
|
||
|
-
|
||
|
- const double elapsed = value / (double) frequency;
|
||
|
- const double period = 1.0 / framerate;
|
||
|
- const double delay = period - fmod(elapsed, period);
|
||
|
-
|
||
|
- usleep(floorl(delay * 1e6));
|
||
|
+ // do-while guarantees at least one swap interval has occurred.
|
||
|
+ [window->context.nsgl.swapIntervalCond wait];
|
||
|
}
|
||
|
+ while (window->context.nsgl.swapIntervalsPassed % window->context.nsgl.swapInterval != 0);
|
||
|
+
|
||
|
+ window->context.nsgl.swapIntervalsPassed = 0;
|
||
|
+ [window->context.nsgl.swapIntervalCond unlock];
|
||
|
}
|
||
|
|
||
|
[window->context.nsgl.object flushBuffer];
|
||
|
@@ -83,8 +95,7 @@ static void swapIntervalNSGL(int interval)
|
||
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||
|
assert(window != NULL);
|
||
|
|
||
|
- [window->context.nsgl.object setValues:&interval
|
||
|
- forParameter:NSOpenGLContextParameterSwapInterval];
|
||
|
+ window->context.nsgl.swapInterval = interval;
|
||
|
|
||
|
} // autoreleasepool
|
||
|
}
|
||
|
@@ -113,6 +124,13 @@ static void destroyContextNSGL(_GLFWwindow* window)
|
||
|
{
|
||
|
@autoreleasepool {
|
||
|
|
||
|
+ CVDisplayLinkStop(window->context.nsgl.displayLink);
|
||
|
+ CVDisplayLinkRelease(window->context.nsgl.displayLink);
|
||
|
+ window->context.nsgl.displayLink = NULL;
|
||
|
+
|
||
|
+ [window->context.nsgl.swapIntervalCond release];
|
||
|
+ window->context.nsgl.swapIntervalCond = nil;
|
||
|
+
|
||
|
[window->context.nsgl.pixelFormat release];
|
||
|
window->context.nsgl.pixelFormat = nil;
|
||
|
|
||
|
@@ -344,6 +362,21 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||
|
|
||
|
[window->context.nsgl.object setView:window->ns.view];
|
||
|
|
||
|
+ window->context.nsgl.swapInterval = 0; // Default value of NSGL swap interval
|
||
|
+ window->context.nsgl.swapIntervalsPassed = 0;
|
||
|
+ window->context.nsgl.swapIntervalCond = [[NSCondition alloc] init];
|
||
|
+
|
||
|
+ // Explicitly set NSGL swap interval to 0, since CVDisplayLink will be used
|
||
|
+ // instead.
|
||
|
+ int swapInterval = 0;
|
||
|
+ [window->context.nsgl.object setValues:&swapInterval
|
||
|
+ forParameter:NSOpenGLContextParameterSwapInterval];
|
||
|
+
|
||
|
+ CVDisplayLinkCreateWithActiveCGDisplays(&window->context.nsgl.displayLink);
|
||
|
+ CVDisplayLinkSetOutputCallback(window->context.nsgl.displayLink, &nsglDisplayLinkCallback, &window->context.nsgl);
|
||
|
+ _glfwUpdateDisplayLinkNSGL(window);
|
||
|
+ CVDisplayLinkStart(window->context.nsgl.displayLink);
|
||
|
+
|
||
|
window->context.makeCurrent = makeContextCurrentNSGL;
|
||
|
window->context.swapBuffers = swapBuffersNSGL;
|
||
|
window->context.swapInterval = swapIntervalNSGL;
|
||
|
@@ -354,6 +387,13 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||
|
return GLFW_TRUE;
|
||
|
}
|
||
|
|
||
|
+void _glfwUpdateDisplayLinkNSGL(_GLFWwindow* window)
|
||
|
+{
|
||
|
+ CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(window->context.nsgl.displayLink,
|
||
|
+ [window->context.nsgl.object CGLContextObj],
|
||
|
+ [window->context.nsgl.pixelFormat CGLPixelFormatObj]);
|
||
|
+}
|
||
|
+
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
////// GLFW native API //////
|