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;
|
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||||
|
|
||||||
ClutterFrame *presented_frame;
|
ClutterFrame *presented_frame;
|
||||||
|
ClutterFrame *posted_frame;
|
||||||
ClutterFrame *next_frame;
|
ClutterFrame *next_frame;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -151,20 +152,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
|
||||||
@ -299,7 +300,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);
|
||||||
}
|
}
|
||||||
@ -368,7 +369,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 = {
|
||||||
@ -544,7 +545,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);
|
||||||
@ -560,6 +561,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));
|
||||||
@ -619,6 +621,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,
|
||||||
@ -1378,7 +1384,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 = {
|
||||||
@ -1536,7 +1542,7 @@ post_next_frame (CoglOnscreen *onscreen)
|
|||||||
MetaKmsDevice *kms_device;
|
MetaKmsDevice *kms_device;
|
||||||
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;
|
||||||
MtkRegion *region;
|
MtkRegion *region;
|
||||||
int sync_fd;
|
int sync_fd;
|
||||||
@ -1551,6 +1557,7 @@ post_next_frame (CoglOnscreen *onscreen)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frame = clutter_frame_ref (onscreen_native->next_frame);
|
||||||
frame_native = meta_frame_native_from_frame (frame);
|
frame_native = meta_frame_native_from_frame (frame);
|
||||||
region = meta_frame_native_get_damage (frame_native);
|
region = meta_frame_native_get_damage (frame_native);
|
||||||
|
|
||||||
@ -1702,24 +1709,27 @@ 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);
|
||||||
|
|
||||||
cogl_scanout_notify_failed (scanout, onscreen);
|
cogl_scanout_notify_failed (scanout, onscreen);
|
||||||
clutter_stage_view_add_redraw_clip (view, NULL);
|
if (onscreen_native->next_frame == NULL)
|
||||||
clutter_stage_view_schedule_update_now (view);
|
{
|
||||||
|
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 = cogl_onscreen_peek_head_frame_info (onscreen);
|
||||||
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 = {
|
||||||
@ -2877,6 +2887,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 =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user