[gtk/css-lookup-caching] Cache css lookups



commit 6eeae76c73d9e9b8f3f2d57846302c417c917999
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Feb 7 19:26:01 2020 -0500

    Cache css lookups
    
    Keep the css lookup around as part of GtkCssStaticStyle,
    and reuse it when we know that the css tree hasn't changed
    in ways that require a new lookup or a new style change
    computation.
    
    Quick statistics from clicking around in widget-factory:
       2814 new lookup and new change
       7321 new lookup, reusing change
      26780 reusing lookup and change

 gtk/gtkcsslookup.c             | 22 ++++++++++++++++++++++
 gtk/gtkcsslookupprivate.h      | 16 +++-------------
 gtk/gtkcssnode.c               | 29 ++++++++++++++++++++---------
 gtk/gtkcssstaticstyle.c        | 40 ++++++++++++++++++++++++++--------------
 gtk/gtkcssstaticstyleprivate.h | 19 +++++++++++++++++--
 5 files changed, 88 insertions(+), 38 deletions(-)
---
diff --git a/gtk/gtkcsslookup.c b/gtk/gtkcsslookup.c
index 32cd64265f..ea0613034c 100644
--- a/gtk/gtkcsslookup.c
+++ b/gtk/gtkcsslookup.c
@@ -112,3 +112,25 @@ _gtk_css_lookup_get (GtkCssLookup *lookup,
 
   return NULL;
 }
+
+void
+_gtk_css_lookup_copy (GtkCssLookup *dest,
+                      GtkCssLookup *src)
+{
+  int i;
+
+  _gtk_bitmask_free (dest->set_values);
+  dest->set_values = _gtk_bitmask_copy (src->set_values);
+  g_array_set_size (dest->values, src->values->len);
+  for (i = 0; i < src->values->len; i++)
+    {
+      GtkCssLookupValue *s = &g_array_index (src->values, GtkCssLookupValue, i);
+      GtkCssLookupValue *d = &g_array_index (dest->values, GtkCssLookupValue, i);
+      d->value = gtk_css_value_ref (s->value);
+      d->id = s->id;
+      if (s->section)
+        d->section = gtk_css_section_ref (s->section);
+      else
+        d->section = NULL;
+    }
+}
diff --git a/gtk/gtkcsslookupprivate.h b/gtk/gtkcsslookupprivate.h
index 0dddbdad91..ad85c2ad0e 100644
--- a/gtk/gtkcsslookupprivate.h
+++ b/gtk/gtkcsslookupprivate.h
@@ -28,19 +28,6 @@
 
 G_BEGIN_DECLS
 
-typedef struct _GtkCssLookup GtkCssLookup;
-
-typedef struct {
-  GtkCssSection     *section;
-  GtkCssValue       *value;
-  guint id;
-} GtkCssLookupValue;
-
-struct _GtkCssLookup {
-  GtkBitmask *set_values;
-  GArray *values;
-};
-
 void                    _gtk_css_lookup_init                    (GtkCssLookup               *lookup);
 void                    _gtk_css_lookup_destroy                 (GtkCssLookup               *lookup);
 gboolean                _gtk_css_lookup_is_missing              (const GtkCssLookup         *lookup,
@@ -51,6 +38,9 @@ void                    _gtk_css_lookup_set                     (GtkCssLookup
                                                                  GtkCssValue                *value);
 GtkCssLookupValue *     _gtk_css_lookup_get                     (GtkCssLookup               *lookup,
                                                                  guint                       id);
+void                   _gtk_css_lookup_copy                     (GtkCssLookup               *dest,
+                                                                 GtkCssLookup               *src);
+
 
 static inline const GtkBitmask *
 _gtk_css_lookup_get_set_values (const GtkCssLookup *lookup)
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 4932447955..3101186736 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -372,20 +372,31 @@ gtk_css_node_create_style (GtkCssNode                   *cssnode,
 
   created_styles++;
 
-  if (change & GTK_CSS_CHANGE_NEEDS_RECOMPUTE)
+  /* We don't need to match again unless one of our change flags is set,
+   * or the theme changed. Typically, get here when just the parent style
+   * and the timestamp changed.
+   */
+  if ((change & GTK_CSS_CHANGE_SOURCE) == 0 &&
+      (change & GTK_CSS_CHANGE_NEEDS_RECOMPUTE) == 0 &&
+      GTK_IS_CSS_STATIC_STYLE (cssnode->style) &&
+      (gtk_css_static_style_get_change (GTK_CSS_STATIC_STYLE (cssnode->style)) & change) == 0)
     {
-      /* Need to recompute the change flags */
-      style_change = 0;
+       style = gtk_css_static_style_recompute (GTK_CSS_STATIC_STYLE (cssnode->style),
+                                               gtk_css_node_get_style_provider (cssnode),
+                                               cssnode->parent ? cssnode->parent->style : NULL);
     }
   else
     {
-      style_change = gtk_css_static_style_get_change (gtk_css_style_get_static_style (cssnode->style));
-    }
+      if (change & GTK_CSS_CHANGE_NEEDS_RECOMPUTE)
+        style_change = 0; /* Need to recompute the change flags */
+      else
+        style_change = gtk_css_static_style_get_change (gtk_css_style_get_static_style (cssnode->style));
 
-  style = gtk_css_static_style_new_compute (gtk_css_node_get_style_provider (cssnode),
-                                            filter,
-                                            cssnode,
-                                            style_change);
+      style = gtk_css_static_style_new_compute (gtk_css_node_get_style_provider (cssnode),
+                                                filter,
+                                                cssnode,
+                                                style_change);
+    }
 
   store_in_global_parent_cache (cssnode, decl, style);
 
diff --git a/gtk/gtkcssstaticstyle.c b/gtk/gtkcssstaticstyle.c
index 232c4edabb..780c635849 100644
--- a/gtk/gtkcssstaticstyle.c
+++ b/gtk/gtkcssstaticstyle.c
@@ -326,6 +326,8 @@ gtk_css_static_style_dispose (GObject *object)
       style->sections = NULL;
     }
 
+  _gtk_css_lookup_destroy (&style->lookup);
+
   G_OBJECT_CLASS (gtk_css_static_style_parent_class)->dispose (object);
 }
 
@@ -364,6 +366,7 @@ gtk_css_static_style_class_init (GtkCssStaticStyleClass *klass)
 static void
 gtk_css_static_style_init (GtkCssStaticStyle *style)
 {
+  _gtk_css_lookup_init (&style->lookup);
 }
 
 static void
@@ -1007,6 +1010,23 @@ gtk_css_lookup_resolve (GtkCssLookup      *lookup,
     gtk_css_other_values_new_compute (sstyle, provider, parent_style, lookup);
 }
 
+GtkCssStyle *
+gtk_css_static_style_recompute (GtkCssStaticStyle *style,
+                                GtkStyleProvider  *provider,
+                                GtkCssStyle       *parent)
+{
+  GtkCssStaticStyle *result;
+
+  result = g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
+
+  _gtk_css_lookup_copy (&result->lookup, &style->lookup);
+  result->change = style->change;
+
+  gtk_css_lookup_resolve (&result->lookup, provider, result, parent);
+
+  return GTK_CSS_STYLE (result);
+}
+
 GtkCssStyle *
 gtk_css_static_style_new_compute (GtkStyleProvider             *provider,
                                   const GtkCountingBloomFilter *filter,
@@ -1014,33 +1034,25 @@ gtk_css_static_style_new_compute (GtkStyleProvider             *provider,
                                   GtkCssChange                  change)
 {
   GtkCssStaticStyle *result;
-  GtkCssLookup lookup;
-  GtkCssNode *parent;
+  GtkCssStyle *parent;
 
-  _gtk_css_lookup_init (&lookup);
+  result = g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
 
   if (node)
     gtk_style_provider_lookup (provider,
                                filter,
                                node,
-                               &lookup,
+                               &result->lookup,
                                change == 0 ? &change : NULL);
 
-  result = g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
-
   result->change = change;
 
-  if (node)
-    parent = gtk_css_node_get_parent (node);
+  if (node && gtk_css_node_get_parent (node))
+    parent = gtk_css_node_get_style (gtk_css_node_get_parent (node));
   else
     parent = NULL;
 
-  gtk_css_lookup_resolve (&lookup,
-                          provider,
-                          result,
-                          parent ? gtk_css_node_get_style (parent) : NULL);
-
-  _gtk_css_lookup_destroy (&lookup);
+  gtk_css_lookup_resolve (&result->lookup, provider, result, parent);
 
   return GTK_CSS_STYLE (result);
 }
diff --git a/gtk/gtkcssstaticstyleprivate.h b/gtk/gtkcssstaticstyleprivate.h
index 04654ac070..c563f8074b 100644
--- a/gtk/gtkcssstaticstyleprivate.h
+++ b/gtk/gtkcssstaticstyleprivate.h
@@ -26,6 +26,19 @@
 
 G_BEGIN_DECLS
 
+typedef struct _GtkCssLookup GtkCssLookup;
+
+typedef struct {
+  GtkCssSection     *section;
+  GtkCssValue       *value;
+  guint id;
+} GtkCssLookupValue;
+
+struct _GtkCssLookup {
+  GtkBitmask *set_values;
+  GArray *values;
+};
+
 #define GTK_TYPE_CSS_STATIC_STYLE           (gtk_css_static_style_get_type ())
 #define GTK_CSS_STATIC_STYLE(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_STATIC_STYLE, 
GtkCssStaticStyle))
 #define GTK_CSS_STATIC_STYLE_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_STATIC_STYLE, 
GtkCssStaticStyleClass))
@@ -35,13 +48,12 @@ G_BEGIN_DECLS
 
 typedef struct _GtkCssStaticStyleClass      GtkCssStaticStyleClass;
 
-
 struct _GtkCssStaticStyle
 {
   GtkCssStyle parent;
 
+  GtkCssLookup           lookup;
   GPtrArray             *sections;             /* sections the values are defined in */
-
   GtkCssChange           change;               /* change as returned by value lookup */
 };
 
@@ -57,6 +69,9 @@ GtkCssStyle *           gtk_css_static_style_new_compute        (GtkStyleProvide
                                                                  const GtkCountingBloomFilter   *filter,
                                                                  GtkCssNode                     *node,
                                                                  GtkCssChange                    change);
+GtkCssStyle *           gtk_css_static_style_recompute          (GtkCssStaticStyle              *style,
+                                                                 GtkStyleProvider               *provider,
+                                                                 GtkCssStyle                    *parent);
 GtkCssChange            gtk_css_static_style_get_change         (GtkCssStaticStyle              *style);
 
 G_END_DECLS


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