mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
Move CVDisplayLink code into its own module
Apple has deprecated CVDisplayLink in favor of CADisplayLink which has different semantics. So turn off deprecation warnings for CVDisplayLink related code only until I can be bothered to port it to CADisplayLink.
This commit is contained in:
160
glfw/cocoa_displaylink.m
Normal file
160
glfw/cocoa_displaylink.m
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* cocoa_displaylink.m
|
||||||
|
* Copyright (C) 2024 Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the GPL3 license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// CVDisplayLink is deprecated
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include <CoreVideo/CVDisplayLink.h>
|
||||||
|
|
||||||
|
#define DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL s_to_monotonic_t(30ll)
|
||||||
|
|
||||||
|
typedef struct _GLFWDisplayLinkNS
|
||||||
|
{
|
||||||
|
CVDisplayLinkRef displayLink;
|
||||||
|
CGDirectDisplayID displayID;
|
||||||
|
monotonic_t lastRenderFrameRequestedAt, first_unserviced_render_frame_request_at;
|
||||||
|
} _GLFWDisplayLinkNS;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
_GLFWDisplayLinkNS entries[256];
|
||||||
|
size_t count;
|
||||||
|
} displayLinks = {0};
|
||||||
|
|
||||||
|
static CGDirectDisplayID
|
||||||
|
displayIDForWindow(_GLFWwindow *w) {
|
||||||
|
NSWindow *nw = w->ns.object;
|
||||||
|
NSDictionary *dict = [nw.screen deviceDescription];
|
||||||
|
NSNumber *displayIDns = dict[@"NSScreenNumber"];
|
||||||
|
if (displayIDns) return [displayIDns unsignedIntValue];
|
||||||
|
return (CGDirectDisplayID)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_glfwClearDisplayLinks(void) {
|
||||||
|
for (size_t i = 0; i < displayLinks.count; i++) {
|
||||||
|
if (displayLinks.entries[i].displayLink) {
|
||||||
|
CVDisplayLinkStop(displayLinks.entries[i].displayLink);
|
||||||
|
CVDisplayLinkRelease(displayLinks.entries[i].displayLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(displayLinks.entries, 0, sizeof(_GLFWDisplayLinkNS) * displayLinks.count);
|
||||||
|
displayLinks.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CVReturn
|
||||||
|
displayLinkCallback(
|
||||||
|
CVDisplayLinkRef displayLink UNUSED,
|
||||||
|
const CVTimeStamp* now UNUSED, const CVTimeStamp* outputTime UNUSED,
|
||||||
|
CVOptionFlags flagsIn UNUSED, CVOptionFlags* flagsOut UNUSED, void* userInfo) {
|
||||||
|
CGDirectDisplayID displayID = (uintptr_t)userInfo;
|
||||||
|
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
|
||||||
|
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
|
||||||
|
[arg release];
|
||||||
|
return kCVReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry) {
|
||||||
|
CVDisplayLinkCreateWithCGDisplay(entry->displayID, &entry->displayLink);
|
||||||
|
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)entry->displayID);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
_glfwCreateDisplayLink(CGDirectDisplayID displayID) {
|
||||||
|
if (displayLinks.count >= arraysz(displayLinks.entries) - 1) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many monitors cannot create display link");
|
||||||
|
return displayLinks.count;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < displayLinks.count; i++) {
|
||||||
|
// already created in this run
|
||||||
|
if (displayLinks.entries[i].displayID == displayID) return i;
|
||||||
|
}
|
||||||
|
_GLFWDisplayLinkNS *entry = &displayLinks.entries[displayLinks.count++];
|
||||||
|
memset(entry, 0, sizeof(_GLFWDisplayLinkNS));
|
||||||
|
entry->displayID = displayID;
|
||||||
|
_glfw_create_cv_display_link(entry);
|
||||||
|
return displayLinks.count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long long display_link_shutdown_timer = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_glfwShutdownCVDisplayLink(unsigned long long timer_id UNUSED, void *user_data UNUSED) {
|
||||||
|
display_link_shutdown_timer = 0;
|
||||||
|
for (size_t i = 0; i < displayLinks.count; i++) {
|
||||||
|
_GLFWDisplayLinkNS *dl = &displayLinks.entries[i];
|
||||||
|
if (dl->displayLink) CVDisplayLinkStop(dl->displayLink);
|
||||||
|
dl->lastRenderFrameRequestedAt = 0;
|
||||||
|
dl->first_unserviced_render_frame_request_at = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_glfwRequestRenderFrame(_GLFWwindow *w) {
|
||||||
|
CGDirectDisplayID displayID = displayIDForWindow(w);
|
||||||
|
if (display_link_shutdown_timer) {
|
||||||
|
_glfwPlatformUpdateTimer(display_link_shutdown_timer, DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL, true);
|
||||||
|
} else {
|
||||||
|
display_link_shutdown_timer = _glfwPlatformAddTimer(DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL, false, _glfwShutdownCVDisplayLink, NULL, NULL);
|
||||||
|
}
|
||||||
|
monotonic_t now = glfwGetTime();
|
||||||
|
bool found_display_link = false;
|
||||||
|
_GLFWDisplayLinkNS *dl = NULL;
|
||||||
|
for (size_t i = 0; i < displayLinks.count; i++) {
|
||||||
|
dl = &displayLinks.entries[i];
|
||||||
|
if (dl->displayID == displayID) {
|
||||||
|
found_display_link = true;
|
||||||
|
dl->lastRenderFrameRequestedAt = now;
|
||||||
|
if (!dl->first_unserviced_render_frame_request_at) dl->first_unserviced_render_frame_request_at = now;
|
||||||
|
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
||||||
|
else if (now - dl->first_unserviced_render_frame_request_at > s_to_monotonic_t(1ll)) {
|
||||||
|
// display link is stuck need to recreate it because Apple can't even
|
||||||
|
// get a simple timer right
|
||||||
|
CVDisplayLinkRelease(dl->displayLink); dl->displayLink = nil;
|
||||||
|
dl->first_unserviced_render_frame_request_at = now;
|
||||||
|
_glfw_create_cv_display_link(dl);
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"CVDisplayLink stuck possibly because of sleep/screensaver + Apple's incompetence, recreating.");
|
||||||
|
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
||||||
|
}
|
||||||
|
} else if (dl->displayLink && dl->lastRenderFrameRequestedAt && now - dl->lastRenderFrameRequestedAt >= DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL) {
|
||||||
|
CVDisplayLinkStop(dl->displayLink);
|
||||||
|
dl->lastRenderFrameRequestedAt = 0;
|
||||||
|
dl->first_unserviced_render_frame_request_at = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found_display_link) {
|
||||||
|
unsigned idx = _glfwCreateDisplayLink(displayID);
|
||||||
|
if (idx < displayLinks.count) {
|
||||||
|
dl = &displayLinks.entries[idx];
|
||||||
|
dl->lastRenderFrameRequestedAt = now;
|
||||||
|
dl->first_unserviced_render_frame_request_at = now;
|
||||||
|
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_glfwDispatchRenderFrame(CGDirectDisplayID displayID) {
|
||||||
|
_GLFWwindow *w = _glfw.windowListHead;
|
||||||
|
while (w) {
|
||||||
|
if (w->ns.renderFrameRequested && displayID == displayIDForWindow(w)) {
|
||||||
|
w->ns.renderFrameRequested = false;
|
||||||
|
w->ns.renderFrameCallback((GLFWwindow*)w);
|
||||||
|
}
|
||||||
|
w = w->next;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < displayLinks.count; i++) {
|
||||||
|
_GLFWDisplayLinkNS *dl = &displayLinks.entries[i];
|
||||||
|
if (dl->displayID == displayID) {
|
||||||
|
dl->first_unserviced_render_frame_request_at = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
// It is fine to use C99 in this file because it will not be built with VS
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -36,7 +35,6 @@
|
|||||||
|
|
||||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||||
#include <CoreVideo/CVBase.h>
|
#include <CoreVideo/CVBase.h>
|
||||||
#include <CoreVideo/CVDisplayLink.h>
|
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -324,54 +322,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void _glfwClearDisplayLinks(void) {
|
|
||||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
|
||||||
if (_glfw.ns.displayLinks.entries[i].displayLink) {
|
|
||||||
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
|
|
||||||
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memset(_glfw.ns.displayLinks.entries, 0, sizeof(_GLFWDisplayLinkNS) * _glfw.ns.displayLinks.count);
|
|
||||||
_glfw.ns.displayLinks.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CVReturn displayLinkCallback(
|
|
||||||
CVDisplayLinkRef displayLink UNUSED,
|
|
||||||
const CVTimeStamp* now UNUSED, const CVTimeStamp* outputTime UNUSED,
|
|
||||||
CVOptionFlags flagsIn UNUSED, CVOptionFlags* flagsOut UNUSED, void* userInfo)
|
|
||||||
{
|
|
||||||
CGDirectDisplayID displayID = (uintptr_t)userInfo;
|
|
||||||
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
|
|
||||||
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
|
|
||||||
[arg release];
|
|
||||||
return kCVReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry) {
|
|
||||||
CVDisplayLinkCreateWithCGDisplay(entry->displayID, &entry->displayLink);
|
|
||||||
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)entry->displayID);
|
|
||||||
}
|
|
||||||
|
|
||||||
_GLFWDisplayLinkNS*
|
|
||||||
_glfw_create_display_link(CGDirectDisplayID displayID) {
|
|
||||||
if (_glfw.ns.displayLinks.count >= arraysz(_glfw.ns.displayLinks.entries) - 1) {
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many monitors cannot create display link");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
|
||||||
// already created in this run
|
|
||||||
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return _glfw.ns.displayLinks.entries + i;
|
|
||||||
}
|
|
||||||
_GLFWDisplayLinkNS *entry = &_glfw.ns.displayLinks.entries[_glfw.ns.displayLinks.count++];
|
|
||||||
memset(entry, 0, sizeof(_GLFWDisplayLinkNS));
|
|
||||||
entry->displayID = displayID;
|
|
||||||
_glfw_create_cv_display_link(entry);
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poll for changes in the set of connected monitors
|
// Poll for changes in the set of connected monitors
|
||||||
//
|
|
||||||
void _glfwPollMonitorsNS(void)
|
void _glfwPollMonitorsNS(void)
|
||||||
{
|
{
|
||||||
uint32_t displayCount;
|
uint32_t displayCount;
|
||||||
@@ -427,7 +378,7 @@ void _glfwPollMonitorsNS(void)
|
|||||||
{
|
{
|
||||||
disconnected[j]->ns.displayID = displays[i];
|
disconnected[j]->ns.displayID = displays[i];
|
||||||
disconnected[j]->ns.screen = screen;
|
disconnected[j]->ns.screen = screen;
|
||||||
_glfw_create_display_link(displays[i]);
|
_glfwCreateDisplayLink(displays[i]);
|
||||||
disconnected[j] = NULL;
|
disconnected[j] = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -448,7 +399,7 @@ void _glfwPollMonitorsNS(void)
|
|||||||
monitor->ns.displayID = displays[i];
|
monitor->ns.displayID = displays[i];
|
||||||
monitor->ns.unitNumber = unitNumber;
|
monitor->ns.unitNumber = unitNumber;
|
||||||
monitor->ns.screen = screen;
|
monitor->ns.screen = screen;
|
||||||
_glfw_create_display_link(monitor->ns.displayID);
|
_glfwCreateDisplayLink(monitor->ns.displayID);
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
|
|
||||||
|
|||||||
25
glfw/cocoa_platform.h
vendored
25
glfw/cocoa_platform.h
vendored
@@ -30,10 +30,8 @@
|
|||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
#if defined(__OBJC__)
|
#if defined(__OBJC__)
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <CoreVideo/CoreVideo.h>
|
|
||||||
#else
|
#else
|
||||||
typedef void* id;
|
typedef void* id;
|
||||||
typedef void* CVDisplayLinkRef;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||||
@@ -160,13 +158,6 @@ typedef struct _GLFWwindowNS
|
|||||||
GLFWcocoarenderframefun resizeCallback;
|
GLFWcocoarenderframefun resizeCallback;
|
||||||
} _GLFWwindowNS;
|
} _GLFWwindowNS;
|
||||||
|
|
||||||
typedef struct _GLFWDisplayLinkNS
|
|
||||||
{
|
|
||||||
CVDisplayLinkRef displayLink;
|
|
||||||
CGDirectDisplayID displayID;
|
|
||||||
monotonic_t lastRenderFrameRequestedAt, first_unserviced_render_frame_request_at;
|
|
||||||
} _GLFWDisplayLinkNS;
|
|
||||||
|
|
||||||
// Cocoa-specific global data
|
// Cocoa-specific global data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWlibraryNS
|
typedef struct _GLFWlibraryNS
|
||||||
@@ -199,10 +190,6 @@ typedef struct _GLFWlibraryNS
|
|||||||
CFStringRef kPropertyUnicodeKeyLayoutData;
|
CFStringRef kPropertyUnicodeKeyLayoutData;
|
||||||
} tis;
|
} tis;
|
||||||
|
|
||||||
struct {
|
|
||||||
_GLFWDisplayLinkNS entries[256];
|
|
||||||
size_t count;
|
|
||||||
} displayLinks;
|
|
||||||
// the callback to handle url open events
|
// the callback to handle url open events
|
||||||
GLFWhandleurlopen url_open_callback;
|
GLFWhandleurlopen url_open_callback;
|
||||||
|
|
||||||
@@ -244,12 +231,16 @@ float _glfwTransformYNS(float y);
|
|||||||
|
|
||||||
void* _glfwLoadLocalVulkanLoaderNS(void);
|
void* _glfwLoadLocalVulkanLoaderNS(void);
|
||||||
|
|
||||||
|
|
||||||
|
// display links
|
||||||
void _glfwClearDisplayLinks(void);
|
void _glfwClearDisplayLinks(void);
|
||||||
void _glfwRestartDisplayLinks(void);
|
void _glfwRestartDisplayLinks(void);
|
||||||
void _glfwDispatchTickCallback(void);
|
unsigned _glfwCreateDisplayLink(CGDirectDisplayID);
|
||||||
void _glfwDispatchRenderFrame(CGDirectDisplayID);
|
void _glfwDispatchRenderFrame(CGDirectDisplayID);
|
||||||
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
|
void _glfwRequestRenderFrame(_GLFWwindow *w);
|
||||||
|
|
||||||
|
// event loop
|
||||||
|
void _glfwDispatchTickCallback(void);
|
||||||
void _glfwCocoaPostEmptyEvent(void);
|
void _glfwCocoaPostEmptyEvent(void);
|
||||||
void _glfw_create_cv_display_link(_GLFWDisplayLinkNS *entry);
|
|
||||||
_GLFWDisplayLinkNS* _glfw_create_display_link(CGDirectDisplayID);
|
|
||||||
uint32_t vk_to_unicode_key_with_current_layout(uint16_t keycode);
|
uint32_t vk_to_unicode_key_with_current_layout(uint16_t keycode);
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
// It is fine to use C99 in this file because it will not be built with VS
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#include "../kitty/monotonic.h"
|
#include "../kitty/monotonic.h"
|
||||||
#include "glfw3.h"
|
#include "glfw3.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
@@ -307,28 +306,6 @@ static NSUInteger getStyleMask(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CGDirectDisplayID displayIDForWindow(_GLFWwindow *w) {
|
|
||||||
NSWindow *nw = w->ns.object;
|
|
||||||
NSDictionary *dict = [nw.screen deviceDescription];
|
|
||||||
NSNumber *displayIDns = dict[@"NSScreenNumber"];
|
|
||||||
if (displayIDns) return [displayIDns unsignedIntValue];
|
|
||||||
return (CGDirectDisplayID)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long long display_link_shutdown_timer = 0;
|
|
||||||
#define DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL s_to_monotonic_t(30ll)
|
|
||||||
|
|
||||||
void
|
|
||||||
_glfwShutdownCVDisplayLink(unsigned long long timer_id UNUSED, void *user_data UNUSED) {
|
|
||||||
display_link_shutdown_timer = 0;
|
|
||||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
|
||||||
_GLFWDisplayLinkNS *dl = &_glfw.ns.displayLinks.entries[i];
|
|
||||||
if (dl->displayLink) CVDisplayLinkStop(dl->displayLink);
|
|
||||||
dl->lastRenderFrameRequestedAt = 0;
|
|
||||||
dl->first_unserviced_render_frame_request_at = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
requestRenderFrame(_GLFWwindow *w, GLFWcocoarenderframefun callback) {
|
requestRenderFrame(_GLFWwindow *w, GLFWcocoarenderframefun callback) {
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
@@ -338,46 +315,7 @@ requestRenderFrame(_GLFWwindow *w, GLFWcocoarenderframefun callback) {
|
|||||||
}
|
}
|
||||||
w->ns.renderFrameCallback = callback;
|
w->ns.renderFrameCallback = callback;
|
||||||
w->ns.renderFrameRequested = true;
|
w->ns.renderFrameRequested = true;
|
||||||
CGDirectDisplayID displayID = displayIDForWindow(w);
|
_glfwRequestRenderFrame(w);
|
||||||
if (display_link_shutdown_timer) {
|
|
||||||
_glfwPlatformUpdateTimer(display_link_shutdown_timer, DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL, true);
|
|
||||||
} else {
|
|
||||||
display_link_shutdown_timer = _glfwPlatformAddTimer(DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL, false, _glfwShutdownCVDisplayLink, NULL, NULL);
|
|
||||||
}
|
|
||||||
monotonic_t now = glfwGetTime();
|
|
||||||
bool found_display_link = false;
|
|
||||||
_GLFWDisplayLinkNS *dl = NULL;
|
|
||||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
|
||||||
dl = &_glfw.ns.displayLinks.entries[i];
|
|
||||||
if (dl->displayID == displayID) {
|
|
||||||
found_display_link = true;
|
|
||||||
dl->lastRenderFrameRequestedAt = now;
|
|
||||||
if (!dl->first_unserviced_render_frame_request_at) dl->first_unserviced_render_frame_request_at = now;
|
|
||||||
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
|
||||||
else if (now - dl->first_unserviced_render_frame_request_at > s_to_monotonic_t(1ll)) {
|
|
||||||
// display link is stuck need to recreate it because Apple can't even
|
|
||||||
// get a simple timer right
|
|
||||||
CVDisplayLinkRelease(dl->displayLink); dl->displayLink = nil;
|
|
||||||
dl->first_unserviced_render_frame_request_at = now;
|
|
||||||
_glfw_create_cv_display_link(dl);
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"CVDisplayLink stuck possibly because of sleep/screensaver + Apple's incompetence, recreating.");
|
|
||||||
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
|
||||||
}
|
|
||||||
} else if (dl->displayLink && dl->lastRenderFrameRequestedAt && now - dl->lastRenderFrameRequestedAt >= DISPLAY_LINK_SHUTDOWN_CHECK_INTERVAL) {
|
|
||||||
CVDisplayLinkStop(dl->displayLink);
|
|
||||||
dl->lastRenderFrameRequestedAt = 0;
|
|
||||||
dl->first_unserviced_render_frame_request_at = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found_display_link) {
|
|
||||||
dl = _glfw_create_display_link(displayID);
|
|
||||||
if (dl) {
|
|
||||||
dl->lastRenderFrameRequestedAt = now;
|
|
||||||
dl->first_unserviced_render_frame_request_at = now;
|
|
||||||
if (!CVDisplayLinkIsRunning(dl->displayLink)) CVDisplayLinkStart(dl->displayLink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2338,24 +2276,6 @@ bool _glfwPlatformRawMouseMotionSupported(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
_glfwDispatchRenderFrame(CGDirectDisplayID displayID) {
|
|
||||||
_GLFWwindow *w = _glfw.windowListHead;
|
|
||||||
while (w) {
|
|
||||||
if (w->ns.renderFrameRequested && displayID == displayIDForWindow(w)) {
|
|
||||||
w->ns.renderFrameRequested = false;
|
|
||||||
w->ns.renderFrameCallback((GLFWwindow*)w);
|
|
||||||
}
|
|
||||||
w = w->next;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
|
||||||
_GLFWDisplayLinkNS *dl = &_glfw.ns.displayLinks.entries[i];
|
|
||||||
if (dl->displayID == displayID) {
|
|
||||||
dl->first_unserviced_render_frame_request_at = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||||
{
|
{
|
||||||
const NSRect contentRect = [window->ns.view frame];
|
const NSRect contentRect = [window->ns.view frame];
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"cocoa_joystick.m",
|
"cocoa_joystick.m",
|
||||||
"cocoa_monitor.m",
|
"cocoa_monitor.m",
|
||||||
"cocoa_window.m",
|
"cocoa_window.m",
|
||||||
|
"cocoa_displaylink.m",
|
||||||
"posix_thread.c",
|
"posix_thread.c",
|
||||||
"nsgl_context.m",
|
"nsgl_context.m",
|
||||||
"egl_context.c",
|
"egl_context.c",
|
||||||
|
|||||||
Reference in New Issue
Block a user