From eabf1215930a0d26f23c1c83cb36da40710b235f Mon Sep 17 00:00:00 2001 From: havoc Date: Tue, 28 Mar 2006 13:02:06 +0000 Subject: [PATCH] modified gamma handling, now VID_UpdateGamma is only called from VID_Finish, and VID_SetGamma/VID_GetGamma/VID_UpdateGamma take rampsize parameters VID_UpdateGamma now supports ramp sizes other than 256, and automatically allocates memory accordingly, this allows hardware gamma on X11 to work on Quadro cards (which report 1024 gamma entries according to div0), and allows any other platform to do whatever it wishes git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6200 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_screen.c | 3 --- vid.h | 13 +++++++++---- vid_agl.c | 35 ++++++++++++++++++----------------- vid_glx.c | 24 ++++++++---------------- vid_null.c | 4 ++-- vid_sdl.c | 10 ++++++---- vid_shared.c | 44 ++++++++++++++++++++++++++------------------ vid_wgl.c | 6 ++++-- 8 files changed, 73 insertions(+), 66 deletions(-) diff --git a/cl_screen.c b/cl_screen.c index e26048ef..4e944b23 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -1296,7 +1296,6 @@ void SCR_UpdateLoadingScreen (void) // don't do anything if not initialized yet if (vid_hidden) return; - VID_UpdateGamma(false); qglViewport(0, 0, vid.width, vid.height); //qglDisable(GL_SCISSOR_TEST); //qglDepthMask(1); @@ -1405,8 +1404,6 @@ void CL_UpdateScreen(void) if (r_timereport_active) R_TimeReport("other"); - VID_UpdateGamma(false); - SCR_SetUpToDrawConsole(); if (r_timereport_active) diff --git a/vid.h b/vid.h index 5aae1b4d..9d5ca137 100644 --- a/vid.h +++ b/vid.h @@ -123,12 +123,17 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate // sets hardware gamma correction, returns false if the device does not // support gamma control -int VID_SetGamma (unsigned short *ramps); +// (ONLY called by VID_UpdateGamma and VID_RestoreSystemGamma) +int VID_SetGamma(unsigned short *ramps, int rampsize); // gets hardware gamma correction, returns false if the device does not // support gamma control -int VID_GetGamma (unsigned short *ramps); - -void VID_UpdateGamma(qboolean force); +// (ONLY called by VID_UpdateGamma and VID_RestoreSystemGamma) +int VID_GetGamma(unsigned short *ramps, int rampsize); +// makes sure ramp arrays are big enough and calls VID_GetGamma/VID_SetGamma +// (ONLY to be called from VID_Finish!) +void VID_UpdateGamma(qboolean force, int rampsize); +// turns off hardware gamma ramps immediately +// (called from various shutdown/deactivation functions) void VID_RestoreSystemGamma(void); void VID_Finish (qboolean allowmousegrab); diff --git a/vid_agl.c b/vid_agl.c index 69329456..d86441fd 100644 --- a/vid_agl.c +++ b/vid_agl.c @@ -101,6 +101,7 @@ static void IN_Activate( qboolean grab ) } } +#define GAMMA_TABLE_SIZE 256 void VID_Finish (qboolean allowmousegrab) { qboolean vid_usemouse; @@ -137,10 +138,10 @@ void VID_Finish (qboolean allowmousegrab) qglFinish(); qaglSwapBuffers(context); } + VID_UpdateGamma(false, GAMMA_TABLE_SIZE); } -#define GAMMA_TABLE_SIZE 256 -int VID_SetGamma(unsigned short *ramps) +int VID_SetGamma(unsigned short *ramps, int rampsize) { CGGammaValue table_red [GAMMA_TABLE_SIZE]; CGGammaValue table_green [GAMMA_TABLE_SIZE]; @@ -148,14 +149,14 @@ int VID_SetGamma(unsigned short *ramps) unsigned int i; // Convert the unsigned short table into 3 float tables - for (i = 0; i < GAMMA_TABLE_SIZE; i++) + for (i = 0; i < rampsize; i++) table_red[i] = (float)ramps[i] / 65535.0f; - for (i = 0; i < GAMMA_TABLE_SIZE; i++) - table_green[i] = (float)ramps[i + GAMMA_TABLE_SIZE] / 65535.0f; - for (i = 0; i < GAMMA_TABLE_SIZE; i++) - table_blue[i] = (float)ramps[i + 2 * GAMMA_TABLE_SIZE] / 65535.0f; + for (i = 0; i < rampsize; i++) + table_green[i] = (float)ramps[i + rampsize] / 65535.0f; + for (i = 0; i < rampsize; i++) + table_blue[i] = (float)ramps[i + 2 * rampsize] / 65535.0f; - if (CGSetDisplayTransferByTable(CGMainDisplayID(), GAMMA_TABLE_SIZE, table_red, table_green, table_blue) != CGDisplayNoErr) + if (CGSetDisplayTransferByTable(CGMainDisplayID(), rampsize, table_red, table_green, table_blue) != CGDisplayNoErr) { Con_Print("VID_SetGamma: ERROR: CGSetDisplayTransferByTable failed!\n"); return false; @@ -164,7 +165,7 @@ int VID_SetGamma(unsigned short *ramps) return true; } -int VID_GetGamma(unsigned short *ramps) +int VID_GetGamma(unsigned short *ramps, int rampsize) { CGGammaValue table_red [GAMMA_TABLE_SIZE]; CGGammaValue table_green [GAMMA_TABLE_SIZE]; @@ -173,24 +174,24 @@ int VID_GetGamma(unsigned short *ramps) unsigned int i; // Get the gamma ramps from the system - if (CGGetDisplayTransferByTable(CGMainDisplayID(), GAMMA_TABLE_SIZE, table_red, table_green, table_blue, &actualsize) != CGDisplayNoErr) + if (CGGetDisplayTransferByTable(CGMainDisplayID(), rampsize, table_red, table_green, table_blue, &actualsize) != CGDisplayNoErr) { Con_Print("VID_GetGamma: ERROR: CGGetDisplayTransferByTable failed!\n"); return false; } - if (actualsize != GAMMA_TABLE_SIZE) + if (actualsize != rampsize) { - Con_Printf("VID_GetGamma: ERROR: invalid gamma table size (%u != %u)\n", actualsize, GAMMA_TABLE_SIZE); + Con_Printf("VID_GetGamma: ERROR: invalid gamma table size (%u != %u)\n", actualsize, rampsize); return false; } // Convert the 3 float tables into 1 unsigned short table - for (i = 0; i < GAMMA_TABLE_SIZE; i++) + for (i = 0; i < rampsize; i++) ramps[i] = table_red[i] * 65535.0f; - for (i = 0; i < GAMMA_TABLE_SIZE; i++) - ramps[i + GAMMA_TABLE_SIZE] = table_green[i] * 65535.0f; - for (i = 0; i < GAMMA_TABLE_SIZE; i++) - ramps[i + 2 * GAMMA_TABLE_SIZE] = table_blue[i] * 65535.0f; + for (i = 0; i < rampsize; i++) + ramps[i + rampsize] = table_green[i] * 65535.0f; + for (i = 0; i < rampsize; i++) + ramps[i + 2 * rampsize] = table_blue[i] * 65535.0f; return true; } diff --git a/vid_glx.c b/vid_glx.c index c5101041..eab081aa 100644 --- a/vid_glx.c +++ b/vid_glx.c @@ -561,6 +561,7 @@ void InitSig(void) void VID_Finish (qboolean allowmousegrab) { + int rampsize; qboolean vid_usemouse; vid_usevsync = vid_vsync.integer && !cls.timedemo && gl_videosyncavailable; @@ -587,28 +588,19 @@ void VID_Finish (qboolean allowmousegrab) qglFinish(); qglXSwapBuffers(vidx11_display, win); } + + if(XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &rampsize)) + VID_UpdateGamma(false, rampsize); } -int VID_SetGamma(unsigned short *ramps) +int VID_SetGamma(unsigned short *ramps, int rampsize) { - int rampsize; - // FIXME: it would be good to generate ramps of the size reported by X, - // for instance Quadro cards seem to use 1024 color ramps not 256 - if(!XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &rampsize)) - return 0; - if(rampsize != 256) - return 0; - return XF86VidModeSetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512); + return XF86VidModeSetGammaRamp(vidx11_display, vidx11_screen, rampsize, ramps, ramps + rampsize, ramps + rampsize*2); } -int VID_GetGamma(unsigned short *ramps) +int VID_GetGamma(unsigned short *ramps, int rampsize) { - int rampsize; - if(!XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &rampsize)) - return 0; - if(rampsize != 256) - return 0; - return XF86VidModeGetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512); + return XF86VidModeGetGammaRamp(vidx11_display, vidx11_screen, rampsize, ramps, ramps + rampsize, ramps + rampsize*2); } void VID_Init(void) diff --git a/vid_null.c b/vid_null.c index 85d18cda..9accd0a6 100644 --- a/vid_null.c +++ b/vid_null.c @@ -55,12 +55,12 @@ void VID_Finish (qboolean allowmousegrab) { } -int VID_SetGamma(unsigned short *ramps) +int VID_SetGamma(unsigned short *ramps, int rampsize) { return FALSE; } -int VID_GetGamma(unsigned short *ramps) +int VID_GetGamma(unsigned short *ramps, int rampsize) { return FALSE; } diff --git a/vid_sdl.c b/vid_sdl.c index c87dbe74..0df9e422 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -473,14 +473,14 @@ void VID_Shutdown (void) SDL_QuitSubSystem(SDL_INIT_VIDEO); } -int VID_SetGamma (unsigned short *ramps) +int VID_SetGamma (unsigned short *ramps, int rampsize) { - return !SDL_SetGammaRamp (ramps, ramps + 256, ramps + 512); + return !SDL_SetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2); } -int VID_GetGamma (unsigned short *ramps) +int VID_GetGamma (unsigned short *ramps, int rampsize) { - return !SDL_GetGammaRamp( ramps, ramps + 256, ramps + 512); + return !SDL_GetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2); } void VID_Finish (qboolean allowmousegrab) @@ -511,4 +511,6 @@ void VID_Finish (qboolean allowmousegrab) vid_usemouse = false; IN_Activate(vid_usemouse); + + VID_UpdateGamma(false, 256); } diff --git a/vid_shared.c b/vid_shared.c index a02639b7..0ffc3628 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -64,8 +64,9 @@ cvar_t vid_hardwaregammasupported = {CVAR_READONLY,"vid_hardwaregammasupported", // whether hardware gamma ramps are currently in effect qboolean vid_usinghwgamma = false; -unsigned short vid_gammaramps[768]; -unsigned short vid_systemgammaramps[768]; +int vid_gammarampsize = 0; +unsigned short *vid_gammaramps = NULL; +unsigned short *vid_systemgammaramps = NULL; cvar_t vid_fullscreen = {CVAR_SAVE, "vid_fullscreen", "1", "use fullscreen (1) or windowed (0)"}; cvar_t vid_width = {CVAR_SAVE, "vid_width", "640", "resolution"}; @@ -706,7 +707,7 @@ void Force_CenterView_f (void) static float cachegamma, cachebrightness, cachecontrast, cacheblack[3], cachegrey[3], cachewhite[3]; static int cachecolorenable, cachehwgamma; #define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f); -void VID_UpdateGamma(qboolean force) +void VID_UpdateGamma(qboolean force, int rampsize) { cvar_t *c; float f; @@ -742,7 +743,17 @@ void VID_UpdateGamma(qboolean force) if (!vid_usinghwgamma) { vid_usinghwgamma = true; - Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_GetGamma(vid_systemgammaramps)); + if (vid_gammarampsize != rampsize || !vid_gammaramps) + { + vid_gammarampsize = rampsize; + if (vid_gammaramps) + Z_Free(vid_gammaramps); + vid_gammaramps = Z_Malloc(6 * vid_gammarampsize * sizeof(unsigned short)); + vid_systemgammaramps = vid_gammaramps + 3 * vid_gammarampsize; + } + Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_GetGamma(vid_systemgammaramps, vid_gammarampsize)); + if (!vid_hardwaregammasupported.integer) + return; } BOUNDCVAR(v_gamma, 0.1, 5);cachegamma = v_gamma.value; @@ -763,14 +774,14 @@ void VID_UpdateGamma(qboolean force) if (cachecolorenable) { BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[0]), cachewhite[0], cacheblack[0], vid_gammaramps); - BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[1]), cachewhite[1], cacheblack[1], vid_gammaramps + 256); - BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[2]), cachewhite[2], cacheblack[2], vid_gammaramps + 512); + BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[1]), cachewhite[1], cacheblack[1], vid_gammaramps + vid_gammarampsize); + BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[2]), cachewhite[2], cacheblack[2], vid_gammaramps + vid_gammarampsize*2); } else { BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps); - BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps + 256); - BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps + 512); + BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps + vid_gammarampsize); + BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps + vid_gammarampsize*2); } // LordHavoc: this code came from Ben Winslow and Zinx Verituse, I have @@ -808,23 +819,20 @@ void VID_UpdateGamma(qboolean force) } for (x = 0, ramp = vid_gammaramps;x < 3;x++) - for (y = 0, t = n[x] - 0.75f;y < 256;y++, t += 0.75f * (2.0f / 256.0f)) + for (y = 0, t = n[x] - 0.75f;y < vid_gammarampsize;y++, t += 0.75f * (2.0f / vid_gammarampsize)) *ramp++ = cos(t*(M_PI*2.0)) * 32767.0f + 32767.0f; } - Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_gammaramps)); + Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_gammaramps, vid_gammarampsize)); // if custom gamma ramps failed (Windows stupidity), restore to system gamma if(!vid_hardwaregammasupported.integer) - VID_SetGamma(vid_systemgammaramps); - } - else - { - if (vid_usinghwgamma) { - vid_usinghwgamma = false; - Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_systemgammaramps)); + VID_RestoreSystemGamma(); + Cvar_SetValueQuick(&vid_hardwaregammasupported, false); } } + else + VID_RestoreSystemGamma(); } void VID_RestoreSystemGamma(void) @@ -832,7 +840,7 @@ void VID_RestoreSystemGamma(void) if (vid_usinghwgamma) { vid_usinghwgamma = false; - VID_SetGamma(vid_systemgammaramps); + Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_systemgammaramps, vid_gammarampsize)); } } diff --git a/vid_wgl.c b/vid_wgl.c index 1b05d59d..1e5a7382 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -289,6 +289,8 @@ void VID_Finish (qboolean allowmousegrab) qglFinish(); SwapBuffers(baseDC); } + + VID_UpdateGamma(false, 256); } //========================================================================== @@ -647,7 +649,7 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return lRet; } -int VID_SetGamma(unsigned short *ramps) +int VID_SetGamma(unsigned short *ramps, int rampsize) { HDC hdc = GetDC (NULL); int i = SetDeviceGammaRamp(hdc, ramps); @@ -655,7 +657,7 @@ int VID_SetGamma(unsigned short *ramps) return i; // return success or failure } -int VID_GetGamma(unsigned short *ramps) +int VID_GetGamma(unsigned short *ramps, int rampsize) { HDC hdc = GetDC (NULL); int i = GetDeviceGammaRamp(hdc, ramps); -- 2.39.2