Cocoa: Only create per-monitor display link once

From upstream: b4a8eb9b19.
This commit is contained in:
Luflosi 2020-01-02 18:05:38 +01:00
parent 003f77b257
commit e725c647ef
No known key found for this signature in database
GPG Key ID: 4E41E29EDCC345D0
2 changed files with 33 additions and 22 deletions

View File

@ -146,7 +146,7 @@ static bool modeIsGood(CGDisplayModeRef mode)
// Convert Core Graphics display mode to GLFW video mode // Convert Core Graphics display mode to GLFW video mode
// //
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
CVDisplayLinkRef link) double fallbackRefreshRate)
{ {
GLFWvidmode result; GLFWvidmode result;
result.width = (int) CGDisplayModeGetWidth(mode); result.width = (int) CGDisplayModeGetWidth(mode);
@ -154,11 +154,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode)); result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
if (result.refreshRate == 0) if (result.refreshRate == 0)
{ result.refreshRate = (int) round(fallbackRefreshRate);
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
if (!(time.flags & kCVTimeIsIndefinite))
result.refreshRate = (int) (time.timeScale / (double) time.timeValue);
}
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
@ -240,6 +236,30 @@ static bool refreshMonitorScreen(_GLFWmonitor* monitor)
return false; return false;
} }
// Returns a fallback refresh rate for when Core Graphics says it is zero
//
static double getFallbackRefreshRate(_GLFWmonitor* monitor)
{
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
double refreshRate = CGDisplayModeGetRefreshRate(mode);
CGDisplayModeRelease(mode);
if (refreshRate == 0.0)
{
CVDisplayLinkRef link = NULL;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
if (!(time.flags & kCVTimeIsIndefinite))
refreshRate = (int) (time.timeScale / (double) time.timeValue);
CVDisplayLinkRelease(link);
}
return refreshRate;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -331,6 +351,7 @@ void _glfwPollMonitorsNS(void)
_GLFWmonitor* monitor = _glfwAllocMonitor(name, (int)size.width, (int)size.height); _GLFWmonitor* monitor = _glfwAllocMonitor(name, (int)size.width, (int)size.height);
monitor->ns.displayID = displays[i]; monitor->ns.displayID = displays[i];
monitor->ns.unitNumber = unitNumber; monitor->ns.unitNumber = unitNumber;
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(monitor);
createDisplayLink(monitor->ns.displayID); createDisplayLink(monitor->ns.displayID);
free(name); free(name);
@ -360,9 +381,6 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
if (_glfwCompareVideoModes(&current, best) == 0) if (_glfwCompareVideoModes(&current, best) == 0)
return; return;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex count = CFArrayGetCount(modes); const CFIndex count = CFArrayGetCount(modes);
CGDisplayModeRef native = NULL; CGDisplayModeRef native = NULL;
@ -373,7 +391,8 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
if (!modeIsGood(dm)) if (!modeIsGood(dm))
continue; continue;
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); const GLFWvidmode mode =
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
if (_glfwCompareVideoModes(best, &mode) == 0) if (_glfwCompareVideoModes(best, &mode) == 0)
{ {
native = dm; native = dm;
@ -392,7 +411,6 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
} }
CFRelease(modes); CFRelease(modes);
CVDisplayLinkRelease(link);
} }
// Restore the previously saved (original) video mode // Restore the previously saved (original) video mode
@ -469,9 +487,6 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
{ {
*count = 0; *count = 0;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex found = CFArrayGetCount(modes); const CFIndex found = CFArrayGetCount(modes);
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode)); GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
@ -482,7 +497,8 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
if (!modeIsGood(dm)) if (!modeIsGood(dm))
continue; continue;
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); const GLFWvidmode mode =
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
for (CFIndex j = 0; j < *count; j++) for (CFIndex j = 0; j < *count; j++)
{ {
@ -499,20 +515,14 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
} }
CFRelease(modes); CFRelease(modes);
CVDisplayLinkRelease(link);
return result; return result;
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
{ {
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID); CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
*mode = vidmodeFromCGDisplayMode(native, link); *mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
CGDisplayModeRelease(native); CGDisplayModeRelease(native);
CVDisplayLinkRelease(link);
} }
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)

View File

@ -201,6 +201,7 @@ typedef struct _GLFWmonitorNS
CGDisplayModeRef previousMode; CGDisplayModeRef previousMode;
uint32_t unitNumber; uint32_t unitNumber;
id screen; id screen;
double fallbackRefreshRate;
} _GLFWmonitorNS; } _GLFWmonitorNS;