macOS: Fix v-sync to monitor refresh rate no longer working under Mojave.

Mojave broke the technique GLFW used to use for v-sync. Changed to use
CVDisplayLink, fix comes from: https://github.com/glfw/glfw/pull/1417
This commit is contained in:
Kovid Goyal 2019-02-17 11:39:49 +05:30
parent fe3a432845
commit 104e213934
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 59 additions and 4 deletions

View File

@ -56,6 +56,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- macOS: When closing a top-level window only switch focus to the previous kitty - macOS: When closing a top-level window only switch focus to the previous kitty
window if it is on the same workspace (:iss:`1379`) window if it is on the same workspace (:iss:`1379`)
- macOS: Fix v-sync to monitor refresh rate no longer working under Mojave. See
:opt:`sync_to_monitor`
0.13.3 [2019-01-19] 0.13.3 [2019-01-19]
------------------------------ ------------------------------

7
glfw/nsgl_context.h vendored
View File

@ -27,6 +27,8 @@
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
#import <CoreVideo/CoreVideo.h>
#include <stdatomic.h>
// NSGL-specific per-context data // NSGL-specific per-context data
// //
@ -34,6 +36,10 @@ typedef struct _GLFWcontextNSGL
{ {
id pixelFormat; id pixelFormat;
id object; id object;
CVDisplayLinkRef displayLink;
atomic_int swapInterval;
int swapIntervalsPassed;
id swapIntervalCond;
} _GLFWcontextNSGL; } _GLFWcontextNSGL;
@ -53,4 +59,3 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig); const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window); void _glfwDestroyContextNSGL(_GLFWwindow* window);

View File

@ -32,6 +32,27 @@
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity #define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif #endif
static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp* now,
const CVTimeStamp* outputTime,
CVOptionFlags flagsIn,
CVOptionFlags* flagsOut,
void* userInfo)
{
_GLFWwindow* window = (_GLFWwindow *) userInfo;
const int setting = atomic_load(&window->context.nsgl.swapInterval);
if (setting > 0)
{
[window->context.nsgl.swapIntervalCond lock];
window->context.nsgl.swapIntervalsPassed++;
[window->context.nsgl.swapIntervalCond signal];
[window->context.nsgl.swapIntervalCond unlock];
}
return kCVReturnSuccess;
}
static void makeContextCurrentNSGL(_GLFWwindow* window) static void makeContextCurrentNSGL(_GLFWwindow* window)
{ {
if (window) if (window)
@ -44,6 +65,18 @@ static void makeContextCurrentNSGL(_GLFWwindow* window)
static void swapBuffersNSGL(_GLFWwindow* window) static void swapBuffersNSGL(_GLFWwindow* window)
{ {
const int setting = atomic_load(&window->context.nsgl.swapInterval);
if (setting > 0)
{
[window->context.nsgl.swapIntervalCond lock];
do
{
[window->context.nsgl.swapIntervalCond wait];
} while (window->context.nsgl.swapIntervalsPassed % setting != 0);
window->context.nsgl.swapIntervalsPassed = 0;
[window->context.nsgl.swapIntervalCond unlock];
}
// ARP appears to be unnecessary, but this is future-proof // ARP appears to be unnecessary, but this is future-proof
[window->context.nsgl.object flushBuffer]; [window->context.nsgl.object flushBuffer];
} }
@ -52,9 +85,11 @@ static void swapIntervalNSGL(int interval)
{ {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
GLint sync = interval; atomic_store(&window->context.nsgl.swapInterval, interval);
[window->context.nsgl.object setValues:&sync [window->context.nsgl.swapIntervalCond lock];
forParameter:NSOpenGLContextParameterSwapInterval]; window->context.nsgl.swapIntervalsPassed = 0;
[window->context.nsgl.swapIntervalCond unlock];
} }
static int extensionSupportedNSGL(const char* extension) static int extensionSupportedNSGL(const char* extension)
@ -316,6 +351,18 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressNSGL; window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL; window->context.destroy = destroyContextNSGL;
CVDisplayLinkCreateWithActiveCGDisplays(&window->context.nsgl.displayLink);
CVDisplayLinkSetOutputCallback(window->context.nsgl.displayLink,
&displayLinkCallback,
window);
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(
window->context.nsgl.displayLink,
(CGLContextObj)window->context.nsgl.object,
(CGLPixelFormatObj)window->context.nsgl.pixelFormat);
CVDisplayLinkStart(window->context.nsgl.displayLink);
window->context.nsgl.swapIntervalCond = [NSCondition new];
return GLFW_TRUE; return GLFW_TRUE;
} }