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
|
- 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
7
glfw/nsgl_context.h
vendored
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user