[mutter] native/renderer: Retrieve the right modifiers set for each GPU



commit aec85281ba76dfd564f71b88dc0a2800b6fc4027
Author: Louis-Francis Ratté-Boulianne <lfrb collabora com>
Date:   Wed Feb 14 13:27:28 2018 -0500

    native/renderer: Retrieve the right modifiers set for each GPU
    
    We were retrieving the supported KMS modifiers for all GPUs even
    though what we really need to intersect between these sets of
    modifiers:
    
    1) KMS supported modifiers for primary GPU if the GPU is used for
       scanout;
    
    2) EGL supported modifiers for secondary GPUs (different than the
       primary GPU used for rendering);
    
    3) GBM supported modifiers when creating the surface (already
       taken care of by gbm_surface_create_with_modifiers());
    
    https://gitlab.gnome.org/GNOME/mutter/issues/18

 src/backends/native/meta-renderer-native.c | 381 ++++++++++++++++++-----------
 1 file changed, 241 insertions(+), 140 deletions(-)
---
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 5b3a9a925..825833975 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -310,6 +310,247 @@ meta_onscreen_native_get_egl (MetaOnscreenNative *onscreen_native)
   return meta_renderer_native_get_egl (onscreen_native->renderer_native);
 }
 
+static GArray *
+get_supported_kms_modifiers (CoglOnscreen *onscreen,
+                             MetaGpu      *gpu,
+                             uint32_t      format)
+{
+  CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
+  MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
+  MetaLogicalMonitor *logical_monitor = onscreen_native->logical_monitor;
+  GArray *modifiers;
+  GArray *base_mods;
+  GList *l_crtc;
+  MetaCrtc *base_crtc = NULL;
+  GList *other_crtcs = NULL;
+  unsigned int i;
+
+  if (!logical_monitor)
+    return NULL;
+
+  /* Find our base CRTC to intersect against. */
+  for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
+    {
+      MetaCrtc *crtc = l_crtc->data;
+
+      if (crtc->logical_monitor != logical_monitor)
+        continue;
+
+      if (!base_crtc)
+        base_crtc = crtc;
+      else if (crtc == base_crtc)
+        continue;
+      else if (g_list_index (other_crtcs, crtc) == -1)
+        other_crtcs = g_list_append (other_crtcs, crtc);
+    }
+
+  if (!base_crtc)
+    goto out;
+
+  base_mods = meta_crtc_kms_get_modifiers (base_crtc, format);
+  if (!base_mods)
+    goto out;
+
+  /*
+   * If this is the only CRTC we have, we don't need to intersect the sets of
+   * modifiers.
+   */
+  if (other_crtcs == NULL)
+    {
+      modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t),
+                                     base_mods->len);
+      g_array_append_vals (modifiers, base_mods->data, base_mods->len);
+      return modifiers;
+    }
+
+  modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t));
+
+  /*
+   * For each modifier from base_crtc, check if it's available on all other
+   * CRTCs.
+   */
+  for (i = 0; i < base_mods->len; i++)
+    {
+      uint64_t modifier = g_array_index (base_mods, uint64_t, i);
+      gboolean found_everywhere = TRUE;
+      GList *k;
+
+      /* Check if we have the same modifier available for all CRTCs. */
+      for (k = other_crtcs; k; k = k->next)
+        {
+          MetaCrtc *crtc = k->data;
+          GArray *crtc_mods;
+          unsigned int m;
+          gboolean found_here = FALSE;
+
+          if (crtc->logical_monitor != logical_monitor)
+            continue;
+
+          crtc_mods = meta_crtc_kms_get_modifiers (crtc, format);
+          if (!crtc_mods)
+            {
+              g_array_free (modifiers, TRUE);
+              goto out;
+            }
+
+          for (m = 0; m < crtc_mods->len; m++)
+            {
+              uint64_t local_mod = g_array_index (crtc_mods, uint64_t, m);
+
+              if (local_mod == modifier)
+                {
+                  found_here = TRUE;
+                  break;
+                }
+            }
+
+          if (!found_here)
+            {
+              found_everywhere = FALSE;
+              break;
+            }
+        }
+
+      if (found_everywhere)
+        g_array_append_val (modifiers, modifier);
+    }
+
+  if (modifiers->len == 0)
+    {
+      g_array_free (modifiers, TRUE);
+      goto out;
+    }
+
+  return modifiers;
+
+out:
+  g_list_free (other_crtcs);
+  return NULL;
+}
+
+static GArray *
+get_supported_egl_modifiers (CoglOnscreen *onscreen,
+                             MetaGpu      *gpu,
+                             uint32_t      format)
+{
+  CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
+  MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
+  MetaRendererNative *renderer_native = onscreen_native->renderer_native;
+  MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
+  MetaRendererNativeGpuData *renderer_gpu_data;
+  EGLint num_modifiers;
+  GArray *modifiers;
+  GError *error = NULL;
+  gboolean ret;
+
+  renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
+                                                         META_GPU_KMS (gpu));
+
+  if (!meta_egl_has_extensions (egl, renderer_gpu_data->egl_display, NULL,
+                                "EGL_EXT_image_dma_buf_import_modifiers",
+                                NULL))
+    return NULL;
+
+  ret = meta_egl_query_dma_buf_modifiers (egl, renderer_gpu_data->egl_display,
+                                          format, 0, NULL, NULL,
+                                          &num_modifiers, NULL);
+  if (!ret || num_modifiers == 0)
+    return NULL;
+
+  modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t),
+                                 num_modifiers);
+  ret = meta_egl_query_dma_buf_modifiers (egl, renderer_gpu_data->egl_display,
+                                          format, num_modifiers,
+                                          (EGLuint64KHR *) modifiers->data, NULL,
+                                          &num_modifiers, &error);
+
+  if (!ret)
+    {
+      g_warning ("Failed to query DMABUF modifiers: %s", error->message);
+      g_error_free (error);
+      g_array_free (modifiers, TRUE);
+      return NULL;
+    }
+
+  return modifiers;
+}
+
+static GArray *
+get_supported_modifiers (CoglOnscreen *onscreen,
+                         uint32_t      format)
+{
+  CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
+  MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
+  MetaLogicalMonitor *logical_monitor = onscreen_native->logical_monitor;
+  GArray *modifiers = NULL;
+  GArray *gpu_mods;
+  GList *l_monitor;
+  unsigned int i;
+
+  if (!logical_monitor)
+    return NULL;
+
+  /* Find our base CRTC to intersect against. */
+  for (l_monitor = meta_logical_monitor_get_monitors (logical_monitor);
+       l_monitor;
+       l_monitor = l_monitor->next)
+    {
+      MetaMonitor *monitor = l_monitor->data;
+      MetaGpu *gpu = meta_monitor_get_gpu (monitor);
+
+      if (gpu == META_GPU (onscreen_native->render_gpu))
+        gpu_mods = get_supported_kms_modifiers (onscreen, gpu, format);
+      else
+        gpu_mods = get_supported_egl_modifiers (onscreen, gpu, format);
+
+      if (!gpu_mods)
+        {
+          g_array_free (modifiers, TRUE);
+          return NULL;
+        }
+
+      if (!modifiers)
+        {
+          modifiers = gpu_mods;
+          continue;
+        }
+
+      for (i = 0; i < modifiers->len; i++)
+        {
+          uint64_t modifier = g_array_index (modifiers, uint64_t, i);
+          gboolean found = FALSE;
+          unsigned int m;
+
+          for (m = 0; m < gpu_mods->len; m++)
+            {
+              uint64_t gpu_mod = g_array_index (gpu_mods, uint64_t, m);
+
+              if (gpu_mod == modifier)
+                {
+                  found = TRUE;
+                  break;
+                }
+            }
+
+          if (!found)
+            {
+              g_array_remove_index_fast (modifiers, i);
+              i--;
+            }
+        }
+
+      g_array_free (gpu_mods, TRUE);
+    }
+
+  if (modifiers && modifiers->len == 0)
+    {
+      g_array_free (modifiers, TRUE);
+      return NULL;
+    }
+
+  return modifiers;
+}
+
 static gboolean
 init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative         *renderer_native,
                                         CoglOnscreen               *onscreen,
@@ -1639,146 +1880,6 @@ meta_renderer_native_init_egl_context (CoglContext *cogl_context,
   return TRUE;
 }
 
-static GArray *
-get_supported_modifiers (CoglOnscreen *onscreen,
-                         uint32_t      format)
-{
-  CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
-  MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
-  MetaRendererNative *renderer_native = onscreen_native->renderer_native;
-  MetaLogicalMonitor *logical_monitor = onscreen_native->logical_monitor;
-  MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
-  CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
-  CoglRenderer *cogl_renderer = cogl_context->display->renderer;
-  CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
-  GArray *modifiers;
-  GArray *base_mods;
-  GList *l_crtc, *l_monitor;
-  MetaCrtc *base_crtc = NULL;
-  GList *other_crtcs = NULL;
-  unsigned int i;
-
-  if (!logical_monitor)
-    return NULL;
-
-  /* Find our base CRTC to intersect against. */
-  for (l_monitor = meta_logical_monitor_get_monitors (logical_monitor);
-       l_monitor;
-       l_monitor = l_monitor->next)
-    {
-      MetaMonitor *monitor = l_monitor->data;
-      MetaGpu *gpu = meta_monitor_get_gpu (monitor);
-      MetaRendererNativeGpuData *renderer_gpu_data;
-
-      /* All secondary GPUs need to be able to import DMA BUF with modifiers */
-      renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
-                                                             META_GPU_KMS (gpu));
-      if (cogl_renderer_egl->platform != renderer_gpu_data &&
-          !meta_egl_has_extensions (egl, renderer_gpu_data->egl_display, NULL,
-                                    "EGL_EXT_image_dma_buf_import_modifiers",
-                                    NULL))
-        goto out;
-
-      for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
-        {
-          MetaCrtc *crtc = l_crtc->data;
-
-          if (crtc->logical_monitor != logical_monitor)
-            continue;
-
-          if (!base_crtc)
-            base_crtc = crtc;
-          else if (crtc == base_crtc)
-            continue;
-          else if (g_list_index (other_crtcs, crtc) == -1)
-            other_crtcs = g_list_append (other_crtcs, crtc);
-        }
-    }
-
-  if (!base_crtc)
-    goto out;
-
-  base_mods = meta_crtc_kms_get_modifiers (base_crtc, format);
-  if (!base_mods)
-    goto out;
-
-  /*
-   * If this is the only CRTC we have, we don't need to intersect the sets of
-   * modifiers.
-   */
-  if (other_crtcs == NULL)
-    {
-      modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t),
-                                     base_mods->len);
-      g_array_append_vals (modifiers, base_mods->data, base_mods->len);
-      return modifiers;
-    }
-
-  modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t));
-
-  /*
-   * For each modifier from base_crtc, check if it's available on all other
-   * CRTCs.
-   */
-  for (i = 0; i < base_mods->len; i++)
-    {
-      uint64_t modifier = g_array_index (base_mods, uint64_t, i);
-      gboolean found_everywhere = TRUE;
-      GList *k;
-
-      /* Check if we have the same modifier available for all CRTCs. */
-      for (k = other_crtcs; k; k = k->next)
-        {
-          MetaCrtc *crtc = k->data;
-          GArray *crtc_mods;
-          unsigned int m;
-          gboolean found_here = FALSE;
-
-          if (crtc->logical_monitor != logical_monitor)
-            continue;
-
-          crtc_mods = meta_crtc_kms_get_modifiers (crtc, format);
-          if (!crtc_mods)
-            {
-              g_array_free (modifiers, TRUE);
-              goto out;
-            }
-
-          for (m = 0; m < crtc_mods->len; m++)
-            {
-              uint64_t local_mod = g_array_index (crtc_mods, uint64_t, m);
-
-              if (local_mod == modifier)
-                {
-                  found_here = TRUE;
-                  break;
-                }
-            }
-
-          if (!found_here)
-            {
-              found_everywhere = FALSE;
-              break;
-            }
-        }
-
-      if (found_everywhere)
-        g_array_append_val (modifiers, modifier);
-    }
-
-  if (modifiers->len == 0)
-    {
-      g_array_free (modifiers, TRUE);
-      goto out;
-    }
-
-  return modifiers;
-
-out:
-  g_list_free (other_crtcs);
-  return NULL;
-}
-
 static gboolean
 should_surface_be_sharable (CoglOnscreen *onscreen)
 {


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