diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index bb526732..13d463f1 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -144,7 +144,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode) // Convert Core Graphics display mode to GLFW video mode // static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, - CVDisplayLinkRef link) + double fallbackRefreshRate) { GLFWvidmode result; result.width = (int) CGDisplayModeGetWidth(mode); @@ -152,11 +152,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode, result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode)); if (result.refreshRate == 0) - { - const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link); - if (!(time.flags & kCVTimeIsIndefinite)) - result.refreshRate = (int) (time.timeScale / (double) time.timeValue); - } + result.refreshRate = (int) round(fallbackRefreshRate); #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); @@ -238,6 +234,29 @@ static GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor) return GLFW_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 ////// @@ -291,6 +310,7 @@ void _glfwPollMonitorsNS(void) _GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height); monitor->ns.displayID = displays[i]; monitor->ns.unitNumber = unitNumber; + monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(monitor); free(name); @@ -318,9 +338,6 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) if (_glfwCompareVideoModes(¤t, best) == 0) return; - CVDisplayLinkRef link; - CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); - CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); const CFIndex count = CFArrayGetCount(modes); CGDisplayModeRef native = NULL; @@ -331,7 +348,8 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) if (!modeIsGood(dm)) continue; - const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); + const GLFWvidmode mode = + vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate); if (_glfwCompareVideoModes(best, &mode) == 0) { native = dm; @@ -350,7 +368,6 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) } CFRelease(modes); - CVDisplayLinkRelease(link); } // Restore the previously saved (original) video mode @@ -440,9 +457,6 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) *count = 0; - CVDisplayLinkRef link; - CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); - CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); const CFIndex found = CFArrayGetCount(modes); GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode)); @@ -453,7 +467,8 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) if (!modeIsGood(dm)) continue; - const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); + const GLFWvidmode mode = + vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate); CFIndex j; for (j = 0; j < *count; j++) @@ -471,7 +486,6 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) } CFRelease(modes); - CVDisplayLinkRelease(link); return result; } // autoreleasepool @@ -481,15 +495,10 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) { @autoreleasepool { - CVDisplayLinkRef link; - CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); - CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID); - *mode = vidmodeFromCGDisplayMode(native, link); + *mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate); CGDisplayModeRelease(native); - CVDisplayLinkRelease(link); - } // autoreleasepool } diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index b29b64c8..2b7371a1 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -170,6 +170,7 @@ typedef struct _GLFWmonitorNS CGDisplayModeRef previousMode; uint32_t unitNumber; id screen; + double fallbackRefreshRate; } _GLFWmonitorNS;