[mutter] later: Listen to MetaCompositor signal instead of clutter



commit b51c468c0facc3be5df597a6fe0c8c35b95a1fff
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Mar 3 10:04:16 2020 +0100

    later: Listen to MetaCompositor signal instead of clutter
    
    We need to coordinate with MetaCompositor during pre-paint so that we
    have control over whether MetaLater callbacks happen first, or the
    MetaCompositor pre-paint logic.
    
    In order to do so, make MetaLater listen to a new signal "pre-paint" on
    MetaCompositor, that is called MetaCompositors own pre-paint handling.
    
    This fixes an issue where the top window actor was calculated after the
    MetaCompositor pre-paint handling, meaning the top actor being painted
    was out-of-date.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/798

 src/compositor/compositor.c         | 22 ++++++++++++++++--
 src/compositor/meta-later-private.h |  3 ++-
 src/compositor/meta-later.c         | 46 ++++++++++++++++++-------------------
 3 files changed, 44 insertions(+), 27 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 06b5ee6a3..7c94687dd 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -97,6 +97,15 @@ enum
 
 static GParamSpec *obj_props[N_PROPS] = { NULL, };
 
+enum
+{
+  PRE_PAINT,
+
+  N_SIGNALS
+};
+
+static guint signals[N_SIGNALS];
+
 typedef struct _MetaCompositorPrivate
 {
   GObject parent;
@@ -1124,7 +1133,8 @@ meta_compositor_pre_paint (MetaCompositor *compositor)
 {
   COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint,
                            "Compositor (pre-paint)");
-  META_COMPOSITOR_GET_CLASS (compositor)->pre_paint (compositor);
+
+  g_signal_emit (compositor, signals[PRE_PAINT], 0);
 }
 
 static gboolean
@@ -1247,7 +1257,7 @@ meta_compositor_init (MetaCompositor *compositor)
                                            compositor,
                                            NULL);
 
-  priv->laters = meta_laters_new ();
+  priv->laters = meta_laters_new (compositor);
 }
 
 static void
@@ -1300,6 +1310,14 @@ meta_compositor_class_init (MetaCompositorClass *klass)
                          G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_STATIC_STRINGS);
   g_object_class_install_properties (object_class, N_PROPS, obj_props);
+
+  signals[PRE_PAINT] =
+    g_signal_new ("pre-paint",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (MetaCompositorClass, pre_paint),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
 }
 
 /**
diff --git a/src/compositor/meta-later-private.h b/src/compositor/meta-later-private.h
index b1c88766f..c8d0f80a8 100644
--- a/src/compositor/meta-later-private.h
+++ b/src/compositor/meta-later-private.h
@@ -19,8 +19,9 @@
 #define META_LATER_PRIVATE_H
 
 typedef struct _MetaLaters MetaLaters;
+typedef struct _MetaCompositor MetaCompositor;
 
-MetaLaters * meta_laters_new (void);
+MetaLaters * meta_laters_new (MetaCompositor *compositor);
 
 void meta_laters_free (MetaLaters *laters);
 
diff --git a/src/compositor/meta-later.c b/src/compositor/meta-later.c
index aaa0f11d4..b68e59a5b 100644
--- a/src/compositor/meta-later.c
+++ b/src/compositor/meta-later.c
@@ -44,12 +44,14 @@ typedef struct _MetaLater
 
 struct _MetaLaters
 {
+  MetaCompositor *compositor;
+
   unsigned int last_later_id;
 
   GSList *laters[META_LATER_N_TYPES];
 
   ClutterTimeline *timeline;
-  guint repaint_func;
+  gulong pre_paint_handler_id;
 };
 
 static MetaLater *
@@ -163,10 +165,10 @@ run_repaint_laters (GSList **laters_list)
     }
 }
 
-static gboolean
-run_all_repaint_laters (gpointer data)
+static void
+on_pre_paint (MetaCompositor *compositor,
+              MetaLaters     *laters)
 {
-  MetaLaters *laters = data;
   unsigned int i;
   GSList *l;
   gboolean keep_timeline_running = FALSE;
@@ -187,24 +189,11 @@ run_all_repaint_laters (gpointer data)
 
   if (!keep_timeline_running)
     clutter_timeline_stop (laters->timeline);
-
-  return TRUE;
 }
 
 static void
-ensure_later_repaint_func (MetaLaters *laters)
+ensure_timeline_running (MetaLaters *laters)
 {
-  if (!laters->timeline)
-    laters->timeline = clutter_timeline_new (G_MAXUINT);
-
-  if (laters->repaint_func == 0)
-    {
-      laters->repaint_func =
-        clutter_threads_add_repaint_func (run_all_repaint_laters,
-                                          laters, NULL);
-    }
-
-  /* Make sure the repaint function gets run */
   clutter_timeline_start (laters->timeline);
 }
 
@@ -250,13 +239,13 @@ meta_laters_add (MetaLaters     *laters,
                                           invoke_later_idle,
                                           later, NULL);
       g_source_set_name_by_id (later->source_id, "[mutter] invoke_later_idle");
-      ensure_later_repaint_func (laters);
+      ensure_timeline_running (laters);
       break;
     case META_LATER_CALC_SHOWING:
     case META_LATER_CHECK_FULLSCREEN:
     case META_LATER_SYNC_STACK:
     case META_LATER_BEFORE_REDRAW:
-      ensure_later_repaint_func (laters);
+      ensure_timeline_running (laters);
       break;
     case META_LATER_IDLE:
       later->source_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
@@ -331,9 +320,19 @@ meta_later_remove (unsigned int later_id)
 }
 
 MetaLaters *
-meta_laters_new (void)
+meta_laters_new (MetaCompositor *compositor)
 {
-  return g_new0 (MetaLaters, 1);
+  MetaLaters *laters;
+
+  laters = g_new0 (MetaLaters, 1);
+  laters->compositor = compositor;
+  laters->timeline = clutter_timeline_new (G_MAXUINT);
+
+  laters->pre_paint_handler_id = g_signal_connect (compositor, "pre-paint",
+                                                   G_CALLBACK (on_pre_paint),
+                                                   laters);
+
+  return laters;
 }
 
 void
@@ -345,7 +344,6 @@ meta_laters_free (MetaLaters *laters)
     g_slist_free_full (laters->laters[i], (GDestroyNotify) meta_later_unref);
 
   g_clear_object (&laters->timeline);
-  if (laters->repaint_func)
-    clutter_threads_remove_repaint_func (laters->repaint_func);
+  g_clear_signal_handler (&laters->pre_paint_handler_id, laters->compositor);
   g_free (laters);
 }


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