[mutter/wip/gbsneto/kms-transactions-on-steroids: 30/30] backend/native: Port gamma management to Atomic KMS API



commit cf9136ecd678255ec096ddbc42fd0fb7f5a5e4f7
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Jun 19 20:39:29 2019 -0300

    backend/native: Port gamma management to Atomic KMS API
    
    As a side note: fun things happen when gamma is set wrong!

 src/backends/native/meta-kms-crtc.c            |  40 +++++++++
 src/backends/native/meta-kms-crtc.h            |  13 +++
 src/backends/native/meta-kms-impl-simple.c     | 110 +++++++++++++++++++++++++
 src/backends/native/meta-kms-update-private.h  |  11 +++
 src/backends/native/meta-kms-update.c          |  55 +++++++++++++
 src/backends/native/meta-kms-update.h          |   7 ++
 src/backends/native/meta-monitor-manager-kms.c | 101 +++--------------------
 7 files changed, 249 insertions(+), 88 deletions(-)
---
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 5006a1816..2ea0d51dd 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -69,6 +69,10 @@ meta_kms_crtc_read_state (MetaKmsCrtc       *crtc,
                           MetaKmsImplDevice *impl_device,
                           drmModeCrtc       *drm_crtc)
 {
+  g_clear_pointer (&crtc->current_state.gamma.red, g_free);
+  g_clear_pointer (&crtc->current_state.gamma.green, g_free);
+  g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
+
   crtc->current_state = (MetaKmsCrtcState) {
     .rect = {
       .x = drm_crtc->x,
@@ -78,7 +82,20 @@ meta_kms_crtc_read_state (MetaKmsCrtc       *crtc,
     },
     .is_drm_mode_valid = drm_crtc->mode_valid,
     .drm_mode = drm_crtc->mode,
+    .gamma = {
+      .size = drm_crtc->gamma_size,
+      .red = g_new0 (unsigned short, drm_crtc->gamma_size),
+      .green = g_new0 (unsigned short, drm_crtc->gamma_size),
+      .blue = g_new0 (unsigned short, drm_crtc->gamma_size),
+    },
   };
+
+  drmModeCrtcGetGamma (meta_kms_impl_device_get_fd (impl_device),
+                       crtc->id,
+                       drm_crtc->gamma_size,
+                       crtc->current_state.gamma.red,
+                       crtc->current_state.gamma.green,
+                       crtc->current_state.gamma.blue);
 }
 
 void
@@ -118,3 +135,26 @@ static void
 meta_kms_crtc_class_init (MetaKmsCrtcClass *klass)
 {
 }
+
+void
+meta_kms_crtc_get_gamma (MetaKmsCrtc     *crtc,
+                         gsize           *size,
+                         unsigned short **red,
+                         unsigned short **green,
+                         unsigned short **blue)
+{
+  unsigned int n_gamma_values = crtc->current_state.gamma.size;
+  unsigned int i;
+
+  *size = n_gamma_values;
+  *red = g_new0 (unsigned short, n_gamma_values);
+  *green = g_new0 (unsigned short, n_gamma_values);
+  *blue = g_new0 (unsigned short, n_gamma_values);
+
+  for (i = 0; i < n_gamma_values; i++)
+    {
+      *red[i] = crtc->current_state.gamma.red[i];
+      *green[i] = crtc->current_state.gamma.green[i];
+      *blue[i] = crtc->current_state.gamma.blue[i];
+    }
+}
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
index 9d0ceadd9..645f4f956 100644
--- a/src/backends/native/meta-kms-crtc.h
+++ b/src/backends/native/meta-kms-crtc.h
@@ -36,6 +36,13 @@ typedef struct _MetaKmsCrtcState
   uint32_t common_possible_crtcs;
   uint32_t common_possible_clones;
   uint32_t encoder_device_idxs;
+
+  struct {
+    unsigned int size;
+    unsigned short *red;
+    unsigned short *green;
+    unsigned short *blue;
+  } gamma;
 } MetaKmsCrtcState;
 
 #define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ())
@@ -51,4 +58,10 @@ uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc);
 
 int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
 
+void meta_kms_crtc_get_gamma (MetaKmsCrtc     *crtc,
+                              gsize           *size,
+                              unsigned short **red,
+                              unsigned short **green,
+                              unsigned short **blue);
+
 #endif /* META_KMS_CRTC_H */
diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c
index ddbee6b81..25643801c 100644
--- a/src/backends/native/meta-kms-impl-simple.c
+++ b/src/backends/native/meta-kms-impl-simple.c
@@ -62,6 +62,68 @@ G_DEFINE_TYPE (MetaKmsImplSimple, meta_kms_impl_simple,
 static void
 flush_postponed_page_flip_datas (MetaKmsImplSimple *impl_simple);
 
+static char *
+generate_gamma_ramp_string (size_t          size,
+                            unsigned short *red,
+                            unsigned short *green,
+                            unsigned short *blue)
+{
+  GString *string;
+  int color;
+
+  string = g_string_new ("[");
+  for (color = 0; color < 3; color++)
+    {
+      unsigned short **color_ptr;
+      char color_char;
+      size_t i;
+
+      switch (color)
+        {
+        case 0:
+          color_ptr = &red;
+          color_char = 'r';
+          break;
+        case 1:
+          color_ptr = &green;
+          color_char = 'g';
+          break;
+        case 2:
+          color_ptr = &blue;
+          color_char = 'b';
+          break;
+        }
+
+      g_string_append_printf (string, " %c: ", color_char);
+      for (i = 0; i < MIN (4, size); i++)
+        {
+          int j;
+
+          if (size > 4)
+            {
+              if (i == 2)
+                g_string_append (string, ",...");
+
+              if (i >= 2)
+                j = i + (size - 4);
+              else
+                j = i;
+            }
+          else
+            {
+              j = i;
+            }
+          g_string_append_printf (string, "%s%hu",
+                                  j == 0 ? "" : ",",
+                                  (*color_ptr)[i]);
+        }
+    }
+
+  g_string_append (string, " ]");
+
+  return g_string_free (string, FALSE);
+}
+
 MetaKmsImplSimple *
 meta_kms_impl_simple_new (MetaKms  *kms,
                           GError  **error)
@@ -103,6 +165,46 @@ process_connector_property (MetaKmsImpl               *impl,
   return TRUE;
 }
 
+static gboolean
+process_crtc_gamma (MetaKmsImpl       *impl,
+                    MetaKmsUpdate     *update,
+                    MetaKmsCrtcGamma  *crtc_gamma,
+                    GError           **error)
+{
+  MetaKmsCrtc *crtc = crtc_gamma->crtc;
+  MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
+  MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
+  g_autofree char *gamma_ramp_string = NULL;
+  uint32_t crtc_id;
+  int fd;
+  int ret;
+
+  fd = meta_kms_impl_device_get_fd (impl_device);
+  crtc_id = meta_kms_crtc_get_id (crtc);
+
+  gamma_ramp_string = generate_gamma_ramp_string (crtc_gamma->size,
+                                                  crtc_gamma->red,
+                                                  crtc_gamma->green,
+                                                  crtc_gamma->blue);
+  g_debug ("Setting CRTC (%u) gamma to %s", crtc_id, gamma_ramp_string);
+
+  ret = drmModeCrtcSetGamma (fd,
+                             crtc_id,
+                             crtc_gamma->size,
+                             crtc_gamma->red,
+                             crtc_gamma->green,
+                             crtc_gamma->blue);
+  if (ret != 0)
+    {
+      g_warning ("Failed to set CRTC (%u) Gamma: %s",
+                 meta_kms_crtc_get_id (crtc),
+                 g_strerror (-ret));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 static gboolean
 process_plane_property (MetaKmsImpl      *impl,
                         MetaKmsPlane     *plane,
@@ -700,6 +802,14 @@ meta_kms_impl_simple_process_update (MetaKmsImpl    *impl,
         goto discard_page_flips;
     }
 
+  for (l = meta_kms_update_get_crtc_gammas (update); l; l = l->next)
+    {
+      MetaKmsCrtcGamma *crtc_gamma = l->data;
+
+      if (!process_crtc_gamma (impl, update, crtc_gamma, error))
+        goto discard_page_flips;
+    }
+
   for (l = meta_kms_update_get_mode_sets (update); l; l = l->next)
     {
       MetaKmsModeSet *mode_set = l->data;
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index bf3326ac4..54c1699d7 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -67,6 +67,15 @@ typedef struct _MetaKmsPageFlip
   gpointer custom_page_flip_user_data;
 } MetaKmsPageFlip;
 
+typedef struct _MetaKmsCrtcGamma
+{
+  MetaKmsCrtc *crtc;
+  gsize size;
+  unsigned short *red;
+  unsigned short *green;
+  unsigned short *blue;
+} MetaKmsCrtcGamma;
+
 void meta_kms_update_set_connector_property (MetaKmsUpdate    *update,
                                              MetaKmsConnector *connector,
                                              uint32_t          prop_id,
@@ -84,6 +93,8 @@ GList * meta_kms_update_get_page_flips (MetaKmsUpdate *update);
 
 GList * meta_kms_update_get_connector_properties (MetaKmsUpdate *update);
 
+GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update);
+
 gboolean meta_kms_update_has_mode_set (MetaKmsUpdate *update);
 
 #endif /* META_KMS_UPDATE_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
index 439e917ba..4e12189f5 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -32,6 +32,7 @@ struct _MetaKmsUpdate
   GList *plane_assignments;
   GList *page_flips;
   GList *connector_properties;
+  GList *crtc_gammas;
 };
 
 static MetaKmsProperty *
@@ -71,6 +72,30 @@ meta_kms_mode_set_free (MetaKmsModeSet *mode_set)
   g_free (mode_set);
 }
 
+static void
+meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *crtc_gamma)
+{
+  g_free (crtc_gamma->red);
+  g_free (crtc_gamma->green);
+  g_free (crtc_gamma->blue);
+  g_free (crtc_gamma);
+}
+
+static unsigned short *
+copy_unsigned_short_array (unsigned short *values,
+                           gsize           n_values)
+{
+  unsigned short *copy;
+
+  if (!values)
+    return NULL;
+
+  copy = g_new (unsigned short, n_values);
+  memcpy (copy, values, sizeof (unsigned short) * n_values);
+
+  return copy;
+}
+
 MetaKmsPlaneAssignment *
 meta_kms_update_assign_plane (MetaKmsUpdate        *update,
                               MetaKmsCrtc          *crtc,
@@ -96,6 +121,28 @@ meta_kms_update_assign_plane (MetaKmsUpdate        *update,
   return plane_assignment;
 }
 
+void
+meta_kms_update_set_crtc_gamma (MetaKmsUpdate  *update,
+                                MetaKmsCrtc    *crtc,
+                                gsize           size,
+                                unsigned short *red,
+                                unsigned short *green,
+                                unsigned short *blue)
+{
+  MetaKmsCrtcGamma *crtc_gamma;
+
+  crtc_gamma = g_new0 (MetaKmsCrtcGamma, 1);
+  *crtc_gamma = (MetaKmsCrtcGamma) {
+    .crtc = crtc,
+    .size = size,
+    .red = copy_unsigned_short_array (red, size),
+    .green = copy_unsigned_short_array (green, size),
+    .blue = copy_unsigned_short_array (blue, size),
+  };
+
+  update->crtc_gammas = g_list_prepend (update->crtc_gammas, crtc_gamma);
+}
+
 void
 meta_kms_update_mode_set (MetaKmsUpdate   *update,
                           MetaKmsCrtc     *crtc,
@@ -210,6 +257,12 @@ meta_kms_update_get_connector_properties (MetaKmsUpdate *update)
   return update->connector_properties;
 }
 
+GList *
+meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update)
+{
+  return update->crtc_gammas;
+}
+
 gboolean
 meta_kms_update_has_mode_set (MetaKmsUpdate *update)
 {
@@ -231,6 +284,8 @@ meta_kms_update_free (MetaKmsUpdate *update)
                     (GDestroyNotify) meta_kms_mode_set_free);
   g_list_free_full (update->page_flips, g_free);
   g_list_free_full (update->connector_properties, g_free);
+  g_list_free_full (update->crtc_gammas,
+                    (GDestroyNotify) meta_kms_crtc_gamma_free);
 
   g_free (update);
 }
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
index fc7d83f33..e237ef26f 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -65,6 +65,13 @@ MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate        *upd
                                                        MetaFixed16Rectangle  src_rect,
                                                        MetaFixed16Rectangle  dst_rect);
 
+void meta_kms_update_set_crtc_gamma (MetaKmsUpdate  *update,
+                                     MetaKmsCrtc    *crtc,
+                                     gsize           size,
+                                     unsigned short *red,
+                                     unsigned short *green,
+                                     unsigned short *blue);
+
 void meta_kms_update_page_flip (MetaKmsUpdate                 *update,
                                 MetaKmsCrtc                   *crtc,
                                 const MetaKmsPageFlipFeedback *feedback,
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 7f094ab42..4b24938cf 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -367,82 +367,8 @@ meta_monitor_manager_kms_get_crtc_gamma (MetaMonitorManager  *manager,
                                          unsigned short     **green,
                                          unsigned short     **blue)
 {
-  MetaGpu *gpu = meta_crtc_get_gpu (crtc);
-  int kms_fd = meta_gpu_kms_get_fd (META_GPU_KMS (gpu));
-  drmModeCrtc *kms_crtc;
-
-  kms_crtc = drmModeGetCrtc (kms_fd, crtc->crtc_id);
-
-  *size = kms_crtc->gamma_size;
-  *red = g_new (unsigned short, *size);
-  *green = g_new (unsigned short, *size);
-  *blue = g_new (unsigned short, *size);
-
-  drmModeCrtcGetGamma (kms_fd, crtc->crtc_id, *size, *red, *green, *blue);
-
-  drmModeFreeCrtc (kms_crtc);
-}
-
-static char *
-generate_gamma_ramp_string (size_t          size,
-                            unsigned short *red,
-                            unsigned short *green,
-                            unsigned short *blue)
-{
-  GString *string;
-  int color;
-
-  string = g_string_new ("[");
-  for (color = 0; color < 3; color++)
-    {
-      unsigned short **color_ptr;
-      char color_char;
-      size_t i;
-
-      switch (color)
-        {
-        case 0:
-          color_ptr = &red;
-          color_char = 'r';
-          break;
-        case 1:
-          color_ptr = &green;
-          color_char = 'g';
-          break;
-        case 2:
-          color_ptr = &blue;
-          color_char = 'b';
-          break;
-        }
-
-      g_string_append_printf (string, " %c: ", color_char);
-      for (i = 0; i < MIN (4, size); i++)
-        {
-          int j;
-
-          if (size > 4)
-            {
-              if (i == 2)
-                g_string_append (string, ",...");
-
-              if (i >= 2)
-                j = i + (size - 4);
-              else
-                j = i;
-            }
-          else
-            {
-              j = i;
-            }
-          g_string_append_printf (string, "%s%hu",
-                                  j == 0 ? "" : ",",
-                                  (*color_ptr)[i]);
-        }
-    }
-
-  g_string_append (string, " ]");
-
-  return g_string_free (string, FALSE);
+  meta_kms_crtc_get_gamma (meta_crtc_kms_get_kms_crtc (crtc),
+                           size, red, green, blue);
 }
 
 static void
@@ -453,20 +379,19 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
                                          unsigned short     *green,
                                          unsigned short     *blue)
 {
-  MetaGpu *gpu = meta_crtc_get_gpu (crtc);
-  int kms_fd = meta_gpu_kms_get_fd (META_GPU_KMS (gpu));
-  g_autofree char *gamma_ramp_string = NULL;
-  int ret;
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+  MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
+  MetaKms *kms = meta_backend_native_get_kms (backend_native);
+  MetaKmsUpdate *kms_update;
+  g_autoptr (GError) error = NULL;
 
-  gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
-  g_debug ("Setting CRTC (%ld) gamma to %s", crtc->crtc_id, gamma_ramp_string);
+  kms_update = meta_kms_ensure_pending_update (kms);
+  meta_kms_update_set_crtc_gamma (kms_update,
+                                  meta_crtc_kms_get_kms_crtc (crtc),
+                                  size, red, green, blue);
 
-  ret = drmModeCrtcSetGamma (kms_fd, crtc->crtc_id, size, red, green, blue);
-  if (ret != 0)
-    {
-      g_warning ("Failed to set CRTC (%ld) Gamma: %s",
-                 crtc->crtc_id, g_strerror (-ret));
-    }
+  if (!meta_kms_post_pending_update_sync (kms, &error))
+    g_warning ("Failed to set CRTC gamma: %s", error->message);
 }
 
 static void


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