[mutter] backends/native: Store Enum and Bitmask information in MetaKmsProp



commit 1e06b346cb47c4a8ea24042ebefba56056a967cf
Author: Sebastian Wick <sebastian wick redhat com>
Date:   Wed Apr 20 21:52:10 2022 +0200

    backends/native: Store Enum and Bitmask information in MetaKmsProp
    
    Add functions for converting between the values used by DRM and the
    enums/bitmasks used by mutter.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2379>

 src/backends/native/meta-kms-connector-private.h |   9 +-
 src/backends/native/meta-kms-connector.c         |   5 +
 src/backends/native/meta-kms-impl-device.c       | 154 ++++++++++++++++++++++-
 src/backends/native/meta-kms-impl-device.h       |   4 +
 src/backends/native/meta-kms-plane-private.h     |   1 +
 src/backends/native/meta-kms-plane.c             |   1 +
 6 files changed, 167 insertions(+), 7 deletions(-)
---
diff --git a/src/backends/native/meta-kms-connector-private.h 
b/src/backends/native/meta-kms-connector-private.h
index 6ae8b18c37..3dd2b84407 100644
--- a/src/backends/native/meta-kms-connector-private.h
+++ b/src/backends/native/meta-kms-connector-private.h
@@ -48,7 +48,8 @@ typedef enum _MetaKmsConnectorDpms
   META_KMS_CONNECTOR_DPMS_STANDBY,
   META_KMS_CONNECTOR_DPMS_SUSPEND,
   META_KMS_CONNECTOR_DPMS_OFF,
-  META_KMS_CONNECTOR_DPMS_N_PROPS
+  META_KMS_CONNECTOR_DPMS_N_PROPS,
+  META_KMS_CONNECTOR_DPMS_UNKNOWN,
 } MetaKmsConnectorDpms;
 
 typedef enum _MetaKmsConnectorUnderscan
@@ -56,7 +57,8 @@ typedef enum _MetaKmsConnectorUnderscan
   META_KMS_CONNECTOR_UNDERSCAN_OFF = 0,
   META_KMS_CONNECTOR_UNDERSCAN_ON,
   META_KMS_CONNECTOR_UNDERSCAN_AUTO,
-  META_KMS_CONNECTOR_UNDERSCAN_N_PROPS
+  META_KMS_CONNECTOR_UNDERSCAN_N_PROPS,
+  META_KMS_CONNECTOR_UNDERSCAN_UNKNOWN,
 } MetaKmsConnectorUnderscan;
 
 typedef enum _MetaKmsConnectorPrivacyScreen
@@ -66,6 +68,7 @@ typedef enum _MetaKmsConnectorPrivacyScreen
   META_KMS_CONNECTOR_PRIVACY_SCREEN_ENABLED_LOCKED,
   META_KMS_CONNECTOR_PRIVACY_SCREEN_DISABLED_LOCKED,
   META_KMS_CONNECTOR_PRIVACY_SCREEN_N_PROPS,
+  META_KMS_CONNECTOR_PRIVACY_SCREEN_UNKNOWN,
 } MetaKmsConnectorPrivacyScreen;
 
 typedef enum _MetaKmsConnectorScalingMode
@@ -75,6 +78,7 @@ typedef enum _MetaKmsConnectorScalingMode
   META_KMS_CONNECTOR_SCALING_MODE_CENTER,
   META_KMS_CONNECTOR_SCALING_MODE_FULL_ASPECT,
   META_KMS_CONNECTOR_SCALING_MODE_N_PROPS,
+  META_KMS_CONNECTOR_SCALING_MODE_UNKNOWN,
 } MetaKmsConnectorScalingMode;
 
 typedef enum _MetaKmsConnectorPanelOrientation
@@ -84,6 +88,7 @@ typedef enum _MetaKmsConnectorPanelOrientation
   META_KMS_CONNECTOR_PANEL_ORIENTATION_LEFT_SIDE_UP,
   META_KMS_CONNECTOR_PANEL_ORIENTATION_RIGHT_SIDE_UP,
   META_KMS_CONNECTOR_PANEL_ORIENTATION_N_PROPS,
+  META_KMS_CONNECTOR_PANEL_ORIENTATION_UNKNOWN,
 } MetaKmsConnectorPanelOrientation;
 
 uint32_t meta_kms_connector_get_prop_id (MetaKmsConnector     *connector,
diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c
index 6804fb6d3b..b582dd4c6f 100644
--- a/src/backends/native/meta-kms-connector.c
+++ b/src/backends/native/meta-kms-connector.c
@@ -868,6 +868,7 @@ init_properties (MetaKmsConnector  *connector,
           .type = DRM_MODE_PROP_ENUM,
           .enum_values = prop_table->underscan_enum,
           .num_enum_values = META_KMS_CONNECTOR_UNDERSCAN_N_PROPS,
+          .default_value = META_KMS_CONNECTOR_UNDERSCAN_UNKNOWN,
         },
       [META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER] =
         {
@@ -885,6 +886,7 @@ init_properties (MetaKmsConnector  *connector,
           .type = DRM_MODE_PROP_ENUM,
           .enum_values = prop_table->privacy_screen_sw_enum,
           .num_enum_values = META_KMS_CONNECTOR_PRIVACY_SCREEN_N_PROPS,
+          .default_value = META_KMS_CONNECTOR_PRIVACY_SCREEN_UNKNOWN,
         },
       [META_KMS_CONNECTOR_PROP_PRIVACY_SCREEN_HW_STATE] =
         {
@@ -892,6 +894,7 @@ init_properties (MetaKmsConnector  *connector,
           .type = DRM_MODE_PROP_ENUM,
           .enum_values = prop_table->privacy_screen_hw_enum,
           .num_enum_values = META_KMS_CONNECTOR_PRIVACY_SCREEN_N_PROPS,
+          .default_value = META_KMS_CONNECTOR_PRIVACY_SCREEN_UNKNOWN,
         },
       [META_KMS_CONNECTOR_PROP_EDID] =
         {
@@ -924,6 +927,7 @@ init_properties (MetaKmsConnector  *connector,
           .type = DRM_MODE_PROP_ENUM,
           .enum_values = prop_table->scaling_mode_enum,
           .num_enum_values = META_KMS_CONNECTOR_SCALING_MODE_N_PROPS,
+          .default_value = META_KMS_CONNECTOR_SCALING_MODE_UNKNOWN,
         },
       [META_KMS_CONNECTOR_PROP_PANEL_ORIENTATION] =
         {
@@ -931,6 +935,7 @@ init_properties (MetaKmsConnector  *connector,
           .type = DRM_MODE_PROP_ENUM,
           .enum_values = prop_table->panel_orientation_enum,
           .num_enum_values = META_KMS_CONNECTOR_PANEL_ORIENTATION_N_PROPS,
+          .default_value = META_KMS_CONNECTOR_PANEL_ORIENTATION_UNKNOWN,
         },
       [META_KMS_CONNECTOR_PROP_NON_DESKTOP] =
         {
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
index ec1a0e5a45..4e0faab565 100644
--- a/src/backends/native/meta-kms-impl-device.c
+++ b/src/backends/native/meta-kms-impl-device.c
@@ -486,6 +486,122 @@ meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device,
   return plane;
 }
 
+uint64_t
+meta_kms_prop_convert_value (MetaKmsProp *prop,
+                             uint64_t     value)
+{
+  switch (prop->type)
+    {
+    case DRM_MODE_PROP_RANGE:
+    case DRM_MODE_PROP_SIGNED_RANGE:
+    case DRM_MODE_PROP_BLOB:
+    case DRM_MODE_PROP_OBJECT:
+      return value;
+    case DRM_MODE_PROP_ENUM:
+      g_assert (prop->enum_values[value].valid);
+      return prop->enum_values[value].value;
+    case DRM_MODE_PROP_BITMASK:
+      {
+        int i;
+        uint64_t result = 0;
+
+        for (i = 0; i < prop->num_enum_values; i++)
+          {
+            if (!prop->enum_values[i].valid)
+              continue;
+
+            if (value & prop->enum_values[i].bitmask)
+              {
+                result |= (1 << prop->enum_values[i].value);
+                value &= ~(prop->enum_values[i].bitmask);
+              }
+          }
+
+        g_assert (value == 0);
+        return result;
+      }
+    default:
+      g_assert_not_reached ();
+    }
+
+  return 0;
+}
+
+static void
+update_prop_value (MetaKmsProp *prop,
+                   uint64_t     drm_value)
+{
+  switch (prop->type)
+    {
+    case DRM_MODE_PROP_RANGE:
+    case DRM_MODE_PROP_SIGNED_RANGE:
+    case DRM_MODE_PROP_BLOB:
+    case DRM_MODE_PROP_OBJECT:
+      prop->value = drm_value;
+      return;
+    case DRM_MODE_PROP_ENUM:
+      {
+        int i;
+
+        for (i = 0; i < prop->num_enum_values; i++)
+          {
+            if (prop->enum_values[i].valid &&
+                prop->enum_values[i].value == drm_value)
+              {
+                prop->value = i;
+                return;
+              }
+          }
+
+        prop->value = prop->default_value;
+        return;
+      }
+    case DRM_MODE_PROP_BITMASK:
+      {
+        int i;
+        uint64_t result = 0;
+
+        for (i = 0; i < prop->num_enum_values; i++)
+          {
+            if (!prop->enum_values[i].valid)
+              continue;
+
+            if (drm_value & (1 << prop->enum_values[i].value))
+              {
+                result |= prop->enum_values[i].bitmask;
+                drm_value &= ~(1 << prop->enum_values[i].value);
+              }
+          }
+        if (drm_value  != 0)
+          result |= prop->default_value;
+
+        prop->value = result;
+        return;
+      }
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static void
+update_prop_enum_value(MetaKmsEnum        *prop_enum,
+                       drmModePropertyRes *drm_prop)
+{
+  int i;
+
+  for (i = 0; i < drm_prop->count_enums; i++)
+    {
+      if (strcmp (prop_enum->name, drm_prop->enums[i].name) == 0)
+        {
+          prop_enum->value = drm_prop->enums[i].value;
+          prop_enum->valid = TRUE;
+          return;
+        }
+    }
+
+  prop_enum->valid = FALSE;
+}
+
 static MetaKmsProp *
 find_prop (MetaKmsProp *props,
            int          n_props,
@@ -516,16 +632,35 @@ meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device,
                                       gpointer           user_data)
 {
   int fd;
-  uint32_t i;
+  uint32_t i, j;
 
   fd = meta_kms_impl_device_get_fd (impl_device);
 
+  for (i = 0; i < n_props; i++)
+    {
+      MetaKmsProp *prop = &props[i];
+
+      prop->prop_id = 0;
+      prop->value = 0;
+
+      for (j = 0; j < prop->num_enum_values; j++)
+        {
+          prop->enum_values[j].valid = FALSE;
+          prop->enum_values[j].value = 0;
+        }
+    }
+
   for (i = 0; i < n_drm_props; i++)
     {
+      uint32_t prop_id;
+      uint64_t prop_value;
       drmModePropertyRes *drm_prop;
       MetaKmsProp *prop;
 
-      drm_prop = drmModeGetProperty (fd, drm_props[i]);
+      prop_id = drm_props[i];
+      prop_value = drm_prop_values[i];
+
+      drm_prop = drmModeGetProperty (fd, prop_id);
       if (!drm_prop)
         continue;
 
@@ -540,17 +675,26 @@ meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device,
         {
           g_warning ("DRM property '%s' (%u) had unexpected flags (0x%x), "
                      "ignoring",
-                     drm_prop->name, drm_props[i], drm_prop->flags);
+                     drm_prop->name, prop_id, drm_prop->flags);
           drmModeFreeProperty (drm_prop);
           continue;
         }
 
-      prop->prop_id = drm_props[i];
+      prop->prop_id = prop_id;
+
+      if (prop->type == DRM_MODE_PROP_BITMASK ||
+          prop->type == DRM_MODE_PROP_ENUM)
+        {
+          for (j = 0; j < prop->num_enum_values; j++)
+            update_prop_enum_value (&prop->enum_values[j], drm_prop);
+        }
+
+      update_prop_value (prop, prop_value);
 
       if (prop->parse)
         {
           prop->parse (impl_device, prop,
-                       drm_prop, drm_prop_values[i],
+                       drm_prop, prop_value,
                        user_data);
         }
 
diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h
index f50b1b6376..015268f5a1 100644
--- a/src/backends/native/meta-kms-impl-device.h
+++ b/src/backends/native/meta-kms-impl-device.h
@@ -62,6 +62,7 @@ struct _MetaKmsProp
 
   unsigned int num_enum_values;
   MetaKmsEnum *enum_values;
+  uint64_t default_value;
 
   uint32_t prop_id;
   uint64_t value;
@@ -192,4 +193,7 @@ gboolean meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice  *impl_device
 
 void meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device);
 
+uint64_t meta_kms_prop_convert_value (MetaKmsProp *prop,
+                                      uint64_t     value);
+
 #endif /* META_KMS_IMPL_DEVICE_H */
diff --git a/src/backends/native/meta-kms-plane-private.h b/src/backends/native/meta-kms-plane-private.h
index 215a4754fd..7dcb7f0c04 100644
--- a/src/backends/native/meta-kms-plane-private.h
+++ b/src/backends/native/meta-kms-plane-private.h
@@ -64,6 +64,7 @@ typedef enum _MetaKmsPlaneRotation
   META_KMS_PLANE_ROTATION_ROTATE_270 = (1 << 3),
   META_KMS_PLANE_ROTATION_REFLECT_X = (1 << 4),
   META_KMS_PLANE_ROTATION_REFLECT_Y = (1 << 5),
+  META_KMS_PLANE_ROTATION_UNKNOWN = (1 << 6),
 } MetaKmsPlaneRotation;
 
 MetaKmsPlane * meta_kms_plane_new (MetaKmsPlaneType         type,
diff --git a/src/backends/native/meta-kms-plane.c b/src/backends/native/meta-kms-plane.c
index 6742ccd118..5ee163c1ad 100644
--- a/src/backends/native/meta-kms-plane.c
+++ b/src/backends/native/meta-kms-plane.c
@@ -387,6 +387,7 @@ init_properties (MetaKmsPlane            *plane,
           .type = DRM_MODE_PROP_BITMASK,
           .enum_values = prop_table->rotation_bitmask,
           .num_enum_values = META_KMS_PLANE_ROTATION_BIT_N_PROPS,
+          .default_value = META_KMS_PLANE_ROTATION_UNKNOWN,
           .parse = parse_rotations,
         },
       [META_KMS_PLANE_PROP_IN_FORMATS] =


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