Video mode detection cleanup.

This commit is contained in:
Camilla Berglund 2014-03-10 12:34:15 +01:00
parent 41fd1655bd
commit 87dd7b89f5
4 changed files with 49 additions and 63 deletions

View File

@ -163,74 +163,60 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
// //
GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{ {
CGDisplayModeRef bestMode = NULL;
CFArrayRef modes; CFArrayRef modes;
CFIndex count, i; CFIndex count, i;
unsigned int sizeDiff, leastSizeDiff = UINT_MAX; CVDisplayLinkRef link;
unsigned int rateDiff, leastRateDiff = UINT_MAX; CGDisplayModeRef native = NULL;
const int bpp = desired->redBits - desired->greenBits - desired->blueBits; GLFWvidmode current;
const GLFWvidmode* best;
best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0)
return GL_TRUE;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
count = CFArrayGetCount(modes); count = CFArrayGetCount(modes);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (!modeIsGood(mode)) if (!modeIsGood(dm))
continue; continue;
int modeBPP; const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
if (_glfwCompareVideoModes(best, &mode) == 0)
// Identify display mode pixel encoding
{ {
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); native = dm;
break;
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) }
modeBPP = 16;
else
modeBPP = 32;
CFRelease(format);
} }
const int modeWidth = (int) CGDisplayModeGetWidth(mode); if (native)
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; if (monitor->ns.previousMode == NULL)
leastSizeDiff = sizeDiff;
leastRateDiff = rateDiff;
}
}
if (!bestMode)
{
CFRelease(modes);
return GL_FALSE;
}
monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID); monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
CGDisplayFadeReservationToken token = beginFadeReservation(); CGDisplayFadeReservationToken token = beginFadeReservation();
CGDisplayCapture(monitor->ns.displayID); CGDisplayCapture(monitor->ns.displayID);
CGDisplaySetDisplayMode(monitor->ns.displayID, bestMode, NULL); CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL);
endFadeReservation(token); endFadeReservation(token);
}
CFRelease(modes); CFRelease(modes);
CVDisplayLinkRelease(link);
if (!native)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Monitor mode list changed");
return GL_FALSE;
}
return GL_TRUE; return GL_TRUE;
} }
@ -342,9 +328,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
CGDisplayModeRef mode; CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (modeIsGood(mode)) if (modeIsGood(mode))
{ {
result[*found] = vidmodeFromCGDisplayMode(mode, link); result[*found] = vidmodeFromCGDisplayMode(mode, link);

View File

@ -54,7 +54,6 @@ GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
DEVMODEW dm; DEVMODEW dm;
best = _glfwChooseVideoMode(monitor, desired); best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current); _glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0) if (_glfwCompareVideoModes(&current, best) == 0)
return GL_TRUE; return GL_TRUE;

View File

@ -86,7 +86,7 @@ static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi)
// Set the current video mode for the specified monitor // 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) if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{ {
@ -99,10 +99,9 @@ void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
int i; int i;
best = _glfwChooseVideoMode(monitor, desired); best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current); _glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0) if (_glfwCompareVideoModes(&current, best) == 0)
return; return GL_TRUE;
sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
@ -136,16 +135,20 @@ void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
ci->outputs, ci->outputs,
ci->noutput); ci->noutput);
} }
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Monitor mode list changed");
}
XRRFreeOutputInfo(oi); XRRFreeOutputInfo(oi);
XRRFreeCrtcInfo(ci); XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr); 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 // Restore the saved (original) video mode for the specified monitor

View File

@ -243,7 +243,7 @@ void _glfwInitTimer(void);
void _glfwInitGammaRamp(void); void _glfwInitGammaRamp(void);
// Fullscreen support // Fullscreen support
void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoMode(_GLFWmonitor* monitor); void _glfwRestoreVideoMode(_GLFWmonitor* monitor);
// Joystick input // Joystick input