Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/winex11.drv/x11drv.h | 8 +++++--- dlls/winex11.drv/xvidmode.c | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 6781d6073a7d..85a05a904aae 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -114,11 +114,13 @@ typedef struct int exposures; /* count of graphics exposures operations */ } X11DRV_PDEVICE;
+#define GAMMA_RAMP_SIZE 256 + struct x11drv_gamma_ramp { - WORD red[256]; - WORD green[256]; - WORD blue[256]; + WORD red[GAMMA_RAMP_SIZE]; + WORD green[GAMMA_RAMP_SIZE]; + WORD blue[GAMMA_RAMP_SIZE]; };
static inline X11DRV_PDEVICE *get_x11drv_dev( PHYSDEV dev ) diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index 0020b08e70b3..63282e727bc9 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -202,7 +202,7 @@ void X11DRV_XF86VM_Init(void) pXF86VidModeGetGammaRampSize(gdi_display, DefaultScreen(gdi_display), &xf86vm_gammaramp_size); if (X11DRV_check_error()) xf86vm_gammaramp_size = 0; - if (xf86vm_gammaramp_size == 256) + if (xf86vm_gammaramp_size == GAMMA_RAMP_SIZE) xf86vm_use_gammaramp = TRUE; } #endif /* X_XF86VidModeSetGammaRamp */ @@ -250,16 +250,16 @@ sym_not_found:
#ifdef X_XF86VidModeSetGamma
-static void GenerateRampFromGamma(WORD ramp[256], float gamma) +static void GenerateRampFromGamma(WORD ramp[GAMMA_RAMP_SIZE], float gamma) { float r_gamma = 1/gamma; unsigned i; TRACE("gamma is %f\n", r_gamma); - for (i=0; i<256; i++) + for (i=0; i<GAMMA_RAMP_SIZE; i++) ramp[i] = pow(i/255.0, r_gamma) * 65535.0; }
-static BOOL ComputeGammaFromRamp(WORD ramp[256], float *gamma) +static BOOL ComputeGammaFromRamp(WORD ramp[GAMMA_RAMP_SIZE], float *gamma) { float r_x, r_y, r_lx, r_ly, r_d, r_v, r_e, g_avg, g_min, g_max; unsigned i, f, l, g_n, c; @@ -342,7 +342,7 @@ static BOOL X11DRV_XF86VM_GetGammaRamp(struct x11drv_gamma_ramp *ramp) if (xf86vm_major < 2) return FALSE; /* no gamma control */ #ifdef X_XF86VidModeSetGammaRamp if (xf86vm_use_gammaramp) - return pXF86VidModeGetGammaRamp(gdi_display, DefaultScreen(gdi_display), 256, + return pXF86VidModeGetGammaRamp(gdi_display, DefaultScreen(gdi_display), GAMMA_RAMP_SIZE, ramp->red, ramp->green, ramp->blue); #endif if (pXF86VidModeGetGamma(gdi_display, DefaultScreen(gdi_display), &gamma)) @@ -367,7 +367,7 @@ static BOOL X11DRV_XF86VM_SetGammaRamp(struct x11drv_gamma_ramp *ramp) !ComputeGammaFromRamp(ramp->blue, &gamma.blue)) return FALSE; #ifdef X_XF86VidModeSetGammaRamp if (xf86vm_use_gammaramp) - return pXF86VidModeSetGammaRamp(gdi_display, DefaultScreen(gdi_display), 256, + return pXF86VidModeSetGammaRamp(gdi_display, DefaultScreen(gdi_display), GAMMA_RAMP_SIZE, ramp->red, ramp->green, ramp->blue); #endif return pXF86VidModeSetGamma(gdi_display, DefaultScreen(gdi_display), &gamma);
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/winex11.drv/xvidmode.c | 98 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index 63282e727bc9..f055c3a53d05 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -37,6 +37,7 @@ #include "windef.h" #include "wingdi.h" #include "wine/debug.h" +#include "wine/heap.h" #include "wine/library.h"
WINE_DEFAULT_DEBUG_CHANNEL(xvidmode); @@ -202,7 +203,8 @@ void X11DRV_XF86VM_Init(void) pXF86VidModeGetGammaRampSize(gdi_display, DefaultScreen(gdi_display), &xf86vm_gammaramp_size); if (X11DRV_check_error()) xf86vm_gammaramp_size = 0; - if (xf86vm_gammaramp_size == GAMMA_RAMP_SIZE) + TRACE("Gamma ramp size %d.\n", xf86vm_gammaramp_size); + if (xf86vm_gammaramp_size >= GAMMA_RAMP_SIZE) xf86vm_use_gammaramp = TRUE; } #endif /* X_XF86VidModeSetGammaRamp */ @@ -334,6 +336,94 @@ static BOOL ComputeGammaFromRamp(WORD ramp[GAMMA_RAMP_SIZE], float *gamma) /* Hmm... should gamma control be available in desktop mode or not? * I'll assume that it should */
+#ifdef X_XF86VidModeSetGammaRamp +static void interpolate_gamma_ramp(WORD *dst_r, WORD *dst_g, WORD *dst_b, unsigned int dst_size, + const WORD *src_r, const WORD *src_g, const WORD *src_b, unsigned int src_size) +{ + double position, distance; + unsigned int dst_i, src_i; + + for (dst_i = 0; dst_i < dst_size; ++dst_i) + { + position = dst_i * (src_size - 1) / (double)(dst_size - 1); + src_i = position; + + if (src_i + 1 < src_size) + { + distance = position - src_i; + + dst_r[dst_i] = (1.0 - distance) * src_r[src_i] + distance * src_r[src_i + 1] + 0.5; + dst_g[dst_i] = (1.0 - distance) * src_g[src_i] + distance * src_g[src_i + 1] + 0.5; + dst_b[dst_i] = (1.0 - distance) * src_b[src_i] + distance * src_b[src_i + 1] + 0.5; + } + else + { + dst_r[dst_i] = src_r[src_i]; + dst_g[dst_i] = src_g[src_i]; + dst_b[dst_i] = src_b[src_i]; + } + } +} + +static BOOL xf86vm_get_gamma_ramp(struct x11drv_gamma_ramp *ramp) +{ + WORD *red, *green, *blue; + BOOL ret = FALSE; + + if (xf86vm_gammaramp_size == GAMMA_RAMP_SIZE) + { + red = ramp->red; + green = ramp->green; + blue = ramp->blue; + } + else + { + if (!(red = heap_calloc(3 * xf86vm_gammaramp_size, sizeof(*red)))) + return FALSE; + green = red + xf86vm_gammaramp_size; + blue = green + xf86vm_gammaramp_size; + } + + ret = pXF86VidModeGetGammaRamp(gdi_display, DefaultScreen(gdi_display), + xf86vm_gammaramp_size, red, green, blue); + if (ret && red != ramp->red) + interpolate_gamma_ramp(ramp->red, ramp->green, ramp->blue, GAMMA_RAMP_SIZE, + red, green, blue, xf86vm_gammaramp_size); + if (red != ramp->red) + heap_free(red); + return ret; +} + +static BOOL xf86vm_set_gamma_ramp(struct x11drv_gamma_ramp *ramp) +{ + WORD *red, *green, *blue; + BOOL ret = FALSE; + + if (xf86vm_gammaramp_size == GAMMA_RAMP_SIZE) + { + red = ramp->red; + green = ramp->green; + blue = ramp->blue; + } + else + { + if (!(red = heap_calloc(3 * xf86vm_gammaramp_size, sizeof(*red)))) + return FALSE; + green = red + xf86vm_gammaramp_size; + blue = green + xf86vm_gammaramp_size; + + interpolate_gamma_ramp(red, green, blue, xf86vm_gammaramp_size, + ramp->red, ramp->green, ramp->blue, GAMMA_RAMP_SIZE); + } + + ret = pXF86VidModeSetGammaRamp(gdi_display, DefaultScreen(gdi_display), + xf86vm_gammaramp_size, red, green, blue); + if (red != ramp->red) + heap_free(red); + return ret; +} +#endif + static BOOL X11DRV_XF86VM_GetGammaRamp(struct x11drv_gamma_ramp *ramp) { #ifdef X_XF86VidModeSetGamma @@ -342,8 +432,7 @@ static BOOL X11DRV_XF86VM_GetGammaRamp(struct x11drv_gamma_ramp *ramp) if (xf86vm_major < 2) return FALSE; /* no gamma control */ #ifdef X_XF86VidModeSetGammaRamp if (xf86vm_use_gammaramp) - return pXF86VidModeGetGammaRamp(gdi_display, DefaultScreen(gdi_display), GAMMA_RAMP_SIZE, - ramp->red, ramp->green, ramp->blue); + return xf86vm_get_gamma_ramp(ramp); #endif if (pXF86VidModeGetGamma(gdi_display, DefaultScreen(gdi_display), &gamma)) { @@ -367,8 +456,7 @@ static BOOL X11DRV_XF86VM_SetGammaRamp(struct x11drv_gamma_ramp *ramp) !ComputeGammaFromRamp(ramp->blue, &gamma.blue)) return FALSE; #ifdef X_XF86VidModeSetGammaRamp if (xf86vm_use_gammaramp) - return pXF86VidModeSetGammaRamp(gdi_display, DefaultScreen(gdi_display), GAMMA_RAMP_SIZE, - ramp->red, ramp->green, ramp->blue); + return xf86vm_set_gamma_ramp(ramp); #endif return pXF86VidModeSetGamma(gdi_display, DefaultScreen(gdi_display), &gamma); #else