[mutter] crtc/kms: Parse and store IN_FORMATS in full



commit 30550ef6887fe6432b8533c867489386c36c7d9f
Author: Pekka Paalanen <pekka paalanen collabora com>
Date:   Fri Nov 16 17:06:36 2018 +0200

    crtc/kms: Parse and store IN_FORMATS in full
    
    Rather than picking just one format, parse and store all the formats and
    their modifiers.
    
    This gives us a list of supported formats (and modifiers) on a CRTC
    primary plane. Later I will be using this list to choose a framebuffer
    format instead of hardcoding it.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/341

 src/backends/native/meta-crtc-kms.c | 88 +++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 38 deletions(-)
---
diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c
index b78e09d43..ba038cd02 100644
--- a/src/backends/native/meta-crtc-kms.c
+++ b/src/backends/native/meta-crtc-kms.c
@@ -2,6 +2,7 @@
 
 /*
  * Copyright (C) 2013-2017 Red Hat
+ * Copyright (C) 2018 DisplayLink (UK) Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -44,7 +45,12 @@ typedef struct _MetaCrtcKms
   uint32_t rotation_map[ALL_TRANSFORMS];
   uint32_t all_hw_transforms;
 
-  GArray *modifiers_xrgb8888;
+  /*
+   * primary plane's supported formats and maybe modifiers
+   * key: GUINT_TO_POINTER (format)
+   * value: owned GArray* (uint64_t modifier), or NULL
+   */
+  GHashTable *formats_modifiers;
 } MetaCrtcKms;
 
 gboolean
@@ -180,10 +186,8 @@ meta_crtc_kms_get_modifiers (MetaCrtc *crtc,
 {
   MetaCrtcKms *crtc_kms = crtc->driver_private;
 
-  if (format != DRM_FORMAT_XRGB8888)
-    return NULL;
-
-  return crtc_kms->modifiers_xrgb8888;
+  return g_hash_table_lookup (crtc_kms->formats_modifiers,
+                              GUINT_TO_POINTER (format));
 }
 
 static inline uint32_t *
@@ -199,6 +203,15 @@ modifiers_ptr (struct drm_format_modifier_blob *blob)
                                          blob->modifiers_offset);
 }
 
+static void
+free_modifier_array (GArray *array)
+{
+  if (!array)
+    return;
+
+  g_array_free (array, TRUE);
+}
+
 static void
 parse_formats (MetaCrtc *crtc,
                int       kms_fd,
@@ -209,8 +222,9 @@ parse_formats (MetaCrtc *crtc,
   struct drm_format_modifier_blob *blob_fmt;
   uint32_t *formats;
   struct drm_format_modifier *modifiers;
-  unsigned int i;
-  unsigned int xrgb_idx = UINT_MAX;
+  unsigned int fmt_i, mod_i;
+
+  g_return_if_fail (g_hash_table_size (crtc_kms->formats_modifiers) == 0);
 
   if (blob_id == 0)
     return;
@@ -227,43 +241,36 @@ parse_formats (MetaCrtc *crtc,
 
   blob_fmt = blob->data;
 
-  /* Find the index of our XRGB8888 format. */
   formats = formats_ptr (blob_fmt);
-  for (i = 0; i < blob_fmt->count_formats; i++)
+  modifiers = modifiers_ptr (blob_fmt);
+
+  for (fmt_i = 0; fmt_i < blob_fmt->count_formats; fmt_i++)
     {
-      if (formats[i] == DRM_FORMAT_XRGB8888)
+      GArray *mod_tmp = g_array_new (FALSE, FALSE, sizeof (uint64_t));
+
+      for (mod_i = 0; mod_i < blob_fmt->count_modifiers; mod_i++)
         {
-          xrgb_idx = i;
-          break;
-        }
-    }
+          struct drm_format_modifier *modifier = &modifiers[mod_i];
 
-  if (xrgb_idx == UINT_MAX)
-    {
-      drmModeFreePropertyBlob (blob);
-      return;
-    }
+          /* The modifier advertisement blob is partitioned into groups of
+           * 64 formats. */
+          if (fmt_i < modifier->offset || fmt_i > modifier->offset + 63)
+            continue;
 
-  modifiers = modifiers_ptr (blob_fmt);
-  crtc_kms->modifiers_xrgb8888 = g_array_new (FALSE, FALSE, sizeof (uint64_t));
-  for (i = 0; i < blob_fmt->count_modifiers; i++)
-    {
-      /* The modifier advertisement blob is partitioned into groups of
-       * 64 formats. */
-      if (xrgb_idx < modifiers[i].offset ||
-          xrgb_idx > modifiers[i].offset + 63)
-        continue;
+          if (!(modifier->formats & (1 << (fmt_i - modifier->offset))))
+            continue;
 
-      if (!(modifiers[i].formats & (1 << (xrgb_idx - modifiers[i].offset))))
-        continue;
+          g_array_append_val (mod_tmp, modifier->modifier);
+        }
 
-      g_array_append_val (crtc_kms->modifiers_xrgb8888, modifiers[i].modifier);
-    }
+      if (mod_tmp->len == 0)
+        {
+          free_modifier_array (mod_tmp);
+          mod_tmp = NULL;
+        }
 
-  if (crtc_kms->modifiers_xrgb8888->len == 0)
-    {
-      g_array_free (crtc_kms->modifiers_xrgb8888, TRUE);
-      crtc_kms->modifiers_xrgb8888 = NULL;
+      g_hash_table_insert (crtc_kms->formats_modifiers,
+                           GUINT_TO_POINTER (formats[fmt_i]), mod_tmp);
     }
 
   drmModeFreePropertyBlob (blob);
@@ -423,8 +430,7 @@ meta_crtc_destroy_notify (MetaCrtc *crtc)
 {
   MetaCrtcKms *crtc_kms = crtc->driver_private;
 
-  if (crtc_kms->modifiers_xrgb8888)
-    g_array_free (crtc_kms->modifiers_xrgb8888, TRUE);
+  g_hash_table_destroy (crtc_kms->formats_modifiers);
   g_free (crtc->driver_private);
 }
 
@@ -468,6 +474,12 @@ meta_create_kms_crtc (MetaGpuKms   *gpu_kms,
   crtc_kms = g_new0 (MetaCrtcKms, 1);
   crtc_kms->index = crtc_index;
 
+  crtc_kms->formats_modifiers =
+    g_hash_table_new_full (g_direct_hash,
+                           g_direct_equal,
+                           NULL,
+                           (GDestroyNotify) free_modifier_array);
+
   crtc->driver_private = crtc_kms;
   crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
 


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