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

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
This commit is contained in:
Daniel van Vugt 2023-12-05 17:50:44 +08:00 committed by Marge Bot
parent 54b393c2b3
commit b6841e2e33

View File

@ -105,6 +105,7 @@ struct _MetaOnscreenNative
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
ClutterFrame *presented_frame;
ClutterFrame *posted_frame;
ClutterFrame *next_frame;
struct {
@ -151,20 +152,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
@ -299,7 +300,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);
}
@ -368,7 +369,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 = {
@ -544,7 +545,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);
@ -560,6 +561,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));
@ -619,6 +621,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,
@ -1378,7 +1384,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 = {
@ -1536,7 +1542,7 @@ post_next_frame (CoglOnscreen *onscreen)
MetaKmsDevice *kms_device;
MetaKmsUpdate *kms_update;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
ClutterFrame *frame = onscreen_native->next_frame;
g_autoptr (ClutterFrame) frame = NULL;
MetaFrameNative *frame_native;
MtkRegion *region;
int sync_fd;
@ -1551,6 +1557,7 @@ post_next_frame (CoglOnscreen *onscreen)
return;
}
frame = clutter_frame_ref (onscreen_native->next_frame);
frame_native = meta_frame_native_from_frame (frame);
region = meta_frame_native_get_damage (frame_native);
@ -1702,24 +1709,27 @@ 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);
cogl_scanout_notify_failed (scanout, onscreen);
clutter_stage_view_add_redraw_clip (view, NULL);
clutter_stage_view_schedule_update_now (view);
if (onscreen_native->next_frame == NULL)
{
clutter_stage_view_add_redraw_clip (view, NULL);
clutter_stage_view_schedule_update_now (view);
}
}
frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
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 = {
@ -2877,6 +2887,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 =