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



commit 588c0a456afd19f0f1eaa2b7db718ae089049a13
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Oct 23 10:21:54 2020 +0200

    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>

 src/backends/native/meta-renderer-native.c | 35 ++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
---
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 281091f3ed..5c3fe49800 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;
 };
@@ -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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]