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:
parent
ae812ca81e
commit
588c0a456a
1 changed files with 35 additions and 0 deletions
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue