[mutter/wip/carlosg/disconnect-from-backend] clutter: Use g_signal_handler_disconnect to disconnect frequent signal



commit 2c5c8ac37fe2c8562eeb6e79cc7831c60e7accfc
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Apr 30 12:48:48 2019 +0200

    clutter: Use g_signal_handler_disconnect to disconnect frequent signal
    
    Clutter does the nicety of connecting just created PangoContexts to
    ClutterBackend signals in order to update it on resolution/font changes.
    However the way the signals are disconnected (automatically via
    g_signal_connect_object() auto-disconnect feature) may incur into
    performance issues with a high enough number of ClutterActors with a
    PangoContext (eg. ClutterText) as the lookup by closure is linear across
    all signals and handlers.
    
    Keep the handler IDs around, and disconnect them specifically on dispose
    so it is more O(1)-ish.
    
    Related: https://gitlab.gnome.org/GNOME/mutter/issues/556

 clutter/clutter/clutter-actor.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 803f76aae..bee7846ae 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -807,6 +807,9 @@ struct _ClutterActorPrivate
   gpointer create_child_data;
   GDestroyNotify create_child_notify;
 
+  guint resolution_changed_id;
+  guint font_changed_id;
+
   /* bitfields: KEEP AT THE END */
 
   /* fixed position and sizes */
@@ -5983,6 +5986,7 @@ clutter_actor_dispose (GObject *object)
 {
   ClutterActor *self = CLUTTER_ACTOR (object);
   ClutterActorPrivate *priv = self->priv;
+  ClutterBackend *backend = clutter_get_default_backend ();
 
   CLUTTER_NOTE (MISC, "Dispose actor (name='%s', ref_count:%d) of type '%s'",
                _clutter_actor_get_debug_name (self),
@@ -6019,6 +6023,18 @@ clutter_actor_dispose (GObject *object)
       g_assert (!CLUTTER_ACTOR_IS_REALIZED (self));
     }
 
+  if (priv->resolution_changed_id)
+    {
+      g_signal_handler_disconnect (backend, priv->resolution_changed_id);
+      priv->resolution_changed_id = 0;
+    }
+
+  if (priv->font_changed_id)
+    {
+      g_signal_handler_disconnect (backend, priv->font_changed_id);
+      priv->font_changed_id = 0;
+    }
+
   g_clear_object (&priv->pango_context);
   g_clear_object (&priv->actions);
   g_clear_object (&priv->constraints);
@@ -15884,10 +15900,12 @@ clutter_actor_get_pango_context (ClutterActor *self)
     {
       priv->pango_context = clutter_actor_create_pango_context (self);
 
-      g_signal_connect_object (backend, "resolution-changed",
-                               G_CALLBACK (update_pango_context), priv->pango_context, 0);
-      g_signal_connect_object (backend, "font-changed",
-                               G_CALLBACK (update_pango_context), priv->pango_context, 0);
+      priv->resolution_changed_id =
+        g_signal_connect_object (backend, "resolution-changed",
+                                 G_CALLBACK (update_pango_context), priv->pango_context, 0);
+      priv->font_changed_id =
+        g_signal_connect_object (backend, "font-changed",
+                                 G_CALLBACK (update_pango_context), priv->pango_context, 0);
     }
   else
     update_pango_context (backend, priv->pango_context);


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