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:
parent
c12fbdb912
commit
f5a36efe3a
1 changed files with 31 additions and 27 deletions
|
@ -98,8 +98,10 @@ struct _MetaOnscreenNative
|
|||
struct {
|
||||
struct gbm_surface *surface;
|
||||
MetaDrmBuffer *current_fb;
|
||||
MetaDrmBuffer *posted_fb;
|
||||
MetaDrmBuffer *next_fb;
|
||||
CoglScanout *current_scanout;
|
||||
CoglScanout *posted_scanout;
|
||||
CoglScanout *next_scanout;
|
||||
} gbm;
|
||||
|
||||
|
@ -146,39 +148,30 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native,
|
|||
CoglOnscreen *onscreen,
|
||||
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
|
||||
meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
||||
if (!onscreen_native->gbm.next_fb)
|
||||
if (!onscreen_native->gbm.posted_fb)
|
||||
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,
|
||||
onscreen_native->gbm.next_scanout);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
onscreen_native->gbm.posted_scanout);
|
||||
g_clear_object (&onscreen_native->gbm.posted_scanout);
|
||||
}
|
||||
|
||||
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_object (&onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
g_clear_object (&onscreen_native->gbm.posted_fb);
|
||||
g_clear_object (&onscreen_native->gbm.posted_scanout);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -359,7 +352,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc,
|
|||
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 MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
|
||||
|
@ -530,13 +523,21 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
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);
|
||||
cogl_scanout_get_dst_rect (onscreen_native->gbm.next_scanout,
|
||||
cogl_scanout_get_dst_rect (onscreen_native->gbm.posted_scanout,
|
||||
&dst_rect);
|
||||
}
|
||||
else
|
||||
|
@ -1267,7 +1268,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 = {
|
||||
|
@ -1632,7 +1633,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
|
|||
|
||||
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);
|
||||
clutter_stage_view_add_redraw_clip (view, NULL);
|
||||
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;
|
||||
|
||||
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 = {
|
||||
|
@ -2882,8 +2883,11 @@ meta_onscreen_native_dispose (GObject *object)
|
|||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
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);
|
||||
free_current_bo (onscreen);
|
||||
g_clear_object (&onscreen_native->gbm.posted_scanout);
|
||||
g_clear_object (&onscreen_native->gbm.current_scanout);
|
||||
break;
|
||||
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
||||
g_assert_not_reached ();
|
||||
|
|
Loading…
Reference in a new issue