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



commit a7561025b27471ecf479433209f0322b889fe898
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 (with
    g_signal_handlers_disconnect*) may incur into performance issues with
    a high enough number of ClutterActors with a PangoContext (eg. ClutterText)
    as the lookup by func/data 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]