1
0
Fork 0

renderer/native: Keep onscreens alive until after the next mode set

Destroying an onscreen destroyes the gbm_surface, the gbm_bo's, and the
fb_id's. Doing this (drmModeRmFB() of the fb_id specifically), may on
some hw implicitly disable the CRTC of the plane that framebuffer was
assigned to. This would cause following atomic commit that attempts to
disable the CRTC to fail as disabling an already disabled CRTC is not
allowed.

It'd also mean we'd always disable the plane before having finished next
mode set, leaving it monitor content potentially empty when not really
necessary.

Solve this by keeping the CoglOnscreens (thus the gbm_surface, gbm_bo
and fb_id) alive until the following global mode set has completed, i.e.
the new state has been fully committed and applied.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-10-23 10:21:54 +02:00 committed by Marge Bot
parent ae812ca81e
commit 588c0a456a

View file

@ -203,6 +203,8 @@ struct _MetaRendererNative
gboolean pending_mode_set;
guint mode_set_failed_feedback_source_id;
GList *kept_alive_onscreens;
GList *power_save_page_flip_onscreens;
guint power_save_page_flip_source_id;
};
@ -1997,6 +1999,14 @@ configure_disabled_crtcs (MetaGpu *gpu,
}
}
static void
clear_kept_alive_onscreens (MetaRendererNative *renderer_native)
{
g_list_free_full (renderer_native->kept_alive_onscreens,
g_object_unref);
renderer_native->kept_alive_onscreens = NULL;
}
static void
meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
{
@ -2035,6 +2045,8 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
}
}
clear_kept_alive_onscreens (renderer_native);
if (failed_views)
{
DispatchFailedModeSetViews *data;
@ -3272,6 +3284,25 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
return view;
}
static void
keep_current_onscreens_alive (MetaRenderer *renderer)
{
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
GList *views;
GList *l;
views = meta_renderer_get_views (renderer);
for (l = views; l; l = l->next)
{
ClutterStageView *stage_view = l->data;
CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (stage_view);
renderer_native->kept_alive_onscreens =
g_list_prepend (renderer_native->kept_alive_onscreens,
g_object_ref (onscreen));
}
}
static void
meta_renderer_native_rebuild_views (MetaRenderer *renderer)
{
@ -3283,6 +3314,8 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer)
meta_kms_discard_pending_page_flips (kms);
keep_current_onscreens_alive (renderer);
parent_renderer_class->rebuild_views (renderer);
meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer));
@ -4100,6 +4133,8 @@ meta_renderer_native_finalize (GObject *object)
{
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object);
clear_kept_alive_onscreens (renderer_native);
if (renderer_native->power_save_page_flip_onscreens)
{
g_list_free_full (renderer_native->power_save_page_flip_onscreens,