summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ã…dahl <jadahl@gmail.com>2020-10-23 10:21:54 +0200
committerMarge Bot <marge-bot@gnome.org>2021-01-22 16:47:08 +0000
commit588c0a456afd19f0f1eaa2b7db718ae089049a13 (patch)
tree4734aa4a40c92acc15802d1dd16e58a6b05aaef3
parentae812ca81e8633346fc3716e1c8a9454a05e72ec (diff)
downloadmutter-588c0a456afd19f0f1eaa2b7db718ae089049a13.tar.gz
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>
-rw-r--r--src/backends/native/meta-renderer-native.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 281091f3e..5c3fe4980 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -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;
};
@@ -1998,6 +2000,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)
{
MetaRenderer *renderer = META_RENDERER (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;
@@ -3273,6 +3285,25 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
}
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)
{
MetaBackend *backend = meta_renderer_get_backend (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,