From 8a2fcf3be0189cd949ca19897fa7a8624a3f4a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 8 Dec 2021 21:23:54 +0100 Subject: [PATCH] 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: --- 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 cc2a8ca76..372368ef4 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; + 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; - crtc_config = meta_crtc_get_config (onscreen_native->crtc); - if (crtc_config->transform != META_MONITOR_TRANSFORM_NORMAL) - 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 (onscreen_native->secondary_gpu_state) - 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); - 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; - - if (gbm_bo_get_modifier (gbm_bo) != drm_modifier) - return FALSE; - - if (gbm_bo_get_stride (gbm_bo) != stride) - return FALSE; - - 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 5c99181d3..3a85ace26 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 bb547f711..8b354e7aa 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 f7e929c5b..f7b334b49 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