From ba8f5a1178fe8dc6aa2cf5bdd311216b42056278 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 30 Apr 2019 12:48:48 +0200 Subject: [PATCH] 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);