xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Apr 5 21:33:00 UTC 2021


 hw/xfree86/drivers/modesetting/drmmode_display.c |   85 ++++++++++++++---------
 1 file changed, 53 insertions(+), 32 deletions(-)

New commits:
commit b75d0cca28aaae5cd21ad76ad2822138fac2882a
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Fri Feb 19 11:47:13 2021 -0800

    modesetting: Defer crtc gamma size upgrade to drmmode_setup_colormap
    
    Rather than trying to create a gamma ramp array of the appropriate size in
    drmmode_crtc_init when the GAMMA_LUT property should be used, just flag the crtc
    as wanting to use the GAMMA_LUT property and then replace the gamma ramp later,
    right before calling xf86HandleColormaps. This avoids a problem during initial
    startup where xf86RandR12CreateObjects12 hard-codes a gamma ramp size of 256,
    causing xf86RandR12CrtcSetGamma to read past the end of the DIX layer's RandR
    gamma ramp array:
    
      PreInit
        drmmode_pre_init
          drmmode_crtc_init
            crtc->gamma_size = 1024
    
      ScreenInit
        xf86CrtcScreenInit
          xf86RandR12Init
            xf86RandR12Init12
              xf86RandR12CreateObjects12
                RRCrtcCreate
                  randr_crtc->gammaSize = 0
              xf86RandR12InitGamma(pScrn, 256)
                RRCrtcGammaSetSize
                  randr_crtc->gammaSize = 256
              xf86RandR12InitGamma
                xf86RandR12CrtcInitGamma
                  RRCrtcGammaSet
                    xf86RandR12CrtcSetGamma
                      // crtc->gamma_size is 1024 here, while randr_crtc->gammaRed
                      // is a 256-element array.
                      memcpy(crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof(crtc->gamma_red[0]));
        drmmode_setup_colormap
          xf86HandleColormaps
            xf86RandR12InitGamma
              RRCrtcGammaSetSize
                randr_crtc->gammaSize = 1024
    
    Fixes: 245b9db0 - modesetting: Use GAMMA_LUT when available
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1126
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Robert Morell <rmorell at nvidia.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 57c50a5ec..c10504c32 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -2404,38 +2404,10 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
                    "Allocated crtc nr. %d to this screen.\n", num);
 
-    /* If the GAMMA_LUT property is available, replace the server's default
-     * gamma ramps with ones of the appropriate size. */
-    if (drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id) {
-        Bool try_gamma_lut =
-            xf86ReturnOptValBool(drmmode->Options, OPTION_USE_GAMMA_LUT, TRUE);
-        uint64_t size = drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value;
-
-        if (try_gamma_lut && size != crtc->gamma_size) {
-            uint16_t *gamma = malloc(3 * size * sizeof(uint16_t));
-
-            if (gamma) {
-                free(crtc->gamma_red);
-
-                crtc->gamma_size = size;
-                crtc->gamma_red = gamma;
-                crtc->gamma_green = gamma + size;
-                crtc->gamma_blue = gamma + size * 2;
-
-                drmmode_crtc->use_gamma_lut = TRUE;
-
-                xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
-                               "Gamma ramp set to %ld entries on CRTC %d\n",
-                               size, num);
-            } else {
-                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                           "Failed to allocate memory for %ld gamma ramp "
-                           "entries on CRTC %d. Falling back to legacy "
-                           "%d-entry mode.\n",
-                           size, num, crtc->gamma_size);
-            }
-        }
-    }
+    drmmode_crtc->use_gamma_lut =
+        drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id &&
+        drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value &&
+        xf86ReturnOptValBool(drmmode->Options, OPTION_USE_GAMMA_LUT, TRUE);
 
     if (drmmode_crtc->use_gamma_lut &&
         drmmode_crtc->props[DRMMODE_CRTC_CTM].prop_id) {
@@ -3906,15 +3878,64 @@ drmmode_load_palette(ScrnInfoPtr pScrn, int numColors,
     }
 }
 
+static Bool
+drmmode_crtc_upgrade_lut(xf86CrtcPtr crtc, int num)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    uint64_t size;
+
+    if (!drmmode_crtc->use_gamma_lut)
+        return TRUE;
+
+    assert(drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id);
+
+    size = drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value;
+
+    if (size != crtc->gamma_size) {
+        ScrnInfoPtr pScrn = crtc->scrn;
+        uint16_t *gamma = malloc(3 * size * sizeof(uint16_t));
+
+        if (gamma) {
+            free(crtc->gamma_red);
+
+            crtc->gamma_size = size;
+            crtc->gamma_red = gamma;
+            crtc->gamma_green = gamma + size;
+            crtc->gamma_blue = gamma + size * 2;
+
+            xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
+                           "Gamma ramp set to %ld entries on CRTC %d\n",
+                           size, num);
+        } else {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Failed to allocate memory for %ld gamma ramp entries "
+                       "on CRTC %d.\n",
+                       size, num);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
 Bool
 drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
 {
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int i;
+
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
               "Initializing kms color map for depth %d, %d bpc.\n",
               pScrn->depth, pScrn->rgbBits);
     if (!miCreateDefColormap(pScreen))
         return FALSE;
 
+    /* If the GAMMA_LUT property is available, replace the server's default
+     * gamma ramps with ones of the appropriate size. */
+    for (i = 0; i < xf86_config->num_crtc; i++)
+        if (!drmmode_crtc_upgrade_lut(xf86_config->crtc[i], i))
+            return FALSE;
+
     /* Adapt color map size and depth to color depth of screen. */
     if (!xf86HandleColormaps(pScreen, 1 << pScrn->rgbBits, 10,
                              drmmode_load_palette, NULL,


More information about the xorg-commit mailing list