NSGL: Simulate vsync for occluded windows

This only supports a swap interval of zero or one, as that is all NSGL
supports.

(cherry picked from commit c3ca88055f)
This commit is contained in:
Camilla Löwy 2019-11-10 19:09:23 +01:00 committed by Camilla Löwy
parent ccb54c3e05
commit bb8ed627bf

View File

@ -28,6 +28,9 @@
#include "internal.h" #include "internal.h"
#include <unistd.h>
#include <math.h>
static void makeContextCurrentNSGL(_GLFWwindow* window) static void makeContextCurrentNSGL(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
@ -45,7 +48,31 @@ static void makeContextCurrentNSGL(_GLFWwindow* window)
static void swapBuffersNSGL(_GLFWwindow* window) static void swapBuffersNSGL(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
// windows with a non-visible occlusion state
if (!([window->ns.object occlusionState] & NSWindowOcclusionStateVisible))
{
int interval = 0;
[window->context.nsgl.object getValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
if (interval > 0)
{
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));
}
}
[window->context.nsgl.object flushBuffer]; [window->context.nsgl.object flushBuffer];
} // autoreleasepool } // autoreleasepool
} }
@ -53,10 +80,10 @@ static void swapIntervalNSGL(int interval)
{ {
@autoreleasepool { @autoreleasepool {
NSOpenGLContext* context = [NSOpenGLContext currentContext]; _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (context) if (window)
{ {
[context setValues:&interval [window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval]; forParameter:NSOpenGLContextParameterSwapInterval];
} }