From 87dd7b89f554d536de2b859f2eb7bb7d3e98406e Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Mar 2014 12:34:15 +0100 Subject: [PATCH] Video mode detection cleanup. --- src/cocoa_monitor.m | 90 +++++++++++++++++++-------------------------- src/win32_monitor.c | 1 - src/x11_monitor.c | 19 ++++++---- src/x11_platform.h | 2 +- 4 files changed, 49 insertions(+), 63 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 2f53a328..f430734e 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -163,74 +163,60 @@ static void endFadeReservation(CGDisplayFadeReservationToken token) // GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) { - CGDisplayModeRef bestMode = NULL; CFArrayRef modes; CFIndex count, i; - unsigned int sizeDiff, leastSizeDiff = UINT_MAX; - unsigned int rateDiff, leastRateDiff = UINT_MAX; - const int bpp = desired->redBits - desired->greenBits - desired->blueBits; + CVDisplayLinkRef link; + CGDisplayModeRef native = NULL; + GLFWvidmode current; + const GLFWvidmode* best; + + best = _glfwChooseVideoMode(monitor, desired); + _glfwPlatformGetVideoMode(monitor, ¤t); + if (_glfwCompareVideoModes(¤t, best) == 0) + return GL_TRUE; + + CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link); modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); count = CFArrayGetCount(modes); for (i = 0; i < count; i++) { - CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); - if (!modeIsGood(mode)) + CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); + if (!modeIsGood(dm)) continue; - int modeBPP; - - // Identify display mode pixel encoding + const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link); + if (_glfwCompareVideoModes(best, &mode) == 0) { - CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); - - if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) - modeBPP = 16; - else - modeBPP = 32; - - CFRelease(format); - } - - const int modeWidth = (int) CGDisplayModeGetWidth(mode); - const int modeHeight = (int) CGDisplayModeGetHeight(mode); - const int modeRate = (int) CGDisplayModeGetRefreshRate(mode); - - sizeDiff = (abs(modeBPP - bpp) << 25) | - ((modeWidth - desired->width) * (modeWidth - desired->width) + - (modeHeight - desired->height) * (modeHeight - desired->height)); - - if (desired->refreshRate) - rateDiff = abs(modeRate - desired->refreshRate); - else - rateDiff = UINT_MAX - modeRate; - - if ((sizeDiff < leastSizeDiff) || - (sizeDiff == leastSizeDiff && rateDiff < leastRateDiff)) - { - bestMode = mode; - leastSizeDiff = sizeDiff; - leastRateDiff = rateDiff; + native = dm; + break; } } - if (!bestMode) + if (native) { - CFRelease(modes); + if (monitor->ns.previousMode == NULL) + monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); + + CGDisplayFadeReservationToken token = beginFadeReservation(); + + CGDisplayCapture(monitor->ns.displayID); + CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL); + + endFadeReservation(token); + } + + CFRelease(modes); + CVDisplayLinkRelease(link); + + if (!native) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Monitor mode list changed"); return GL_FALSE; } - monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); - - CGDisplayFadeReservationToken token = beginFadeReservation(); - - CGDisplayCapture(monitor->ns.displayID); - CGDisplaySetDisplayMode(monitor->ns.displayID, bestMode, NULL); - - endFadeReservation(token); - - CFRelease(modes); return GL_TRUE; } @@ -342,9 +328,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) for (i = 0; i < count; i++) { - CGDisplayModeRef mode; - - mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); + CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); if (modeIsGood(mode)) { result[*found] = vidmodeFromCGDisplayMode(mode, link); diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 2442f303..aa9ad272 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -54,7 +54,6 @@ GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) DEVMODEW dm; best = _glfwChooseVideoMode(monitor, desired); - _glfwPlatformGetVideoMode(monitor, ¤t); if (_glfwCompareVideoModes(¤t, best) == 0) return GL_TRUE; diff --git a/src/x11_monitor.c b/src/x11_monitor.c index a9b28493..b5876a2e 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -86,7 +86,7 @@ static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi) // Set the current video mode for the specified monitor // -void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) { if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { @@ -99,10 +99,9 @@ void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) int i; best = _glfwChooseVideoMode(monitor, desired); - _glfwPlatformGetVideoMode(monitor, ¤t); if (_glfwCompareVideoModes(¤t, best) == 0) - return; + return GL_TRUE; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); @@ -136,16 +135,20 @@ void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) ci->outputs, ci->noutput); } - else - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Monitor mode list changed"); - } XRRFreeOutputInfo(oi); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); + + if (!native) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Monitor mode list changed"); + return GL_FALSE; + } } + + return GL_TRUE; } // Restore the saved (original) video mode for the specified monitor diff --git a/src/x11_platform.h b/src/x11_platform.h index f0dc6081..e4846538 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -243,7 +243,7 @@ void _glfwInitTimer(void); void _glfwInitGammaRamp(void); // Fullscreen support -void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); +GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); void _glfwRestoreVideoMode(_GLFWmonitor* monitor); // Joystick input