[mutter] wayland: Use new KMS update test API to try acquiring scanout



commit 8a2fcf3be0189cd949ca19897fa7a8624a3f4a68
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Dec 8 21:23:54 2021 +0100

    wayland: Use new KMS update test API to try acquiring scanout
    
    This significantly increases the chance of a fullscreen surface buffer
    being scanned out instead of being painted via composition. This is
    assuming the client supports the DMA buffer feedback Wayland protocol.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2146>

 src/backends/native/meta-onscreen-native.c | 54 +++++++++++-------------------
 src/backends/native/meta-onscreen-native.h |  6 ++--
 src/wayland/meta-wayland-buffer.c          | 28 ++++++----------
 src/wayland/meta-wayland-dma-buf.c         | 22 ++++--------
 4 files changed, 38 insertions(+), 72 deletions(-)
---
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
index cc2a8ca763..372368ef4b 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -1226,46 +1226,30 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen  *onscreen,
 }
 
 gboolean
-meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
-                                                   uint32_t      drm_format,
-                                                   uint64_t      drm_modifier,
-                                                   uint32_t      stride)
+meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen  *onscreen,
+                                                   MetaDrmBuffer *fb)
 {
   MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
-  const MetaCrtcConfig *crtc_config;
-  MetaDrmBuffer *fb;
-  struct gbm_bo *gbm_bo;
-
-  crtc_config = meta_crtc_get_config (onscreen_native->crtc);
-  if (crtc_config->transform != META_MONITOR_TRANSFORM_NORMAL)
-    return FALSE;
-
-  if (onscreen_native->secondary_gpu_state)
-    return FALSE;
-
-  if (!onscreen_native->gbm.surface)
-    return FALSE;
-
-  fb = onscreen_native->gbm.current_fb ? onscreen_native->gbm.current_fb
-                                       : onscreen_native->gbm.next_fb;
-  if (!fb)
-    return FALSE;
-
-  if (!META_IS_DRM_BUFFER_GBM (fb))
-    return FALSE;
-
-  gbm_bo = meta_drm_buffer_gbm_get_bo (META_DRM_BUFFER_GBM (fb));
-
-  if (gbm_bo_get_format (gbm_bo) != drm_format)
-    return FALSE;
+  MetaCrtc *crtc = onscreen_native->crtc;
+  MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
+  MetaGpuKms *gpu_kms;
+  MetaKmsDevice *kms_device;
+  MetaKms *kms;
+  MetaKmsUpdate *test_update;
+  g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
+  MetaKmsFeedbackResult result;
 
-  if (gbm_bo_get_modifier (gbm_bo) != drm_modifier)
-    return FALSE;
+  gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
+  kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
+  kms = meta_kms_device_get_kms (kms_device);
+  test_update = meta_kms_update_new (kms_device);
 
-  if (gbm_bo_get_stride (gbm_bo) != stride)
-    return FALSE;
+  meta_crtc_kms_assign_primary_plane (crtc_kms, fb, test_update);
+  kms_feedback = meta_kms_post_test_update_sync (kms, test_update);
+  meta_kms_update_free (test_update);
 
-  return TRUE;
+  result = meta_kms_feedback_get_result (kms_feedback);
+  return result == META_KMS_FEEDBACK_PASSED;
 }
 
 static gboolean
diff --git a/src/backends/native/meta-onscreen-native.h b/src/backends/native/meta-onscreen-native.h
index 5c99181d39..3a85ace267 100644
--- a/src/backends/native/meta-onscreen-native.h
+++ b/src/backends/native/meta-onscreen-native.h
@@ -40,10 +40,8 @@ void meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
 
 void meta_onscreen_native_dummy_power_save_page_flip (CoglOnscreen *onscreen);
 
-gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
-                                                            uint32_t      drm_format,
-                                                            uint64_t      drm_modifier,
-                                                            uint32_t      stride);
+gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen  *onscreen,
+                                                            MetaDrmBuffer *fb);
 
 void meta_onscreen_native_set_view (CoglOnscreen     *onscreen,
                                     MetaRendererView *view);
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index bb547f7117..8b354e7aa6 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -691,11 +691,8 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
   MetaDeviceFile *device_file;
   struct gbm_device *gbm_device;
   struct gbm_bo *gbm_bo;
-  uint32_t drm_format;
-  uint64_t drm_modifier;
-  uint32_t stride;
   MetaDrmBufferFlags flags;
-  MetaDrmBufferGbm *fb;
+  g_autoptr (MetaDrmBufferGbm) fb = NULL;
   g_autoptr (GError) error = NULL;
 
   gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
@@ -708,20 +705,8 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
   if (!gbm_bo)
     return NULL;
 
-  drm_format = gbm_bo_get_format (gbm_bo);
-  drm_modifier = gbm_bo_get_modifier (gbm_bo);
-  stride = gbm_bo_get_stride (gbm_bo);
-  if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
-                                                          drm_format,
-                                                          drm_modifier,
-                                                          stride))
-    {
-      gbm_bo_destroy (gbm_bo);
-      return NULL;
-    }
-
   flags = META_DRM_BUFFER_FLAG_NONE;
-  if (drm_modifier == DRM_FORMAT_MOD_INVALID)
+  if (gbm_bo_get_modifier (gbm_bo) == DRM_FORMAT_MOD_INVALID)
     flags |= META_DRM_BUFFER_FLAG_DISABLE_MODIFIERS;
 
   fb = meta_drm_buffer_gbm_new_take (device_file, gbm_bo, flags, &error);
@@ -732,7 +717,11 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
       return NULL;
     }
 
-  return COGL_SCANOUT (fb);
+  if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
+                                                          META_DRM_BUFFER (fb)))
+    return NULL;
+
+  return COGL_SCANOUT (g_steal_pointer (&fb));
 #else
   return NULL;
 #endif
@@ -742,6 +731,9 @@ CoglScanout *
 meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
                                          CoglOnscreen      *onscreen)
 {
+  COGL_TRACE_BEGIN_SCOPED (MetaWaylandBufferTryScanout,
+                           "WaylandBuffer (try scanout)");
+
   switch (buffer->type)
     {
     case META_WAYLAND_BUFFER_TYPE_SHM:
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
index f7e929c5b4..f7b334b496 100644
--- a/src/wayland/meta-wayland-dma-buf.c
+++ b/src/wayland/meta-wayland-dma-buf.c
@@ -528,17 +528,14 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
   MetaBackend *backend = meta_get_backend ();
   MetaRenderer *renderer = meta_backend_get_renderer (backend);
   MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
+  int n_planes;
   MetaDeviceFile *device_file;
   MetaGpuKms *gpu_kms;
-  int n_planes;
-  uint32_t drm_format;
-  uint64_t drm_modifier;
-  uint32_t stride;
   struct gbm_bo *gbm_bo;
   gboolean use_modifier;
   g_autoptr (GError) error = NULL;
   MetaDrmBufferFlags flags;
-  MetaDrmBufferGbm *fb;
+  g_autoptr (MetaDrmBufferGbm) fb = NULL;
 
   for (n_planes = 0; n_planes < META_WAYLAND_DMA_BUF_MAX_FDS; n_planes++)
     {
@@ -546,15 +543,6 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
         break;
     }
 
-  drm_format = dma_buf->drm_format;
-  drm_modifier = dma_buf->drm_modifier;
-  stride = dma_buf->strides[0];
-  if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
-                                                          drm_format,
-                                                          drm_modifier,
-                                                          stride))
-    return NULL;
-
   device_file = meta_renderer_native_get_primary_device_file (renderer_native);
   gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
   gbm_bo = import_scanout_gbm_bo (dma_buf, gpu_kms, n_planes, &use_modifier);
@@ -576,7 +564,11 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
       return NULL;
     }
 
-  return COGL_SCANOUT (fb);
+  if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
+                                                          META_DRM_BUFFER (fb)))
+    return NULL;
+
+  return COGL_SCANOUT (g_steal_pointer (&fb));
 #else
   return NULL;
 #endif


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