Made gamma ramp functions per-monitor.

This commit is contained in:
Camilla Berglund 2013-02-12 13:50:41 +01:00
parent 20ccf0bc60
commit 92a71e07d3
12 changed files with 139 additions and 126 deletions

View File

@ -883,27 +883,28 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
*/
GLFWAPI GLFWvidmode glfwGetVideoMode(GLFWmonitor* monitor);
/*! @brief Sets the system gamma ramp for all connected monitors to one
* generated from the specified exponent.
/*! @brief Generates a gamma ramp and sets it for the specified monitor.
* @param[in] monitor The monitor whose gamma ramp to set.
* @param[in] gamma The desired exponent.
* @ingroup gamma
*
* @remarks This is a helper function layered on top of @ref glfwSetGammaRamp.
* @remarks This is a helper function on top of @ref glfwSetGammaRamp.
*/
GLFWAPI void glfwSetGamma(float gamma);
GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
/*! @brief Retrieves the current system gamma ramp.
/*! @brief Retrieves the current gamma ramp for the specified monitor.
* @param[in] monitor The monitor to query.
* @param[out] ramp Where to store the gamma ramp.
* @ingroup gamma
*/
GLFWAPI void glfwGetGammaRamp(GLFWgammaramp* ramp);
GLFWAPI void glfwGetGammaRamp(GLFWmonitor* monitor, GLFWgammaramp* ramp);
/*! @brief Sets the system gamma ramp for all connected monitors to the one
* specified.
/*! @brief Sets the gamma ramp for the specified monitor.
* @param[in] monitor The monitor whose gamma ramp to set.
* @param[in] ramp The gamma ramp to use.
* @ingroup gamma
*/
GLFWAPI void glfwSetGammaRamp(const GLFWgammaramp* ramp);
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
/*! @brief Resets all window hints to their default values
*

View File

@ -39,19 +39,27 @@
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
// TODO: Support ramp sizes other than 256
uint32_t sampleCount;
int i;
CGGammaValue red[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue green[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE];
// For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
if (_glfw.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
if (CGDisplayGammaTableCapacity(monitor->ns.displayID) !=
GLFW_GAMMA_RAMP_SIZE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Only gamma ramps of size 256 supported");
return;
}
CGGetDisplayTransferByTable(CGMainDisplayID(), GLFW_GAMMA_RAMP_SIZE, red, green, blue,
CGGetDisplayTransferByTable(monitor->ns.displayID,
GLFW_GAMMA_RAMP_SIZE,
red, green, blue,
&sampleCount);
for (i = 0; i < GLFW_GAMMA_RAMP_SIZE; i++)
@ -62,17 +70,23 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
}
}
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
// TODO: Support ramp sizes other than 256
int i;
int size = GLFW_GAMMA_RAMP_SIZE;
CGGammaValue red[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue green[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE];
// For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
if (_glfw.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
if (CGDisplayGammaTableCapacity(monitor->ns.displayID) !=
GLFW_GAMMA_RAMP_SIZE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Only gamma ramps of size 256 supported");
return;
}
// Convert to float & take the difference of the original gamma and
// the linear function.
@ -83,6 +97,8 @@ void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
blue[i] = ramp->blue[i] / 65535.f;
}
CGSetDisplayTransferByTable(CGMainDisplayID(), GLFW_GAMMA_RAMP_SIZE, red, green, blue);
CGSetDisplayTransferByTable(monitor->ns.displayID,
GLFW_GAMMA_RAMP_SIZE,
red, green, blue);
}

View File

@ -93,10 +93,6 @@ int _glfwPlatformInit(void)
changeToResourcesDirectory();
#endif
// Save the original gamma ramp
_glfw.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID());
_glfwPlatformGetGammaRamp(&_glfw.originalRamp);
_glfwInitTimer();
_glfwInitJoysticks();
@ -123,10 +119,6 @@ void _glfwPlatformTerminate(void)
_glfw.ns.eventSource = NULL;
}
// Restore the original gamma ramp
if (_glfw.rampChanged)
_glfwPlatformSetGammaRamp(&_glfw.originalRamp);
[NSApp setDelegate:nil];
[_glfw.ns.delegate release];
_glfw.ns.delegate = nil;

View File

@ -37,7 +37,7 @@
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI void glfwSetGamma(float gamma)
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
{
int i, size = GLFW_GAMMA_RAMP_SIZE;
GLFWgammaramp ramp;
@ -75,29 +75,38 @@ GLFWAPI void glfwSetGamma(float gamma)
ramp.blue[i] = (unsigned short) value;
}
glfwSetGammaRamp(&ramp);
glfwSetGammaRamp(handle, &ramp);
}
GLFWAPI void glfwGetGammaRamp(GLFWgammaramp* ramp)
GLFWAPI void glfwGetGammaRamp(GLFWmonitor* handle, GLFWgammaramp* ramp)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
if (!_glfwInitialized)
{
_glfwInputError(GLFW_NOT_INITIALIZED, NULL);
return;
}
_glfwPlatformGetGammaRamp(ramp);
_glfwPlatformGetGammaRamp(monitor, ramp);
}
GLFWAPI void glfwSetGammaRamp(const GLFWgammaramp* ramp)
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
if (!_glfwInitialized)
{
_glfwInputError(GLFW_NOT_INITIALIZED, NULL);
return;
}
_glfwPlatformSetGammaRamp(ramp);
_glfw.rampChanged = GL_TRUE;
if (!monitor->rampChanged)
{
_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp);
monitor->rampChanged = GL_TRUE;
}
_glfwPlatformSetGammaRamp(monitor, ramp);
}

View File

@ -150,6 +150,8 @@ GLFWAPI int glfwInit(void)
GLFWAPI void glfwTerminate(void)
{
int i;
if (!_glfwInitialized)
return;
@ -157,6 +159,13 @@ GLFWAPI void glfwTerminate(void)
while (_glfw.windowListHead)
glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
for (i = 0; i < _glfw.monitorCount; i++)
{
_GLFWmonitor* monitor = _glfw.monitors[i];
if (monitor->rampChanged)
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
}
_glfwDestroyMonitors();
_glfwPlatformTerminate();

View File

@ -267,6 +267,9 @@ struct _GLFWmonitor
GLFWvidmode* modes;
int modeCount;
GLFWgammaramp originalRamp;
GLboolean rampChanged;
// This is defined in the window API's platform.h
_GLFW_PLATFORM_MONITOR_STATE;
};
@ -285,10 +288,6 @@ struct _GLFWlibrary
int monitorCount;
GLFWmonitorfun monitorCallback;
GLFWgammaramp originalRamp;
int originalRampSize;
GLboolean rampChanged;
// This is defined in the window API's platform.h
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
// This is defined in the context API's platform.h
@ -376,17 +375,19 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
*/
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
/*! @brief Returns the current system gamma ramp.
/*! @brief Retrieves the current gamma ramp for the specified monitor.
* @param[in] monitor The monitor to query.
* @param[out] ramp The current system gamma ramp.
* @ingroup platform
*/
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
/*! @brief Sets the system gamma ramp.
/*! @brief Sets the gamma ramp for the specified monitor.
* @param[in] monitor The monitor whose gamma ramp to set.
* @param[in] ramp The desired system gamma ramp.
* @ingroup platform
*/
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
/*! @brief Sets the system clipboard to the specified string.
* @param[in] window The window who will own the system clipboard contents, on

View File

@ -36,13 +36,31 @@
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
GetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
HDC dc;
DISPLAY_DEVICE display;
ZeroMemory(&display, sizeof(DISPLAY_DEVICE));
display.cb = sizeof(DISPLAY_DEVICE);
EnumDisplayDevices(monitor->win32.name, 0, &display, 0);
dc = CreateDC(L"DISPLAY", display.DeviceString, NULL, NULL);
GetDeviceGammaRamp(dc, (WORD*) ramp);
DeleteDC(dc);
}
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
HDC dc;
DISPLAY_DEVICE display;
ZeroMemory(&display, sizeof(DISPLAY_DEVICE));
display.cb = sizeof(DISPLAY_DEVICE);
EnumDisplayDevices(monitor->win32.name, 0, &display, 0);
dc = CreateDC(L"DISPLAY", display.DeviceString, NULL, NULL);
SetDeviceGammaRamp(dc, (WORD*) ramp);
DeleteDC(dc);
}

View File

@ -168,10 +168,6 @@ int _glfwPlatformInit(void)
_control87(MCW_EM, MCW_EM);
#endif
// Save the original gamma ramp
_glfw.originalRampSize = 256;
_glfwPlatformGetGammaRamp(&_glfw.originalRamp);
if (!_glfwInitContextAPI())
return GL_FALSE;
@ -184,10 +180,6 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void)
{
// Restore the original gamma ramp
if (_glfw.rampChanged)
_glfwPlatformSetGammaRamp(&_glfw.originalRamp);
if (_glfw.win32.classAtom)
{
UnregisterClass(_GLFW_WNDCLASSNAME, GetModuleHandle(NULL));

View File

@ -37,7 +37,7 @@
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Detect gamma ramp support and save original gamma ramp, if available
// Detect gamma ramp support
//
void _glfwInitGammaRamp(void)
{
@ -54,9 +54,7 @@ void _glfwInitGammaRamp(void)
XRRScreenResources* rr = XRRGetScreenResources(_glfw.x11.display,
_glfw.x11.root);
_glfw.originalRampSize = XRRGetCrtcGammaSize(_glfw.x11.display,
rr->crtcs[0]);
if (_glfw.originalRampSize == 0)
if (XRRGetCrtcGammaSize(_glfw.x11.display, rr->crtcs[0]))
{
// This is probably older Nvidia RandR with broken gamma support
// Flag it as useless and try Xf86VidMode below, if available
@ -65,28 +63,6 @@ void _glfwInitGammaRamp(void)
XRRFreeScreenResources(rr);
}
if (_glfw.x11.vidmode.available && !_glfw.originalRampSize)
{
// Get the gamma size using XF86VidMode
XF86VidModeGetGammaRampSize(_glfw.x11.display,
_glfw.x11.screen,
&_glfw.originalRampSize);
}
if (_glfw.originalRampSize)
{
// Save the original gamma ramp
_glfwPlatformGetGammaRamp(&_glfw.originalRamp);
}
}
// Restore original gamma ramp if necessary
//
void _glfwTerminateGammaRamp(void)
{
if (_glfw.originalRampSize && _glfw.rampChanged)
_glfwPlatformSetGammaRamp(&_glfw.originalRamp);
}
@ -94,83 +70,85 @@ void _glfwTerminateGammaRamp(void)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
// For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
if (_glfw.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to get gamma ramp due to size "
"incompatibility");
return;
}
// TODO: Support ramp sizes other than 256
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
XRRCrtcGamma* gamma;
size_t size = GLFW_GAMMA_RAMP_SIZE * sizeof(unsigned short);
XRRScreenResources* rr = XRRGetScreenResources(_glfw.x11.display,
_glfw.x11.root);
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) !=
GLFW_GAMMA_RAMP_SIZE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Only gamma ramps of size 256 supported");
return;
}
XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display,
rr->crtcs[0]);
// TODO: Handle case of original ramp size having a size other than 256
gamma = XRRGetCrtcGamma(_glfw.x11.display, monitor->x11.crtc);
memcpy(ramp->red, gamma->red, size);
memcpy(ramp->green, gamma->green, size);
memcpy(ramp->blue, gamma->blue, size);
XRRFreeGamma(gamma);
XRRFreeScreenResources(rr);
}
else if (_glfw.x11.vidmode.available)
{
XF86VidModeGetGammaRamp(_glfw.x11.display,
_glfw.x11.screen,
GLFW_GAMMA_RAMP_SIZE,
ramp->red,
ramp->green,
ramp->blue);
}
}
int size;
XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size);
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
{
// For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
if (_glfw.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
if (size != GLFW_GAMMA_RAMP_SIZE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to set gamma ramp due to size "
"incompatibility");
"X11: Only gamma ramps of size 256 supported");
return;
}
XF86VidModeGetGammaRamp(_glfw.x11.display,
_glfw.x11.screen,
GLFW_GAMMA_RAMP_SIZE,
ramp->red, ramp->green, ramp->blue);
}
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
int i;
size_t size = GLFW_GAMMA_RAMP_SIZE * sizeof(unsigned short);
XRRCrtcGamma* gamma;
XRRScreenResources* rr = XRRGetScreenResources(_glfw.x11.display,
_glfw.x11.root);
// Update gamma per monitor
for (i = 0; i < rr->ncrtc; i++)
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) !=
GLFW_GAMMA_RAMP_SIZE)
{
XRRCrtcGamma* gamma = XRRAllocGamma(GLFW_GAMMA_RAMP_SIZE);
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Only gamma ramps of size 256 supported");
return;
}
gamma = XRRAllocGamma(GLFW_GAMMA_RAMP_SIZE);
memcpy(gamma->red, ramp->red, size);
memcpy(gamma->green, ramp->green, size);
memcpy(gamma->blue, ramp->blue, size);
XRRSetCrtcGamma(_glfw.x11.display, rr->crtcs[i], gamma);
XRRFreeGamma(gamma);
}
XRRFreeScreenResources(rr);
XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma);
}
else if (_glfw.x11.vidmode.available)
{
int size;
XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size);
if (size != GLFW_GAMMA_RAMP_SIZE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Only gamma ramps of size 256 supported");
return;
}
XF86VidModeSetGammaRamp(_glfw.x11.display,
_glfw.x11.screen,
GLFW_GAMMA_RAMP_SIZE,

View File

@ -603,8 +603,6 @@ void _glfwPlatformTerminate(void)
_glfw.x11.cursor = (Cursor) 0;
}
_glfwTerminateGammaRamp();
_glfwTerminateJoysticks();
_glfwTerminateContextAPI();

View File

@ -210,7 +210,6 @@ void _glfwInitTimer(void);
// Gamma
void _glfwInitGammaRamp(void);
void _glfwTerminateGammaRamp(void);
// OpenGL support
int _glfwInitContextAPI(void);

View File

@ -49,7 +49,7 @@ static void set_gamma(float value)
{
gamma_value = value;
printf("Gamma: %f\n", gamma_value);
glfwSetGamma(gamma_value);
glfwSetGamma(glfwGetPrimaryMonitor(), gamma_value);
}
static void error_callback(int error, const char* description)