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:
parent
fe3a432845
commit
104e213934
@ -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
|
||||
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]
|
||||
------------------------------
|
||||
|
||||
|
||||
7
glfw/nsgl_context.h
vendored
7
glfw/nsgl_context.h
vendored
@ -27,6 +27,8 @@
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
|
||||
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
// NSGL-specific per-context data
|
||||
//
|
||||
@ -34,6 +36,10 @@ typedef struct _GLFWcontextNSGL
|
||||
{
|
||||
id pixelFormat;
|
||||
id object;
|
||||
CVDisplayLinkRef displayLink;
|
||||
atomic_int swapInterval;
|
||||
int swapIntervalsPassed;
|
||||
id swapIntervalCond;
|
||||
|
||||
} _GLFWcontextNSGL;
|
||||
|
||||
@ -53,4 +59,3 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||
|
||||
|
||||
@ -32,6 +32,27 @@
|
||||
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||
#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)
|
||||
{
|
||||
if (window)
|
||||
@ -44,6 +65,18 @@ static void makeContextCurrentNSGL(_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
|
||||
[window->context.nsgl.object flushBuffer];
|
||||
}
|
||||
@ -52,9 +85,11 @@ static void swapIntervalNSGL(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
|
||||
GLint sync = interval;
|
||||
[window->context.nsgl.object setValues:&sync
|
||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||
atomic_store(&window->context.nsgl.swapInterval, interval);
|
||||
[window->context.nsgl.swapIntervalCond lock];
|
||||
window->context.nsgl.swapIntervalsPassed = 0;
|
||||
|
||||
[window->context.nsgl.swapIntervalCond unlock];
|
||||
}
|
||||
|
||||
static int extensionSupportedNSGL(const char* extension)
|
||||
@ -316,6 +351,18 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressNSGL;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user