xserver: Branch 'master' - 4 commits

Keith Packard keithp at kemper.freedesktop.org
Thu Jul 28 17:00:49 UTC 2016


 hw/xfree86/common/xf86Helper.c |    7 
 hw/xfree86/common/xf86cmap.c   |   60 +-------
 hw/xfree86/modes/xf86Crtc.c    |  113 ---------------
 hw/xfree86/modes/xf86RandR12.c |  302 ++++++++++++++++++++++++++++-------------
 hw/xfree86/modes/xf86RandR12.h |    5 
 present/present.c              |    7 
 6 files changed, 229 insertions(+), 265 deletions(-)

New commits:
commit 0924ac014d7caadab0b15ba69cd0a09cfe8a01da
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Jul 26 17:28:33 2016 +0900

    present: Only call restore_screen_pixmap once from set_abort_flip
    
    present_restore_screen_pixmap's work doesn't need to be done several
    times for the same pending flip.
    
    Fixes a crash if the X server quits while a flip is pending, in which
    case present_set_abort_flip may be called several times, including when
    screen->root is already cleared to NULL.
    
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/present/present.c b/present/present.c
index 5210832..5fde846 100644
--- a/present/present.c
+++ b/present/present.c
@@ -455,9 +455,10 @@ present_set_abort_flip(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
 
-    present_restore_screen_pixmap(screen);
-
-    screen_priv->flip_pending->abort_flip = TRUE;
+    if (!screen_priv->flip_pending->abort_flip) {
+        present_restore_screen_pixmap(screen);
+        screen_priv->flip_pending->abort_flip = TRUE;
+    }
 }
 
 static void
commit b4e46c0444bb09f4af59d9d13acc939a0fbbc6d6
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Sat Nov 28 16:50:47 2015 +0900

    xfree86: Hook up colormaps and RandR 1.2 gamma code v6
    
    Instead of breaking the former when the driver supports the latter,
    hook them up so that the hardware LUTs reflect the combination of the
    current colourmap and gamma states. I.e. combine the colourmap, the
    global gamma value/ramp and the RandR 1.2 per-CRTC gamma ramps into one
    combined LUT per CRTC.
    
    Fixes e.g. gamma sliders not working in games.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27222
    
    v2:
    * Initialize palette_size and palette struct members, fixes crash on
      server startup.
    v3:
    * Free randrp->palette in xf86RandR12CloseScreen, fixes memory leak.
    v4:
    * Call CMapUnwrapScreen if xf86RandR12InitGamma fails (Emil Velikov).
    * Still allow xf86HandleColormaps to be called with a NULL loadPalette
      parameter in the xf86_crtc_supports_gamma case.
    v5:
    * Clean up inner loops in xf86RandR12CrtcComputeGamma (Keith Packard)
    * Move palette update out of per-CRTC loop in xf86RandR12LoadPalette
      (Keith Packard)
    v6:
    * Handle reallocarray failure in xf86RandR12LoadPalette (Keith Packard)
    
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index bceb017..6f3a608 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -54,7 +54,6 @@
 #include "xf86Xinput.h"
 #include "xf86InPriv.h"
 #include "mivalidate.h"
-#include "xf86Crtc.h"
 
 /* For xf86GetClocks */
 #if defined(CSRG_BASED) || defined(__GNU__)
@@ -908,11 +907,7 @@ xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
         scrp->gamma.green = 1.0;
         scrp->gamma.blue = 1.0;
     }
-    /* Pretend we succeeded if we support better a gamma system.
-     * This avoids a confusing message.
-     */
-    if (xf86_crtc_supports_gamma(scrp))
-        return TRUE;
+
     xf86DrvMsg(scrp->scrnIndex, from,
                "Using gamma correction (%.1f, %.1f, %.1f)\n",
                scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index ba0b277..8588c9f 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -49,6 +49,7 @@
 #include "xf86_OSproc.h"
 #include "xf86str.h"
 #include "micmap.h"
+#include "xf86RandR12.h"
 #include "xf86Crtc.h"
 
 #ifdef XFreeXDGA
@@ -132,9 +133,6 @@ static void CMapUnwrapScreen(ScreenPtr pScreen);
 Bool
 xf86ColormapAllocatePrivates(ScrnInfoPtr pScrn)
 {
-    /* If we support a better colormap system, then pretend we succeeded. */
-    if (xf86_crtc_supports_gamma(pScrn))
-        return TRUE;
     if (!dixRegisterPrivateKey(&CMapScreenKeyRec, PRIVATE_SCREEN, 0))
         return FALSE;
 
@@ -157,11 +155,8 @@ xf86HandleColormaps(ScreenPtr pScreen,
     int *indices;
     int elements;
 
-    /* If we support a better colormap system, then pretend we succeeded. */
-    if (xf86_crtc_supports_gamma(pScrn))
-        return TRUE;
-
-    if (!maxColors || !sigRGBbits || !loadPalette)
+    if (!maxColors || !sigRGBbits ||
+        (!loadPalette && !xf86_crtc_supports_gamma(pScrn)))
         return FALSE;
 
     elements = 1 << sigRGBbits;
@@ -230,6 +225,15 @@ xf86HandleColormaps(ScreenPtr pScreen,
         return FALSE;
     }
 
+    if (xf86_crtc_supports_gamma(pScrn)) {
+        pScrn->LoadPalette = xf86RandR12LoadPalette;
+
+        if (!xf86RandR12InitGamma(pScrn, elements)) {
+            CMapUnwrapScreen(pScreen);
+            return FALSE;
+        }
+    }
+
     /* Force the initial map to be loaded */
     SetInstalledmiColormap(pScreen, NULL);
     CMapInstallColormap(pDefMap);
@@ -1005,19 +1009,6 @@ xf86ChangeGammaRamp(ScreenPtr pScreen,
     CMapScreenPtr pScreenPriv;
     CMapLinkPtr pLink;
 
-    if (xf86_crtc_supports_gamma(pScrn)) {
-        RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
-        if (crtc) {
-            if (crtc->gammaSize != size)
-                return BadValue;
-
-            RRCrtcGammaSet(crtc, red, green, blue);
-
-            return Success;
-        }
-    }
-
     if (!CMapScreenKeyRegistered)
         return BadImplementation;
 
@@ -1077,16 +1068,8 @@ xf86ChangeGammaRamp(ScreenPtr pScreen,
 int
 xf86GetGammaRampSize(ScreenPtr pScreen)
 {
-    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     CMapScreenPtr pScreenPriv;
 
-    if (xf86_crtc_supports_gamma(pScrn)) {
-        RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
-        if (crtc)
-            return crtc->gammaSize;
-    }
-
     if (!CMapScreenKeyRegistered)
         return 0;
 
@@ -1104,29 +1087,10 @@ xf86GetGammaRamp(ScreenPtr pScreen,
                  unsigned short *red,
                  unsigned short *green, unsigned short *blue)
 {
-    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     CMapScreenPtr pScreenPriv;
     LOCO *entry;
     int shift, sigbits;
 
-    if (xf86_crtc_supports_gamma(pScrn)) {
-        RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
-        if (crtc) {
-            if (crtc->gammaSize < size)
-                return BadValue;
-
-            if (!RRCrtcGammaGet(crtc))
-                return BadImplementation;
-
-            memcpy(red, crtc->gammaRed, size * sizeof(*red));
-            memcpy(green, crtc->gammaGreen, size * sizeof(*green));
-            memcpy(blue, crtc->gammaBlue, size * sizeof(*blue));
-
-            return Success;
-        }
-    }
-
     if (!CMapScreenKeyRegistered)
         return BadImplementation;
 
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index e097fa7..1e9cbd3 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -40,6 +40,7 @@
 #include <randrstr.h>
 #include <X11/extensions/render.h>
 
+#include "xf86cmap.h"
 #include "xf86Crtc.h"
 #include "xf86RandR12.h"
 
@@ -55,6 +56,13 @@ typedef struct _xf86RandR12Info {
     Rotation rotation;          /* current mode */
     Rotation supported_rotations;       /* driver supported */
 
+    /* Compatibility with colormaps and XF86VidMode's gamma */
+    int palette_red_size;
+    int palette_green_size;
+    int palette_blue_size;
+    int palette_size;
+    LOCO *palette;
+
     /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends
      * (actually, any time that we switch back into our VT).
      *
@@ -882,6 +890,9 @@ xf86RandR12Init(ScreenPtr pScreen)
 
     randrp->maxX = randrp->maxY = 0;
 
+    randrp->palette_size = 0;
+    randrp->palette = NULL;
+
     dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
 
 #if RANDR_12_INTERFACE
@@ -905,6 +916,7 @@ xf86RandR12CloseScreen(ScreenPtr pScreen)
     pScreen->ConstrainCursorHarder = randrp->orig_ConstrainCursorHarder;
 #endif
 
+    free(randrp->palette);
     free(randrp);
 }
 
@@ -1237,37 +1249,47 @@ xf86RandR12CrtcSet(ScreenPtr pScreen,
     return xf86RandR12CrtcNotify(randr_crtc);
 }
 
-static Bool
-xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
+static void
+xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
 {
+    XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
     xf86CrtcPtr crtc = randr_crtc->devPrivate;
+    int gamma_slots;
+    CARD16 value;
+    int i, j;
 
-    if (crtc->funcs->gamma_set == NULL)
-        return FALSE;
+    gamma_slots = crtc->gamma_size / randrp->palette_red_size;
+    for (i = 0; i < randrp->palette_red_size; i++) {
+        value = randr_crtc->gammaRed[randrp->palette[i].red];
 
-    if (!crtc->scrn->vtSema)
-        return TRUE;
+        for (j = 0; j < gamma_slots; j++)
+            crtc->gamma_red[i * gamma_slots + j] = value;
+    }
 
-    /* Realloc local gamma if needed. */
-    if (randr_crtc->gammaSize != crtc->gamma_size) {
-        CARD16 *tmp_ptr;
+    gamma_slots = crtc->gamma_size / randrp->palette_green_size;
+    for (i = 0; i < randrp->palette_green_size; i++) {
+        value = randr_crtc->gammaGreen[randrp->palette[i].green];
 
-        tmp_ptr = reallocarray(crtc->gamma_red,
-                               randr_crtc->gammaSize, 3 * sizeof(CARD16));
-        if (!tmp_ptr)
-            return FALSE;
-        crtc->gamma_red = tmp_ptr;
-        crtc->gamma_green = crtc->gamma_red + randr_crtc->gammaSize;
-        crtc->gamma_blue = crtc->gamma_green + randr_crtc->gammaSize;
+        for (j = 0; j < gamma_slots; j++)
+            crtc->gamma_green[i * gamma_slots + j] = value;
     }
 
-    crtc->gamma_size = randr_crtc->gammaSize;
-    memcpy(crtc->gamma_red, randr_crtc->gammaRed,
-           crtc->gamma_size * sizeof(CARD16));
-    memcpy(crtc->gamma_green, randr_crtc->gammaGreen,
-           crtc->gamma_size * sizeof(CARD16));
-    memcpy(crtc->gamma_blue, randr_crtc->gammaBlue,
-           crtc->gamma_size * sizeof(CARD16));
+    gamma_slots = crtc->gamma_size / randrp->palette_blue_size;
+    for (i = 0; i < randrp->palette_blue_size; i++) {
+        value = randr_crtc->gammaBlue[randrp->palette[i].blue];
+
+        for (j = 0; j < gamma_slots; j++)
+            crtc->gamma_blue[i * gamma_slots + j] = value;
+    }
+}
+
+static void
+xf86RandR12CrtcReloadGamma(RRCrtcPtr randr_crtc)
+{
+    xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+    if (!crtc->scrn->vtSema || !crtc->funcs->gamma_set)
+        return;
 
     /* Only set it when the crtc is actually running.
      * Otherwise it will be set when it's activated.
@@ -1275,6 +1297,21 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
     if (crtc->active)
         crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
                                crtc->gamma_blue, crtc->gamma_size);
+}
+
+static Bool
+xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
+{
+    XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+    xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+    if (crtc->funcs->gamma_set == NULL)
+        return FALSE;
+
+    if (randrp->palette_size) {
+        xf86RandR12CrtcComputeGamma(pScreen, randr_crtc);
+        xf86RandR12CrtcReloadGamma(randr_crtc);
+    }
 
     return TRUE;
 }
@@ -1358,7 +1395,7 @@ xf86RandR12OutputInitGamma(xf86OutputPtr output)
     return TRUE;
 }
 
-static Bool
+Bool
 xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize) {
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
     int o, c;
@@ -1815,57 +1852,59 @@ xf86RandR13SetPanning(ScreenPtr pScreen,
 }
 
 /*
- * Compatibility with XF86VidMode's gamma changer.  This necessarily clobbers
- * any per-crtc setup.  You asked for it...
+ * Compatibility with colormaps and XF86VidMode's gamma
  */
-
-static void
-gamma_to_ramp(float gamma, CARD16 *ramp, int size)
+void
+xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+                       LOCO *colors, VisualPtr pVisual)
 {
-    int i;
+    ScreenPtr pScreen = pScrn->pScreen;
+    XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int reds, greens, blues, index, palette_size;
+    int c, i;
 
-    for (i = 0; i < size; i++) {
-        if (gamma == 1.0)
-            ramp[i] = i | i << 8;
-        else
-            ramp[i] =
-                (CARD16) (pow((double) i / (double) (size - 1), 1. / gamma)
-                          * (double) (size - 1) * 257);
+    if (pVisual->class == TrueColor || pVisual->class == DirectColor) {
+        reds = (pVisual->redMask >> pVisual->offsetRed) + 1;
+        greens = (pVisual->greenMask >> pVisual->offsetGreen) + 1;
+        blues = (pVisual->blueMask >> pVisual->offsetBlue) + 1;
+    } else {
+        reds = greens = blues = pVisual->ColormapEntries;
     }
-}
-
-static int
-xf86RandR12ChangeGamma(ScrnInfoPtr pScrn, Gamma gamma)
-{
-    CARD16 *points, *red, *green, *blue;
-    RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-    int size;
-
-    if (!crtc)
-        return Success;
-
-    size = max(0, crtc->gammaSize);
-    if (!size)
-        return Success;
 
-    points = calloc(size, 3 * sizeof(CARD16));
-    if (!points)
-        return BadAlloc;
+    palette_size = max(reds, max(greens, blues));
 
-    red = points;
-    green = points + size;
-    blue = points + 2 * size;
-
-    gamma_to_ramp(gamma.red, red, size);
-    gamma_to_ramp(gamma.green, green, size);
-    gamma_to_ramp(gamma.blue, blue, size);
-    RRCrtcGammaSet(crtc, red, green, blue);
+    if (randrp->palette_size != palette_size) {
+        randrp->palette = reallocarray(randrp->palette, palette_size,
+                                       sizeof(colors[0]));
+        if (!randrp->palette) {
+            randrp->palette_size = 0;
+            return;
+        }
 
-    free(points);
+        randrp->palette_size = palette_size;
+    }
+    randrp->palette_red_size = reds;
+    randrp->palette_green_size = greens;
+    randrp->palette_blue_size = blues;
+
+    for (i = 0; i < numColors; i++) {
+        index = indices[i];
+
+        if (index < reds)
+            randrp->palette[index].red = colors[index].red;
+        if (index < greens)
+            randrp->palette[index].green = colors[index].green;
+        if (index < blues)
+            randrp->palette[index].blue = colors[index].blue;
+    }
 
-    pScrn->gamma = gamma;
+    for (c = 0; c < config->num_crtc; c++) {
+        RRCrtcPtr randr_crtc = config->crtc[c]->randr_crtc;
 
-    return Success;
+        xf86RandR12CrtcComputeGamma(pScreen, randr_crtc);
+        xf86RandR12CrtcReloadGamma(randr_crtc);
+    }
 }
 
 static Bool
@@ -1888,7 +1927,7 @@ xf86RandR12EnterVT(ScrnInfoPtr pScrn)
 
     /* reload gamma */
     for (i = 0; i < rp->numCrtcs; i++)
-        xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]);
+        xf86RandR12CrtcReloadGamma(rp->crtcs[i]);
 
     return RRGetInfo(pScreen, TRUE);    /* force a re-probe of outputs and notify clients about changes */
 }
@@ -2067,7 +2106,6 @@ xf86RandR12Init12(ScreenPtr pScreen)
     rp->rrProviderDestroy = xf86RandR14ProviderDestroy;
 
     pScrn->PointerMoved = xf86RandR12PointerMoved;
-    pScrn->ChangeGamma = xf86RandR12ChangeGamma;
 
     randrp->orig_EnterVT = pScrn->EnterVT;
     pScrn->EnterVT = xf86RandR12EnterVT;
diff --git a/hw/xfree86/modes/xf86RandR12.h b/hw/xfree86/modes/xf86RandR12.h
index e603799..31aaaaf 100644
--- a/hw/xfree86/modes/xf86RandR12.h
+++ b/hw/xfree86/modes/xf86RandR12.h
@@ -40,4 +40,9 @@ extern _X_EXPORT void xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn,
 extern _X_EXPORT Bool xf86RandR12PreInit(ScrnInfoPtr pScrn);
 extern _X_EXPORT void xf86RandR12TellChanged(ScreenPtr pScreen);
 
+extern void xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors,
+                                   int *indices, LOCO *colors,
+                                   VisualPtr pVisual);
+extern Bool xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize);
+
 #endif                          /* _XF86_RANDR_H_ */
commit 17213b74fd7fc4c4e2fe7a3781e7422dd482a0ab
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Jun 21 16:44:20 2016 +0900

    xfree86/modes: Remove xf86RandR12CrtcGetGamma
    
    This would normally return the same values the core RandR code passed to
    xf86RandR12CrtcSetGamma before, which is rather pointless. The only
    possible exception would be if a driver tried initializing
    crtc->gamma_red/green/blue to reflect the hardware LUT state on startup,
    but that can't work correctly if whatever set the LUT before the server
    started was running at a different depth.
    
    Even the pointless round-trip case will no longer work with the
    following change.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 5b24ebb..e097fa7 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1279,40 +1279,6 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
     return TRUE;
 }
 
-static Bool
-xf86RandR12CrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
-{
-    xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
-    if (!crtc->gamma_size)
-        return FALSE;
-
-    if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
-        return FALSE;
-
-    /* Realloc randr gamma if needed. */
-    if (randr_crtc->gammaSize != crtc->gamma_size) {
-        CARD16 *tmp_ptr;
-
-        tmp_ptr = reallocarray(randr_crtc->gammaRed,
-                               crtc->gamma_size, 3 * sizeof(CARD16));
-        if (!tmp_ptr)
-            return FALSE;
-        randr_crtc->gammaRed = tmp_ptr;
-        randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
-        randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
-    }
-    randr_crtc->gammaSize = crtc->gamma_size;
-    memcpy(randr_crtc->gammaRed, crtc->gamma_red,
-           crtc->gamma_size * sizeof(CARD16));
-    memcpy(randr_crtc->gammaGreen, crtc->gamma_green,
-           crtc->gamma_size * sizeof(CARD16));
-    memcpy(randr_crtc->gammaBlue, crtc->gamma_blue,
-           crtc->gamma_size * sizeof(CARD16));
-
-    return TRUE;
-}
-
 static void
 init_one_component(CARD16 *comp, unsigned size, unsigned shift, float gamma)
 {
@@ -2077,13 +2043,11 @@ xf86RandR12Init12(ScreenPtr pScreen)
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     rrScrPrivPtr rp = rrGetScrPriv(pScreen);
     XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-    int i;
 
     rp->rrGetInfo = xf86RandR12GetInfo12;
     rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
     rp->rrCrtcSet = xf86RandR12CrtcSet;
     rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
-    rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
     rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
     rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
 #if RANDR_13_INTERFACE
@@ -2124,9 +2088,6 @@ xf86RandR12Init12(ScreenPtr pScreen)
     if (!xf86RandR12InitGamma(pScrn, 256))
         return FALSE;
 
-    for (i = 0; i < rp->numCrtcs; i++) {
-        xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]);
-    }
     return TRUE;
 }
 
commit 62f44052573b475a7b4c24f8e2da9bd6a8f1bd70
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Jun 21 15:41:45 2016 +0900

    xfree86/modes: Move gamma initialization to xf86RandR12Init12 v2
    
    RRCrtcGammaSetSize cannot be used yet in xf86InitialConfiguration,
    because randr_crtc isn't allocated yet at that point, but a following
    change will require RRCrtcGammaSetSize to be called from
    xf86RandR12CrtcInitGamma.
    
    v2:
    * Bail from xf86RandR12CrtcInitGamma if !crtc->funcs->gamma_set (Keith
      Packard)
    
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 4a13c13..966a168 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2451,108 +2451,6 @@ xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
     return FALSE;
 }
 
-static Bool
-xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
-                        float gamma_blue)
-{
-    int i, size = 256;
-    CARD16 *red, *green, *blue;
-
-    red = xallocarray(size, 3 * sizeof(CARD16));
-    green = red + size;
-    blue = green + size;
-
-    /* Only cause warning if user wanted gamma to be set. */
-    if (!crtc->funcs->gamma_set &&
-        (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) {
-        free(red);
-        return FALSE;
-    }
-    else if (!crtc->funcs->gamma_set) {
-        free(red);
-        return TRUE;
-    }
-
-    /* At this early stage none of the randr-interface stuff is up.
-     * So take the default gamma size for lack of something better.
-     */
-    for (i = 0; i < size; i++) {
-        if (gamma_red == 1.0)
-            red[i] = i << 8;
-        else
-            red[i] = (CARD16) (pow((double) i / (double) (size - 1),
-                                   1. / (double) gamma_red) * (double) (size -
-                                                                        1) *
-                               256);
-
-        if (gamma_green == 1.0)
-            green[i] = i << 8;
-        else
-            green[i] = (CARD16) (pow((double) i / (double) (size - 1),
-                                     1. / (double) gamma_green) *
-                                 (double) (size - 1) * 256);
-
-        if (gamma_blue == 1.0)
-            blue[i] = i << 8;
-        else
-            blue[i] = (CARD16) (pow((double) i / (double) (size - 1),
-                                    1. / (double) gamma_blue) * (double) (size -
-                                                                          1) *
-                                256);
-    }
-
-    /* Default size is 256, so anything else is failure. */
-    if (size != crtc->gamma_size) {
-        free(red);
-        return FALSE;
-    }
-
-    crtc->gamma_size = size;
-    memcpy(crtc->gamma_red, red, crtc->gamma_size * sizeof(CARD16));
-    memcpy(crtc->gamma_green, green, crtc->gamma_size * sizeof(CARD16));
-    memcpy(crtc->gamma_blue, blue, crtc->gamma_size * sizeof(CARD16));
-
-    /* Do not set gamma now, delay until the crtc is activated. */
-
-    free(red);
-
-    return TRUE;
-}
-
-static Bool
-xf86OutputSetInitialGamma(xf86OutputPtr output)
-{
-    XF86ConfMonitorPtr mon = output->conf_monitor;
-    float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
-
-    if (!mon)
-        return TRUE;
-
-    if (!output->crtc)
-        return FALSE;
-
-    /* Get configured values, where they exist. */
-    if (mon->mon_gamma_red >= GAMMA_MIN && mon->mon_gamma_red <= GAMMA_MAX)
-        gamma_red = mon->mon_gamma_red;
-
-    if (mon->mon_gamma_green >= GAMMA_MIN && mon->mon_gamma_green <= GAMMA_MAX)
-        gamma_green = mon->mon_gamma_green;
-
-    if (mon->mon_gamma_blue >= GAMMA_MIN && mon->mon_gamma_blue <= GAMMA_MAX)
-        gamma_blue = mon->mon_gamma_blue;
-
-    /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */
-    if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
-        xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
-                   "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n",
-                   output->name, gamma_red, gamma_green, gamma_blue);
-        return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green,
-                                       gamma_blue);
-    }
-    else
-        return TRUE;
-}
-
 /**
  * Construct default screen configuration
  *
@@ -2672,15 +2570,8 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
 
         crtc->enabled = FALSE;
         memset(&crtc->desiredMode, '\0', sizeof(crtc->desiredMode));
-        /* Set default gamma for all crtc's. */
-        /* This is done to avoid problems later on with cloned outputs. */
-        xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0);
     }
 
-    if (xf86_crtc_supports_gamma(scrn))
-        xf86DrvMsg(scrn->scrnIndex, X_INFO,
-                   "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n");
-
     /*
      * Set initial configuration
      */
@@ -2703,10 +2594,6 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
             memcpy(crtc->panningBorder, output->initialBorder,
                    4 * sizeof(INT16));
             output->crtc = crtc;
-            if (!xf86OutputSetInitialGamma(output))
-                xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-                           "Initial gamma correction for output %s: failed.\n",
-                           output->name);
         }
         else {
             output->crtc = NULL;
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 9f93270..5b24ebb 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1313,6 +1313,116 @@ xf86RandR12CrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
     return TRUE;
 }
 
+static void
+init_one_component(CARD16 *comp, unsigned size, unsigned shift, float gamma)
+{
+    int i;
+
+    if (gamma == 1.0) {
+        for (i = 0; i < size; i++)
+            comp[i] = i << shift;
+    } else {
+        for (i = 0; i < size; i++)
+            comp[i] = (CARD16) (pow((double) i / (double) (size - 1),
+                                   1. / (double) gamma) *
+                               (double) (size - 1) * (1 << shift));
+    }
+}
+
+static Bool
+xf86RandR12CrtcInitGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
+                         float gamma_blue)
+{
+    unsigned size = crtc->randr_crtc->gammaSize, shift;
+    CARD16 *red, *green, *blue;
+
+    if (!crtc->funcs->gamma_set &&
+        (gamma_red != 1.0f || gamma_green != 1.0f || gamma_blue != 1.0f))
+        return FALSE;
+
+    red = xallocarray(size, 3 * sizeof(CARD16));
+    if (!red)
+        return FALSE;
+
+    green = red + size;
+    blue = green + size;
+
+    for (shift = 0; (size << shift) < (1 << 16); shift++);
+
+    init_one_component(red, size, shift, gamma_red);
+    init_one_component(green, size, shift, gamma_green);
+    init_one_component(blue, size, shift, gamma_blue);
+
+    RRCrtcGammaSet(crtc->randr_crtc, red, green, blue);
+    free(red);
+
+    return TRUE;
+}
+
+static Bool
+xf86RandR12OutputInitGamma(xf86OutputPtr output)
+{
+    XF86ConfMonitorPtr mon = output->conf_monitor;
+    float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
+
+    if (!mon)
+        return TRUE;
+
+    /* Get configured values, where they exist. */
+    if (mon->mon_gamma_red >= GAMMA_MIN && mon->mon_gamma_red <= GAMMA_MAX)
+        gamma_red = mon->mon_gamma_red;
+
+    if (mon->mon_gamma_green >= GAMMA_MIN && mon->mon_gamma_green <= GAMMA_MAX)
+        gamma_green = mon->mon_gamma_green;
+
+    if (mon->mon_gamma_blue >= GAMMA_MIN && mon->mon_gamma_blue <= GAMMA_MAX)
+        gamma_blue = mon->mon_gamma_blue;
+
+    /* Don't set gamma 1.0 if another cloned output on this CRTC already set a
+     * different gamma
+     */
+    if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
+        xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
+                   "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n",
+                   output->name, gamma_red, gamma_green, gamma_blue);
+        return xf86RandR12CrtcInitGamma(output->crtc, gamma_red, gamma_green,
+                                        gamma_blue);
+    }
+
+    return TRUE;
+}
+
+static Bool
+xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize) {
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int o, c;
+
+    /* Set default gamma for all CRTCs
+     * This is done to avoid problems later on with cloned outputs
+     */
+    for (c = 0; c < config->num_crtc; c++) {
+        xf86CrtcPtr crtc = config->crtc[c];
+
+        if (!RRCrtcGammaSetSize(crtc->randr_crtc, gammaSize) ||
+            !xf86RandR12CrtcInitGamma(crtc, 1.0f, 1.0f, 1.0f))
+            return FALSE;
+    }
+
+    /* Set initial gamma per monitor configuration
+     */
+    for (o = 0; o < config->num_output; o++) {
+        xf86OutputPtr output = config->output[o];
+
+        if (output->crtc &&
+            !xf86RandR12OutputInitGamma(output))
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                       "Initial gamma correction for output %s: failed.\n",
+                       output->name);
+    }
+
+    return TRUE;
+}
+
 static Bool
 xf86RandR12OutputSetProperty(ScreenPtr pScreen,
                              RROutputPtr randr_output,
@@ -1533,7 +1643,6 @@ xf86RandR12CreateObjects12(ScreenPtr pScreen)
         xf86CrtcPtr crtc = config->crtc[c];
 
         crtc->randr_crtc = RRCrtcCreate(pScreen, crtc);
-        RRCrtcGammaSetSize(crtc->randr_crtc, 256);
     }
     /*
      * Configure outputs
@@ -2011,6 +2120,10 @@ xf86RandR12Init12(ScreenPtr pScreen)
      */
     if (!xf86RandR12SetInfo12(pScreen))
         return FALSE;
+
+    if (!xf86RandR12InitGamma(pScrn, 256))
+        return FALSE;
+
     for (i = 0; i < rp->numCrtcs; i++) {
         xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]);
     }


More information about the xorg-commit mailing list