[mutter] stage-view: Don't destroy onscreen until finalizing



commit a1daf0ab24fc4da1017485cafbf8953102cf12e3
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Sun Aug 16 21:36:38 2020 +0200

    stage-view: Don't destroy onscreen until finalizing
    
    There might be pending flip callbacks to process; we shouldn't release
    the buffers until we have received the callback.
    
    Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1378
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1407

 clutter/clutter/clutter-stage-view.c      | 14 +++++++++++++-
 clutter/clutter/cogl/clutter-stage-cogl.c | 26 +++++++++++++++++++++-----
 2 files changed, 34 insertions(+), 6 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index d02b92909f..b5d99f5301 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -1267,7 +1267,6 @@ clutter_stage_view_dispose (GObject *object)
   int i;
 
   g_clear_pointer (&priv->name, g_free);
-  g_clear_pointer (&priv->framebuffer, cogl_object_unref);
 
   g_clear_pointer (&priv->shadow.framebuffer, cogl_object_unref);
   for (i = 0; i < G_N_ELEMENTS (priv->shadow.dma_buf.handles); i++)
@@ -1286,6 +1285,18 @@ clutter_stage_view_dispose (GObject *object)
   G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
 }
 
+static void
+clutter_stage_view_finalize (GObject *object)
+{
+  ClutterStageView *view = CLUTTER_STAGE_VIEW (object);
+  ClutterStageViewPrivate *priv =
+    clutter_stage_view_get_instance_private (view);
+
+  g_clear_pointer (&priv->framebuffer, cogl_object_unref);
+
+  G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
+}
+
 static void
 clutter_stage_view_init (ClutterStageView *view)
 {
@@ -1310,6 +1321,7 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
   object_class->set_property = clutter_stage_view_set_property;
   object_class->constructed = clutter_stage_view_constructed;
   object_class->dispose = clutter_stage_view_dispose;
+  object_class->finalize = clutter_stage_view_finalize;
 
   obj_props[PROP_NAME] =
     g_param_spec_string ("name",
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index b53a6c16a4..9baccbd0e8 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -58,6 +58,8 @@ typedef struct _ClutterStageViewCoglPrivate
   ClutterDamageHistory *damage_history;
 
   guint notify_presented_handle_id;
+
+  CoglFrameClosure *frame_cb_closure;
 } ClutterStageViewCoglPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (ClutterStageViewCogl, clutter_stage_view_cogl,
@@ -762,27 +764,41 @@ clutter_stage_view_cogl_dispose (GObject *object)
   ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (object);
   ClutterStageViewCoglPrivate *view_priv =
     clutter_stage_view_cogl_get_instance_private (view_cogl);
+  ClutterStageView *view = CLUTTER_STAGE_VIEW (view_cogl);
 
   g_clear_handle_id (&view_priv->notify_presented_handle_id, g_source_remove);
   g_clear_pointer (&view_priv->damage_history, clutter_damage_history_free);
 
+  if (view_priv->frame_cb_closure)
+    {
+      CoglFramebuffer *framebuffer;
+
+      framebuffer = clutter_stage_view_get_onscreen (view);
+      cogl_onscreen_remove_frame_callback (COGL_ONSCREEN (framebuffer),
+                                           view_priv->frame_cb_closure);
+      view_priv->frame_cb_closure = NULL;
+    }
+
   G_OBJECT_CLASS (clutter_stage_view_cogl_parent_class)->dispose (object);
 }
 
 static void
 clutter_stage_view_cogl_constructed (GObject *object)
 {
+  ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (object);
+  ClutterStageViewCoglPrivate *view_priv =
+    clutter_stage_view_cogl_get_instance_private (view_cogl);
   ClutterStageView *view = CLUTTER_STAGE_VIEW (view_cogl);
   CoglFramebuffer *framebuffer;
 
   framebuffer = clutter_stage_view_get_onscreen (view);
-
   if (framebuffer && cogl_is_onscreen (framebuffer))
     {
-      cogl_onscreen_add_frame_callback (COGL_ONSCREEN (framebuffer),
-                                        frame_cb,
-                                        view,
-                                        NULL);
+      view_priv->frame_cb_closure =
+        cogl_onscreen_add_frame_callback (COGL_ONSCREEN (framebuffer),
+                                          frame_cb,
+                                          view,
+                                          NULL);
     }
 
   G_OBJECT_CLASS (clutter_stage_view_cogl_parent_class)->constructed (object);


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