1
0
Fork 0

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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
Signed-off-by: Mingi Sung <sungmg@saltyming.net>
This commit is contained in:
Daniel van Vugt 2023-12-05 17:50:44 +08:00 committed by Mingi Sung
parent e895919517
commit dfdd88ff74
Signed by: sungmg
GPG key ID: 41BAFD6FFD8036C5

View file

@ -105,6 +105,7 @@ struct _MetaOnscreenNative
gboolean secondary_gpu_used; gboolean secondary_gpu_used;
ClutterFrame *presented_frame; ClutterFrame *presented_frame;
ClutterFrame *posted_frame;
ClutterFrame *next_frame; ClutterFrame *next_frame;
struct { struct {
@ -153,20 +154,20 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
{ {
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
if (!onscreen_native->next_frame) if (!onscreen_native->posted_frame)
return; return;
g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref); g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref);
onscreen_native->presented_frame = onscreen_native->presented_frame =
g_steal_pointer (&onscreen_native->next_frame); g_steal_pointer (&onscreen_native->posted_frame);
} }
static void 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); 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 static void
@ -301,7 +302,7 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
frame_info = cogl_onscreen_peek_head_frame_info (onscreen); frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; 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); 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_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 = { 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); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaRendererNative *renderer_native = onscreen_native->renderer_native; MetaRendererNative *renderer_native = onscreen_native->renderer_native;
ClutterFrame *frame = onscreen_native->next_frame; g_autoptr (ClutterFrame) frame = NULL;
MetaFrameNative *frame_native; MetaFrameNative *frame_native;
MetaGpuKms *render_gpu = onscreen_native->render_gpu; MetaGpuKms *render_gpu = onscreen_native->render_gpu;
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
@ -538,6 +539,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs,
"Meta::OnscreenNative::flip_crtc()"); "Meta::OnscreenNative::flip_crtc()");
frame = g_steal_pointer (&onscreen_native->next_frame);
g_return_if_fail (frame); g_return_if_fail (frame);
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
@ -600,6 +602,10 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
#endif #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, meta_kms_update_add_page_flip_listener (kms_update,
kms_crtc, kms_crtc,
&page_flip_listener_vtable, &page_flip_listener_vtable,
@ -1329,7 +1335,7 @@ swap_buffer_result_feedback (const MetaKmsFeedback *kms_feedback,
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
meta_onscreen_native_notify_frame_complete (onscreen); 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 = { 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); MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
MetaKmsUpdate *kms_update; MetaKmsUpdate *kms_update;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL; g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
ClutterFrame *frame = onscreen_native->next_frame; g_autoptr (ClutterFrame) frame = NULL;
MetaFrameNative *frame_native; MetaFrameNative *frame_native;
COGL_TRACE_SCOPED_ANCHOR (MetaRendererNativePostKmsUpdate); COGL_TRACE_SCOPED_ANCHOR (MetaRendererNativePostKmsUpdate);
@ -1493,6 +1499,7 @@ post_latest_swap (CoglOnscreen *onscreen)
int n_rectangles; int n_rectangles;
int *rectangles; int *rectangles;
frame = clutter_frame_ref (onscreen_native->next_frame);
frame_native = meta_frame_native_from_frame (frame); frame_native = meta_frame_native_from_frame (frame);
n_rectangles = meta_frame_native_get_damage (frame_native, &rectangles); 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)) G_IO_ERROR_PERMISSION_DENIED))
{ {
ClutterStageView *view = CLUTTER_STAGE_VIEW (onscreen_native->view); ClutterStageView *view = CLUTTER_STAGE_VIEW (onscreen_native->view);
ClutterFrame *next_frame = onscreen_native->next_frame; ClutterFrame *posted_frame = onscreen_native->posted_frame;
MetaFrameNative *next_frame_native = MetaFrameNative *posted_frame_native =
meta_frame_native_from_frame (next_frame); meta_frame_native_from_frame (posted_frame);
CoglScanout *scanout = 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); 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; frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
meta_onscreen_native_notify_frame_complete (onscreen); 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 = { static const MetaKmsResultListenerVtable scanout_result_listener_vtable = {
@ -2922,6 +2929,7 @@ meta_onscreen_native_dispose (GObject *object)
meta_onscreen_native_detach (onscreen_native); meta_onscreen_native_detach (onscreen_native);
g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref); 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); g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref);
renderer_gpu_data = renderer_gpu_data =