css: Avoid computing change too often
authorMatthias Clasen <mclasen@redhat.com>
Wed, 15 Jan 2020 07:35:21 +0000 (02:35 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 16 Jan 2020 22:03:51 +0000 (17:03 -0500)
Most of the time when styles need to be recreated, the name and classes
of the css node haven't changed. In this case, the change value will not
change either, since we are computing change under the assumption that
name and classes are unchanged.

So don't recompute the change. This avoids the second match we do to
find the superset, cutting down the number of times we consult the
selector tree.

gtk/gtkcssnode.c
gtk/gtkcssstaticstyle.c
gtk/gtkcssstaticstyleprivate.h

index 16faabe0df47e76acdfa5d59bda2e7d798d9df4b..b921b8ba7335d73aca349beacf9eb7961f506d90 100644 (file)
  * if we need to change things. */
 #define GTK_CSS_RADICAL_CHANGE (GTK_CSS_CHANGE_ID | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_SOURCE | GTK_CSS_CHANGE_PARENT_STYLE)
 
+/* When these change, we need to recompute the change flags for the new style
+ * since they may have changed.
+ */
+#define GTK_CSS_CHANGE_NEEDS_RECOMPUTE (GTK_CSS_RADICAL_CHANGE & ~GTK_CSS_CHANGE_PARENT_STYLE)
+
 G_DEFINE_TYPE (GtkCssNode, gtk_css_node, G_TYPE_OBJECT)
 
 enum {
@@ -348,12 +353,14 @@ store_in_global_parent_cache (GtkCssNode                  *node,
 }
 
 static GtkCssStyle *
-gtk_css_node_create_style (GtkCssNode *cssnode)
+gtk_css_node_create_style (GtkCssNode   *cssnode,
+                           GtkCssChange  change)
 {
   const GtkCssNodeDeclaration *decl;
   GtkCssMatcher matcher;
   GtkCssStyle *parent;
   GtkCssStyle *style;
+  GtkCssChange style_change;
 
   decl = gtk_css_node_get_declaration (cssnode);
 
@@ -363,14 +370,26 @@ gtk_css_node_create_style (GtkCssNode *cssnode)
 
   parent = cssnode->parent ? cssnode->parent->style : NULL;
 
+  if (change & GTK_CSS_CHANGE_NEEDS_RECOMPUTE)
+    {
+      /* Need to recompute the change flags */
+      style_change = 0;
+    }
+  else
+    {
+      style_change = gtk_css_static_style_get_change (gtk_css_style_get_static_style (cssnode->style));
+    }
+
   if (gtk_css_node_init_matcher (cssnode, &matcher))
     style = gtk_css_static_style_new_compute (gtk_css_node_get_style_provider (cssnode),
                                               &matcher,
-                                              parent);
+                                              parent,
+                                              style_change);
   else
     style = gtk_css_static_style_new_compute (gtk_css_node_get_style_provider (cssnode),
                                               NULL,
-                                              parent);
+                                              parent,
+                                              style_change);
 
   store_in_global_parent_cache (cssnode, decl, style);
 
@@ -410,7 +429,7 @@ gtk_css_node_real_update_style (GtkCssNode   *cssnode,
   static_style = GTK_CSS_STYLE (gtk_css_style_get_static_style (style));
 
   if (gtk_css_style_needs_recreation (static_style, change))
-    new_static_style = gtk_css_node_create_style (cssnode);
+    new_static_style = gtk_css_node_create_style (cssnode, change);
   else
     new_static_style = g_object_ref (static_style);
 
@@ -429,7 +448,7 @@ gtk_css_node_real_update_style (GtkCssNode   *cssnode,
     }
   else if (static_style != style && (change & GTK_CSS_CHANGE_TIMESTAMP))
     {
-      new_style = gtk_css_animated_style_new_advance ((GtkCssAnimatedStyle *)style,
+      new_style = gtk_css_animated_style_new_advance (GTK_CSS_ANIMATED_STYLE (style),
                                                       static_style,
                                                       timestamp);
     }
index d961731541603babf5e136a7918b573be318b653..2ea6ddb1f8be513b71c1b8bb5898acfc902b9979 100644 (file)
@@ -165,7 +165,8 @@ gtk_css_static_style_get_default (void)
       settings = gtk_settings_get_default ();
       default_style = gtk_css_static_style_new_compute (GTK_STYLE_PROVIDER (settings),
                                                         NULL,
-                                                        NULL);
+                                                        NULL,
+                                                        TRUE);
       g_object_set_data_full (G_OBJECT (settings), I_("gtk-default-style"),
                               default_style, clear_default_style);
     }
@@ -176,11 +177,11 @@ gtk_css_static_style_get_default (void)
 GtkCssStyle *
 gtk_css_static_style_new_compute (GtkStyleProvider    *provider,
                                   const GtkCssMatcher *matcher,
-                                  GtkCssStyle         *parent)
+                                  GtkCssStyle         *parent,
+                                  GtkCssChange         change)
 {
   GtkCssStaticStyle *result;
   GtkCssLookup lookup;
-  GtkCssChange change = GTK_CSS_CHANGE_ANY_SELF | GTK_CSS_CHANGE_ANY_SIBLING | GTK_CSS_CHANGE_ANY_PARENT;
 
   _gtk_css_lookup_init (&lookup);
 
@@ -188,7 +189,7 @@ gtk_css_static_style_new_compute (GtkStyleProvider    *provider,
     gtk_style_provider_lookup (provider,
                                matcher,
                                &lookup,
-                               &change);
+                               change == 0 ? &change : NULL);
 
   result = g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
 
index 7ef2b67a4d082bd3fbaeb8efa4116e5c986bd9e3..81c97bbdc0d367793738e036e94a3413c2af7b20 100644 (file)
@@ -54,7 +54,8 @@ GType                   gtk_css_static_style_get_type           (void) G_GNUC_CO
 GtkCssStyle *           gtk_css_static_style_get_default        (void);
 GtkCssStyle *           gtk_css_static_style_new_compute        (GtkStyleProvider       *provider,
                                                                  const GtkCssMatcher    *matcher,
-                                                                 GtkCssStyle            *parent);
+                                                                 GtkCssStyle            *parent,
+                                                                 GtkCssChange            change);
 
 void                    gtk_css_static_style_compute_value      (GtkCssStaticStyle      *style,
                                                                  GtkStyleProvider       *provider,