From d5a2392cc78aae038eaaab12d7a84b4e6d45f3bd Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 24 Mar 2012 02:15:41 +0100 Subject: [PATCH] stylecontext: Don't clear cache when only state changes This takes more memory, but changes to backdrop or active state are quite expensive otherwise. --- gtk/gtkstylecontext.c | 51 +++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 2d0c2da3b5..2072d4225d 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -304,6 +304,9 @@ /* When these change we do a full restyling. Otherwise we try to figure out * if we need to change things. */ #define GTK_STYLE_CONTEXT_RADICAL_CHANGE (GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS) +/* When these change we don't clear the cache. This takes more memory but makes + * things go faster. */ +#define GTK_STYLE_CONTEXT_CACHED_CHANGE (GTK_CSS_CHANGE_STATE) typedef struct GtkStyleInfo GtkStyleInfo; typedef struct GtkRegion GtkRegion; @@ -3268,6 +3271,31 @@ store_animation_region (GtkStyleContext *context, } } +static void +gtk_style_context_do_invalidate (GtkStyleContext *context, + gboolean clear_caches) +{ + GtkStyleContextPrivate *priv; + + g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); + + priv = context->priv; + + /* Avoid reentrancy */ + if (priv->invalidating_context) + return; + + priv->invalidating_context = TRUE; + + if (clear_caches) + g_hash_table_remove_all (priv->style_data); + priv->current_data = NULL; + + g_signal_emit (context, signals[CHANGED], 0); + + priv->invalidating_context = FALSE; +} + void _gtk_style_context_validate (GtkStyleContext *context, GtkCssChange change) @@ -3312,7 +3340,9 @@ _gtk_style_context_validate (GtkStyleContext *context, if (priv->relevant_changes & change) { - gtk_style_context_invalidate (context); + gboolean clear_cache = ((priv->relevant_changes & change) & ~GTK_STYLE_CONTEXT_CACHED_CHANGE) != 0; + + gtk_style_context_do_invalidate (context, clear_cache); } change = _gtk_css_change_for_child (change); @@ -3356,26 +3386,9 @@ _gtk_style_context_queue_invalidate (GtkStyleContext *context, void gtk_style_context_invalidate (GtkStyleContext *context) { - GtkStyleContextPrivate *priv; - g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); - priv = context->priv; - - /* Avoid reentrancy */ - if (priv->invalidating_context) - return; - - priv->invalidating_context = TRUE; - - g_hash_table_remove_all (priv->style_data); - priv->current_data = NULL; - - priv->relevant_changes = GTK_CSS_CHANGE_ANY; - - g_signal_emit (context, signals[CHANGED], 0); - - priv->invalidating_context = FALSE; + gtk_style_context_do_invalidate (context, TRUE); } /**