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




commit 4a6a0819fb48c9a7e4433122f711419b83b91eaa
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 the gamma cruves 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.
    
    See: https://gitlab.gnome.org/GNOME/mutter/-/issues/1392

 src/backends/native/meta-kms-crtc.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
---
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 6cf7524949..a33651d4c9 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,26 @@ meta_kms_crtc_set_gamma (MetaKmsCrtc    *crtc,
                          const uint16_t *blue)
 {
   meta_kms_update_set_crtc_gamma (update, crtc, size, red, green, blue);
+
+  /* This is a hack to work around
+   * https://gitlab.freedesktop.org/drm/intel/-/issues/2362
+   */
+  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 +103,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]