1
0
Fork 0

onscreen/native: Insert a 'posted' frame between 'next' and 'current'

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.
This commit is contained in:
Daniel van Vugt 2023-12-05 17:50:44 +08:00
parent c12fbdb912
commit f5a36efe3a

View file

@ -98,8 +98,10 @@ struct _MetaOnscreenNative
struct { struct {
struct gbm_surface *surface; struct gbm_surface *surface;
MetaDrmBuffer *current_fb; MetaDrmBuffer *current_fb;
MetaDrmBuffer *posted_fb;
MetaDrmBuffer *next_fb; MetaDrmBuffer *next_fb;
CoglScanout *current_scanout; CoglScanout *current_scanout;
CoglScanout *posted_scanout;
CoglScanout *next_scanout; CoglScanout *next_scanout;
} gbm; } gbm;
@ -146,39 +148,30 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native,
CoglOnscreen *onscreen, CoglOnscreen *onscreen,
GError **error); GError **error);
static void
free_current_bo (CoglOnscreen *onscreen)
{
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
g_clear_object (&onscreen_native->gbm.current_fb);
g_clear_object (&onscreen_native->gbm.current_scanout);
}
static void static void
meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen) 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->gbm.next_fb) if (!onscreen_native->gbm.posted_fb)
return; return;
free_current_bo (onscreen); g_set_object (&onscreen_native->gbm.current_fb,
onscreen_native->gbm.posted_fb);
g_clear_object (&onscreen_native->gbm.posted_fb);
g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
g_clear_object (&onscreen_native->gbm.next_fb);
g_set_object (&onscreen_native->gbm.current_scanout, g_set_object (&onscreen_native->gbm.current_scanout,
onscreen_native->gbm.next_scanout); onscreen_native->gbm.posted_scanout);
g_clear_object (&onscreen_native->gbm.next_scanout); g_clear_object (&onscreen_native->gbm.posted_scanout);
} }
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_object (&onscreen_native->gbm.next_fb); g_clear_object (&onscreen_native->gbm.posted_fb);
g_clear_object (&onscreen_native->gbm.next_scanout); g_clear_object (&onscreen_native->gbm.posted_scanout);
} }
static void static void
@ -359,7 +352,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc,
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 MetaKmsPageFlipListenerVtable page_flip_listener_vtable = { static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
@ -530,13 +523,21 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
switch (renderer_gpu_data->mode) switch (renderer_gpu_data->mode)
{ {
case META_RENDERER_NATIVE_MODE_GBM: case META_RENDERER_NATIVE_MODE_GBM:
buffer = onscreen_native->gbm.next_fb; g_set_object (&onscreen_native->gbm.posted_fb,
onscreen_native->gbm.next_fb);
g_clear_object (&onscreen_native->gbm.next_fb);
if (onscreen_native->gbm.next_scanout) buffer = onscreen_native->gbm.posted_fb;
g_set_object (&onscreen_native->gbm.posted_scanout,
onscreen_native->gbm.next_scanout);
g_clear_object (&onscreen_native->gbm.next_scanout);
if (onscreen_native->gbm.posted_scanout)
{ {
cogl_scanout_get_src_rect (onscreen_native->gbm.next_scanout, cogl_scanout_get_src_rect (onscreen_native->gbm.posted_scanout,
&src_rect); &src_rect);
cogl_scanout_get_dst_rect (onscreen_native->gbm.next_scanout, cogl_scanout_get_dst_rect (onscreen_native->gbm.posted_scanout,
&dst_rect); &dst_rect);
} }
else else
@ -1267,7 +1268,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 = {
@ -1632,7 +1633,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
g_warning ("Direct scanout page flip failed: %s", error->message); g_warning ("Direct scanout page flip failed: %s", error->message);
cogl_scanout_notify_failed (onscreen_native->gbm.next_scanout, cogl_scanout_notify_failed (onscreen_native->gbm.posted_scanout,
onscreen); onscreen);
clutter_stage_view_add_redraw_clip (view, NULL); clutter_stage_view_add_redraw_clip (view, NULL);
clutter_stage_view_schedule_update_now (view); clutter_stage_view_schedule_update_now (view);
@ -1642,7 +1643,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 = {
@ -2882,8 +2883,11 @@ meta_onscreen_native_dispose (GObject *object)
{ {
case META_RENDERER_NATIVE_MODE_GBM: case META_RENDERER_NATIVE_MODE_GBM:
g_clear_object (&onscreen_native->gbm.next_fb); g_clear_object (&onscreen_native->gbm.next_fb);
g_clear_object (&onscreen_native->gbm.posted_fb);
g_clear_object (&onscreen_native->gbm.current_fb);
g_clear_object (&onscreen_native->gbm.next_scanout); g_clear_object (&onscreen_native->gbm.next_scanout);
free_current_bo (onscreen); g_clear_object (&onscreen_native->gbm.posted_scanout);
g_clear_object (&onscreen_native->gbm.current_scanout);
break; break;
case META_RENDERER_NATIVE_MODE_SURFACELESS: case META_RENDERER_NATIVE_MODE_SURFACELESS:
g_assert_not_reached (); g_assert_not_reached ();