From dfdd88ff74f5fbdba67a86554ce7571a7b3f8f3b Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Tue, 5 Dec 2023 17:50:44 +0800 Subject: [PATCH] onscreen/native: Insert a 'posted' frame between 'next' and 'presented' This will allow us to keep track of up to two buffers that have been swapped but not yet scanning out, for triple buffering. This commit replaces mutter!1968 (cherry picked from commit cd14dbbe1b3ea42a7e8ca5b19a4a177dffa6cae0) Part-of: Signed-off-by: Mingi Sung --- src/backends/native/meta-onscreen-native.c | 36 +++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 0e245449d..8ea47ae4e 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -105,6 +105,7 @@ struct _MetaOnscreenNative gboolean secondary_gpu_used; ClutterFrame *presented_frame; + ClutterFrame *posted_frame; ClutterFrame *next_frame; struct { @@ -153,20 +154,20 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen) { MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); - if (!onscreen_native->next_frame) + if (!onscreen_native->posted_frame) return; g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref); onscreen_native->presented_frame = - g_steal_pointer (&onscreen_native->next_frame); + g_steal_pointer (&onscreen_native->posted_frame); } static void -meta_onscreen_native_clear_next_fb (CoglOnscreen *onscreen) +meta_onscreen_native_clear_posted_fb (CoglOnscreen *onscreen) { MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); - g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref); + g_clear_pointer (&onscreen_native->posted_frame, clutter_frame_unref); } static void @@ -301,7 +302,7 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc, frame_info = cogl_onscreen_peek_head_frame_info (onscreen); frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; - g_warn_if_fail (!onscreen_native->next_frame); + g_warn_if_fail (!onscreen_native->posted_frame); meta_onscreen_native_notify_frame_complete (onscreen); } @@ -373,7 +374,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc, } meta_onscreen_native_notify_frame_complete (onscreen); - meta_onscreen_native_clear_next_fb (onscreen); + meta_onscreen_native_clear_posted_fb (onscreen); } static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = { @@ -522,7 +523,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, { MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaRendererNative *renderer_native = onscreen_native->renderer_native; - ClutterFrame *frame = onscreen_native->next_frame; + g_autoptr (ClutterFrame) frame = NULL; MetaFrameNative *frame_native; MetaGpuKms *render_gpu = onscreen_native->render_gpu; MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); @@ -538,6 +539,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, "Meta::OnscreenNative::flip_crtc()"); + frame = g_steal_pointer (&onscreen_native->next_frame); g_return_if_fail (frame); gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); @@ -600,6 +602,10 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, #endif } + g_warn_if_fail (!onscreen_native->posted_frame); + g_clear_pointer (&onscreen_native->posted_frame, clutter_frame_unref); + onscreen_native->posted_frame = g_steal_pointer (&frame); + meta_kms_update_add_page_flip_listener (kms_update, kms_crtc, &page_flip_listener_vtable, @@ -1329,7 +1335,7 @@ swap_buffer_result_feedback (const MetaKmsFeedback *kms_feedback, frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; meta_onscreen_native_notify_frame_complete (onscreen); - meta_onscreen_native_clear_next_fb (onscreen); + meta_onscreen_native_clear_posted_fb (onscreen); } static const MetaKmsResultListenerVtable swap_buffer_result_listener_vtable = { @@ -1482,7 +1488,7 @@ post_latest_swap (CoglOnscreen *onscreen) MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); MetaKmsUpdate *kms_update; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; - ClutterFrame *frame = onscreen_native->next_frame; + g_autoptr (ClutterFrame) frame = NULL; MetaFrameNative *frame_native; COGL_TRACE_SCOPED_ANCHOR (MetaRendererNativePostKmsUpdate); @@ -1493,6 +1499,7 @@ post_latest_swap (CoglOnscreen *onscreen) int n_rectangles; int *rectangles; + frame = clutter_frame_ref (onscreen_native->next_frame); frame_native = meta_frame_native_from_frame (frame); n_rectangles = meta_frame_native_get_damage (frame_native, &rectangles); @@ -1654,11 +1661,11 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback, G_IO_ERROR_PERMISSION_DENIED)) { ClutterStageView *view = CLUTTER_STAGE_VIEW (onscreen_native->view); - ClutterFrame *next_frame = onscreen_native->next_frame; - MetaFrameNative *next_frame_native = - meta_frame_native_from_frame (next_frame); + ClutterFrame *posted_frame = onscreen_native->posted_frame; + MetaFrameNative *posted_frame_native = + meta_frame_native_from_frame (posted_frame); CoglScanout *scanout = - meta_frame_native_get_scanout (next_frame_native); + meta_frame_native_get_scanout (posted_frame_native); g_warning ("Direct scanout page flip failed: %s", error->message); @@ -1671,7 +1678,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback, frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; meta_onscreen_native_notify_frame_complete (onscreen); - meta_onscreen_native_clear_next_fb (onscreen); + meta_onscreen_native_clear_posted_fb (onscreen); } static const MetaKmsResultListenerVtable scanout_result_listener_vtable = { @@ -2922,6 +2929,7 @@ meta_onscreen_native_dispose (GObject *object) meta_onscreen_native_detach (onscreen_native); g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref); + g_clear_pointer (&onscreen_native->posted_frame, clutter_frame_unref); g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref); renderer_gpu_data =