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




commit 4e450f485ee6aa1196d74224e7db645269515d8f
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]