From 167b013b99e92d56c5ec7aed8ab36aa25deec53e 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 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 a7de255ce..150cc0d10 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -104,6 +104,7 @@ struct _MetaOnscreenNative MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; ClutterFrame *presented_frame; + ClutterFrame *posted_frame; ClutterFrame *next_frame; struct { @@ -152,20 +153,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 @@ -300,7 +301,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); } @@ -372,7 +373,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 = { @@ -521,7 +522,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); @@ -537,6 +538,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)); @@ -599,6 +601,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, @@ -1356,7 +1362,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 = { @@ -1524,7 +1530,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; int sync_fd; COGL_TRACE_SCOPED_ANCHOR (MetaRendererNativePostKmsUpdate); @@ -1535,6 +1541,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); @@ -1689,11 +1696,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); @@ -1706,7 +1713,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 = { @@ -2954,6 +2961,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 =