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:
parent
54b393c2b3
commit
b6841e2e33
@ -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 =
|
||||
|
Loading…
x
Reference in New Issue
Block a user