[mutter] kms/crtc: Keep track of ACTIVE property value



commit f07d6d1f43a040b611fffe3acec308c5402ada65
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Sep 23 17:07:37 2020 +0200

    kms/crtc: Keep track of ACTIVE property value
    
    When atomic modesetting isn't enabled, this property may not exist, so
    emulate by assuming ACTIVE is set to true if a mode is set.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>

 src/backends/native/meta-kms-crtc-private.h |   7 +-
 src/backends/native/meta-kms-crtc.c         | 108 ++++++++++++++++++++++++----
 src/backends/native/meta-kms-crtc.h         |   4 ++
 src/backends/native/meta-kms-impl-device.c  |  22 +++++-
 4 files changed, 122 insertions(+), 19 deletions(-)
---
diff --git a/src/backends/native/meta-kms-crtc-private.h b/src/backends/native/meta-kms-crtc-private.h
index 9e2937a3b5..60c5fd3095 100644
--- a/src/backends/native/meta-kms-crtc-private.h
+++ b/src/backends/native/meta-kms-crtc-private.h
@@ -32,9 +32,10 @@ typedef enum _MetaKmsCrtcProp
   META_KMS_CRTC_N_PROPS
 } MetaKmsCrtcProp;
 
-MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
-                                 drmModeCrtc       *drm_crtc,
-                                 int                idx);
+MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice  *impl_device,
+                                 drmModeCrtc        *drm_crtc,
+                                 int                 idx,
+                                 GError            **error);
 
 void meta_kms_crtc_update_state (MetaKmsCrtc *crtc);
 
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 38fb06fab7..4e4bd4319f 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -86,6 +86,12 @@ meta_kms_crtc_get_prop_name (MetaKmsCrtc     *crtc,
   return crtc->prop_table.props[prop].name;
 }
 
+gboolean
+meta_kms_crtc_is_active (MetaKmsCrtc *crtc)
+{
+  return crtc->current_state.is_active;
+}
+
 static void
 read_gamma_state (MetaKmsCrtc       *crtc,
                   MetaKmsImplDevice *impl_device,
@@ -116,11 +122,33 @@ read_gamma_state (MetaKmsCrtc       *crtc,
                        current_state->gamma.blue);
 }
 
+static int
+find_prop_idx (MetaKmsProp *prop,
+               uint32_t    *drm_props,
+               int          n_drm_props)
+{
+  int i;
+
+  g_return_val_if_fail (prop->prop_id > 0, -1);
+
+  for (i = 0; i < n_drm_props; i++)
+    {
+      if (drm_props[i] == prop->prop_id)
+        return i;
+    }
+
+  return -1;
+}
+
 static void
-meta_kms_crtc_read_state (MetaKmsCrtc       *crtc,
-                          MetaKmsImplDevice *impl_device,
-                          drmModeCrtc       *drm_crtc)
+meta_kms_crtc_read_state (MetaKmsCrtc             *crtc,
+                          MetaKmsImplDevice       *impl_device,
+                          drmModeCrtc             *drm_crtc,
+                          drmModeObjectProperties *drm_props)
 {
+  MetaKmsProp *active_prop;
+  int active_idx;
+
   crtc->current_state.rect = (MetaRectangle) {
     .x = drm_crtc->x,
     .y = drm_crtc->y,
@@ -131,6 +159,19 @@ meta_kms_crtc_read_state (MetaKmsCrtc       *crtc,
   crtc->current_state.is_drm_mode_valid = drm_crtc->mode_valid;
   crtc->current_state.drm_mode = drm_crtc->mode;
 
+  active_prop = &crtc->prop_table.props[META_KMS_CRTC_PROP_ACTIVE];
+  if (active_prop->prop_id)
+    {
+      active_idx = find_prop_idx (active_prop,
+                                  drm_props->props,
+                                  drm_props->count_props);
+      crtc->current_state.is_active = !!drm_props->prop_values[active_idx];
+    }
+  else
+    {
+      crtc->current_state.is_active = drm_crtc->mode_valid;
+    }
+
   read_gamma_state (crtc, impl_device, drm_crtc);
 }
 
@@ -138,20 +179,29 @@ void
 meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
 {
   MetaKmsImplDevice *impl_device;
+  int fd;
   drmModeCrtc *drm_crtc;
+  drmModeObjectProperties *drm_props;
 
   impl_device = meta_kms_device_get_impl_device (crtc->device);
-  drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device),
-                             crtc->id);
-  if (!drm_crtc)
+  fd = meta_kms_impl_device_get_fd (impl_device);
+
+  drm_crtc = drmModeGetCrtc (fd, crtc->id);
+  drm_props = drmModeObjectGetProperties (fd, crtc->id, DRM_MODE_OBJECT_CRTC);
+
+  if (!drm_crtc || !drm_props)
     {
+      crtc->current_state.is_active = FALSE;
       crtc->current_state.rect = (MetaRectangle) { };
       crtc->current_state.is_drm_mode_valid = FALSE;
-      return;
+      goto out;
     }
 
-  meta_kms_crtc_read_state (crtc, impl_device, drm_crtc);
-  drmModeFreeCrtc (drm_crtc);
+  meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props);
+
+out:
+  g_clear_pointer (&drm_props, drmModeFreeObjectProperties);
+  g_clear_pointer (&drm_crtc, drmModeFreeCrtc);
 }
 
 static void
@@ -188,6 +238,7 @@ meta_kms_crtc_predict_state (MetaKmsCrtc   *crtc,
             meta_kms_update_get_primary_plane_assignment (update, crtc);
           drm_mode = meta_kms_mode_get_drm_mode (mode_set->mode);
 
+          crtc->current_state.is_active = TRUE;
           crtc->current_state.rect =
             meta_fixed_16_rectangle_to_rectangle (plane_assignment->src_rect);
           crtc->current_state.is_drm_mode_valid = TRUE;
@@ -195,6 +246,7 @@ meta_kms_crtc_predict_state (MetaKmsCrtc   *crtc,
         }
       else
         {
+          crtc->current_state.is_active = FALSE;
           crtc->current_state.rect = (MetaRectangle) { 0 };
           crtc->current_state.is_drm_mode_valid = FALSE;
           crtc->current_state.drm_mode = (drmModeModeInfo) { 0 };
@@ -224,6 +276,18 @@ meta_kms_crtc_predict_state (MetaKmsCrtc   *crtc,
     }
 }
 
+static void
+parse_active (MetaKmsImplDevice  *impl_device,
+              MetaKmsProp        *prop,
+              drmModePropertyPtr  drm_prop,
+              uint64_t            drm_prop_value,
+              gpointer            user_data)
+{
+  MetaKmsCrtc *crtc = user_data;
+
+  crtc->current_state.is_active = !!drm_prop_value;
+}
+
 static void
 init_proporties (MetaKmsCrtc       *crtc,
                  MetaKmsImplDevice *impl_device,
@@ -244,6 +308,7 @@ init_proporties (MetaKmsCrtc       *crtc,
         {
           .name = "ACTIVE",
           .type = DRM_MODE_PROP_RANGE,
+          .parse = parse_active,
         },
       [META_KMS_CRTC_PROP_GAMMA_LUT] =
         {
@@ -264,18 +329,31 @@ init_proporties (MetaKmsCrtc       *crtc,
                                         drm_props->count_props,
                                         crtc->prop_table.props,
                                         META_KMS_CRTC_N_PROPS,
-                                        NULL);
+                                        crtc);
 
   drmModeFreeObjectProperties (drm_props);
 }
 
 MetaKmsCrtc *
-meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
-                   drmModeCrtc       *drm_crtc,
-                   int                idx)
+meta_kms_crtc_new (MetaKmsImplDevice  *impl_device,
+                   drmModeCrtc        *drm_crtc,
+                   int                 idx,
+                   GError            **error)
 {
+  int fd;
+  drmModeObjectProperties *drm_props;
   MetaKmsCrtc *crtc;
 
+  fd = meta_kms_impl_device_get_fd (impl_device);
+  drm_props = drmModeObjectGetProperties (fd, drm_crtc->crtc_id,
+                                          DRM_MODE_OBJECT_CRTC);
+  if (!drm_props)
+    {
+      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+                   "drmModeObjectGetProperties: %s", g_strerror (errno));
+      return NULL;
+    }
+
   crtc = g_object_new (META_TYPE_KMS_CRTC, NULL);
   crtc->device = meta_kms_impl_device_get_device (impl_device);
   crtc->id = drm_crtc->crtc_id;
@@ -283,7 +361,9 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
 
   init_proporties (crtc, impl_device, drm_crtc);
 
-  meta_kms_crtc_read_state (crtc, impl_device, drm_crtc);
+  meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props);
+
+  drmModeFreeObjectProperties (drm_props);
 
   return crtc;
 }
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
index 824b5eec4b..1d9b791563 100644
--- a/src/backends/native/meta-kms-crtc.h
+++ b/src/backends/native/meta-kms-crtc.h
@@ -29,6 +29,8 @@
 
 typedef struct _MetaKmsCrtcState
 {
+  gboolean is_active;
+
   MetaRectangle rect;
   gboolean is_drm_mode_valid;
   drmModeModeInfo drm_mode;
@@ -55,4 +57,6 @@ uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc);
 
 int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
 
+gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
+
 #endif /* META_KMS_CRTC_H */
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
index 321fc0167a..1385e06762 100644
--- a/src/backends/native/meta-kms-impl-device.c
+++ b/src/backends/native/meta-kms-impl-device.c
@@ -304,13 +304,31 @@ init_crtcs (MetaKmsImplDevice *impl_device,
 
   for (idx = 0; idx < drm_resources->count_crtcs; idx++)
     {
+      uint32_t crtc_id;
       drmModeCrtc *drm_crtc;
       MetaKmsCrtc *crtc;
+      g_autoptr (GError) error = NULL;
+
+      crtc_id = drm_resources->crtcs[idx];
+      drm_crtc = drmModeGetCrtc (priv->fd, crtc_id);
+      if (!drm_crtc)
+        {
+          g_warning ("Failed to get CRTC %u info on '%s': %s",
+                     crtc_id, priv->path, error->message);
+          continue;
+        }
+
+      crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx, &error);
 
-      drm_crtc = drmModeGetCrtc (priv->fd, drm_resources->crtcs[idx]);
-      crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx);
       drmModeFreeCrtc (drm_crtc);
 
+      if (!crtc)
+        {
+          g_warning ("Failed to create CRTC for %u on '%s': %s",
+                     crtc_id, priv->path, error->message);
+          continue;
+        }
+
       priv->crtcs = g_list_prepend (priv->crtcs, crtc);
     }
   priv->crtcs = g_list_reverse (priv->crtcs);


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