[mutter/benzea/gamma-fix-master: 19/20] kms-crtc: Cache last set gamma value and prefer it over reading




commit 64ef3b4ac4730203c87cd8915a22d072c2d88d60
Author: Benjamin Berg <bberg redhat com>
Date:   Fri Aug 28 19:57:12 2020 +0200

    kms-crtc: Cache last set gamma value and prefer it over reading
    
    Since commit 2e5b767c0 (gpu/kms: Turn off CRTCs as well for DPMS) we
    turn off the CRTCs. This has the undesired side effect that (at least
    currently) updates to the gamma curve are lost. While this can be
    considered a kernel issue, it has the major side effect of breaking
    Night Light in ugly ways.
    
    To avoid loosing the gamma curve in case the CRTC is off, keep holding
    on to the information in MetaKmsCrtc. That way it is possible to fetch
    and re-set it again later.
    
    Note that this may be considered a DRM/driver bug. See
      https://gitlab.freedesktop.org/drm/intel/-/issues/2362
    
    See: https://gitlab.gnome.org/GNOME/mutter/-/issues/1392

 src/backends/native/meta-kms-crtc.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
---
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 6cf7524949..08fe0d07f5 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -35,6 +35,7 @@ struct _MetaKmsCrtc
   uint32_t id;
   int idx;
 
+  gboolean cached_gamma;
   MetaKmsCrtcState current_state;
 };
 
@@ -49,6 +50,23 @@ meta_kms_crtc_set_gamma (MetaKmsCrtc    *crtc,
                          const uint16_t *blue)
 {
   meta_kms_update_set_crtc_gamma (update, crtc, size, red, green, blue);
+
+  crtc->cached_gamma = TRUE;
+  crtc->current_state.gamma.size = size;
+  crtc->current_state.gamma.red = g_realloc_n (crtc->current_state.gamma.red,
+                                               size,
+                                               sizeof(uint16_t));
+  crtc->current_state.gamma.green = g_realloc_n (crtc->current_state.gamma.green,
+                                                 size,
+                                                 sizeof(uint16_t));
+  crtc->current_state.gamma.blue = g_realloc_n (crtc->current_state.gamma.blue,
+                                                size,
+                                                sizeof(uint16_t));
+
+  /* Source may be identical to dest. */
+  memmove (crtc->current_state.gamma.red, red, sizeof(uint16_t) * size);
+  memmove (crtc->current_state.gamma.green, green, sizeof(uint16_t) * size);
+  memmove (crtc->current_state.gamma.blue, blue, sizeof(uint16_t) * size);
 }
 
 MetaKmsDevice *
@@ -82,6 +100,11 @@ read_gamma_state (MetaKmsCrtc       *crtc,
 {
   MetaKmsCrtcState *current_state = &crtc->current_state;
 
+  /* Only read gamma if we don't have a cached value.
+   * Otherwise it might be wrong if the CRTC is turned off. */
+  if (crtc->cached_gamma)
+    return;
+
   if (current_state->gamma.size != drm_crtc->gamma_size)
     {
       current_state->gamma.size = drm_crtc->gamma_size;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]