modified gamma handling, now VID_UpdateGamma is only called from VID_Finish, and...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 28 Mar 2006 13:02:06 +0000 (13:02 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 28 Mar 2006 13:02:06 +0000 (13:02 +0000)
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
vid.h
vid_agl.c
vid_glx.c
vid_null.c
vid_sdl.c
vid_shared.c
vid_wgl.c

index e26048e..4e944b2 100644 (file)
@@ -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 5aae1b4..9d5ca13 100644 (file)
--- 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);
index 6932945..d86441f 100644 (file)
--- 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;
 }
index c510104..eab081a 100644 (file)
--- 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)
index 85d18cd..9accd0a 100644 (file)
@@ -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;
 }
index c87dbe7..0df9e42 100644 (file)
--- 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);
 }
index a02639b..0ffc362 100644 (file)
@@ -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));
        }
 }
 
index 1b05d59..1e5a738 100644 (file)
--- 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);