[gtk/wip/otte/css: 3150/3150] css: Add fast-path for parent selector matching



commit c1751367ee0c9eb324b433b861afd974b82db409
Author: Benjamin Otte <otte redhat com>
Date:   Sun Jan 26 04:37:17 2020 +0100

    css: Add fast-path for parent selector matching
    
    Add a fast path for parent selector matching that uses a bloom filter to
    quickly discard selectors that can't possibly match.
    
    This also changes what we consider a radical change:
    Because we can quickly discard selectors for radical changes in parent
    nodes now, we do just that.
    And because we consider the change in the parent radical already, we do
    an expensive recalculation anyway.
    
    This avoids a lot of potential matches.
    For example, a "button:hover label" type selector will not match a label
    that is not inside a button and the change for the label will then not
    include the GTK_CSS_CHANGE_PARENT_HOVER flag.
    
    Keep in mind that we match using a bloom filter, so we might
    accidentally include too many selectors when hash/bucket collisions
    occur. This will increase matching time and potentially return change
    flags that aren't relevant, but that's not a correctness problem, it
    just increases performance.
    
    The idea for this change is taken from browsers, in particular WebKit.

 gtk/gtkcountingbloomfilterprivate.h | 158 ++++++++++++++++++++++++++++++++++++
 gtk/gtkcssnode.c                    |  59 +++++++++-----
 gtk/gtkcssnodedeclaration.c         |  34 ++++++++
 gtk/gtkcssnodedeclarationprivate.h  |   6 ++
 gtk/gtkcssnodeprivate.h             |   2 +
 gtk/gtkcssprovider.c                |  11 +--
 gtk/gtkcssselector.c                |  46 ++++++++++-
 gtk/gtkcssselectorprivate.h         |   2 +
 gtk/gtkcssstaticstyle.c             |  10 ++-
 gtk/gtkcssstaticstyleprivate.h      |  27 +++---
 gtk/gtkcsstransientnode.c           |  11 +--
 gtk/gtkstylecascade.c               |  11 +--
 gtk/gtkstyleprovider.c              |  11 +--
 gtk/gtkstyleproviderprivate.h       |   3 +
 14 files changed, 334 insertions(+), 57 deletions(-)
---
diff --git a/gtk/gtkcountingbloomfilterprivate.h b/gtk/gtkcountingbloomfilterprivate.h
new file mode 100644
index 0000000000..9151901d75
--- /dev/null
+++ b/gtk/gtkcountingbloomfilterprivate.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright © 2020 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_COUNTING_BLOOM_FILTER_PRIVATE_H__
+#define __GTK_COUNTING_BLOOM_FILTER_PRIVATE_H__
+
+#include <glib.h>
+
+
+G_BEGIN_DECLS
+
+/*
+ * SECTION:gtkcountingbloomfilter
+ * @Short_description: A counting bloom filter
+ * @Title: GtkCountingBloomFilter
+ * @See_also: https://en.wikipedia.org/wiki/Bloom_filter,
+ *            https://en.wikipedia.org/wiki/Counting_Bloom_filter
+ *
+ * This implements a counting bloom filter. A bloom filter is a space-efficient
+ * probabilistic data structure that is used to test whether an element may be
+ * a member of a set.  
+ * The Wikipedia links provide a lot more details into how and why this data
+ * structure works and when to use it.
+ *
+ * This implementation is based on similar implementations in web browsers, because it's
+ * original use case is the same: Making CSS lookups fast.
+ *
+ * As such, the number of bits is hardcoded to 12 and the elements in the set
+ * are 16bit hash values.  
+ * It is possible to use 32bit hash values or a different number of bits, should this
+ * be considered useful.
+ */
+
+/* The number of bits from the hash we care about */
+#define GTK_COUNTING_BLOOM_FILTER_BITS (12)
+
+/* The necessary size of the filter */
+#define GTK_COUNTING_BLOOM_FILTER_SIZE (1 << GTK_COUNTING_BLOOM_FILTER_BITS)
+
+typedef struct _GtkCountingBloomFilter GtkCountingBloomFilter;
+
+struct _GtkCountingBloomFilter
+{
+  guint8        buckets[GTK_COUNTING_BLOOM_FILTER_SIZE];
+};
+
+static inline void      gtk_counting_bloom_filter_add           (GtkCountingBloomFilter         *self,
+                                                                 guint16                         hash);
+static inline void      gtk_counting_bloom_filter_remove        (GtkCountingBloomFilter         *self,
+                                                                 guint16                         hash);
+static inline gboolean  gtk_counting_bloom_filter_may_contain   (const GtkCountingBloomFilter   *self,
+                                                                 guint16                         hash);
+
+
+/*
+ * GTK_COUNTING_BLOOM_FILTER_INIT:
+ *
+ * Initialize the bloom filter. As bloom filters are always stack-allocated,
+ * initialization should happen when defining them, like:
+ * ```c
+ * GtkCountingBloomFilter filter = GTK_COUNTING_BLOOM_FILTER_INIT;
+ * ```
+ *
+ * The filter does not need to be freed.
+ */
+#define GTK_COUNTING_BLOOM_FILTER_INIT { 0, }
+
+/*
+ * gtk_counting_bloom_filter_add:
+ * @self: a #GtkCountingBloomFilter
+ * @hash: a hash value to add to the filter
+ *
+ * Adds the hash value to the filter.
+ *
+ * If the same hash value gets added multiple times, it will
+ * be considered as contained in the hash until it has been
+ * removed as many times.
+ **/
+static inline void
+gtk_counting_bloom_filter_add (GtkCountingBloomFilter *self,
+                               guint16                 hash)
+{
+  guint16 bucket = hash % GTK_COUNTING_BLOOM_FILTER_SIZE;
+
+  if (self->buckets[bucket] == 255)
+    return;
+
+  self->buckets[bucket]++;
+}
+
+/*
+ * gtk_counting_bloom_filter_remove:
+ * @self: a #GtkCountingBloomFilter
+ * @hash: a hash value to remove from the filter
+ *
+ * Removes a hash value from the filter that has previously
+ * been added via gtk_counting_bloom_filter_add().
+ **/
+static inline void
+gtk_counting_bloom_filter_remove (GtkCountingBloomFilter *self,
+                                  guint16                 hash)
+{
+  guint16 bucket = hash % GTK_COUNTING_BLOOM_FILTER_SIZE;
+
+  if (self->buckets[bucket] == 255)
+    return;
+
+  g_assert (self->buckets[bucket] > 0);
+
+  self->buckets[bucket]--;
+}
+
+/*
+ * gtk_counting_bloom_filter_may_contain:
+ * @self: a #GtkCountingBloomFilter
+ * @hash: the hash value to check
+ *
+ * Checks if @hash may be contained in @self.
+ *
+ * A return value of %FALSE means that @hash is definitely not part
+ * of @self.
+ *
+ * A return value of %TRUE means that @hash may or may not have been
+ * added to @self. In that case a different method must be used to
+ * confirm that @hash is indeed part of the set.
+ *
+ * Returns: %FALSE if @hash is not part of @self.
+ **/
+static inline gboolean
+gtk_counting_bloom_filter_may_contain (const GtkCountingBloomFilter *self,
+                                       guint16                       hash)
+{
+  guint16 bucket = hash % GTK_COUNTING_BLOOM_FILTER_SIZE;
+
+  return self->buckets[bucket] != 0;
+}
+
+
+G_END_DECLS
+
+
+#endif /* __GTK_COUNTING_BLOOM_FILTER_PRIVATE_H_ */
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 013e9a26f5..ab52c2bcd3 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -87,7 +87,9 @@
 
 /* When these change we do a full restyling. Otherwise we try to figure out
  * 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)
+#define GTK_CSS_RADICAL_CHANGE (GTK_CSS_CHANGE_ID | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS | \
+                                GTK_CSS_CHANGE_PARENT_ID | GTK_CSS_CHANGE_PARENT_NAME | 
GTK_CSS_CHANGE_PARENT_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.
@@ -354,8 +356,9 @@ store_in_global_parent_cache (GtkCssNode                  *node,
 }
 
 static GtkCssStyle *
-gtk_css_node_create_style (GtkCssNode   *cssnode,
-                           GtkCssChange  change)
+gtk_css_node_create_style (GtkCssNode                   *cssnode,
+                           const GtkCountingBloomFilter *filter,
+                           GtkCssChange                  change)
 {
   const GtkCssNodeDeclaration *decl;
   GtkCssStyle *style;
@@ -380,6 +383,7 @@ gtk_css_node_create_style (GtkCssNode   *cssnode,
     }
 
   style = gtk_css_static_style_new_compute (gtk_css_node_get_style_provider (cssnode),
+                                            filter,
                                             cssnode,
                                             style_change);
 
@@ -411,17 +415,18 @@ gtk_css_style_needs_recreation (GtkCssStyle  *style,
 }
 
 static GtkCssStyle *
-gtk_css_node_real_update_style (GtkCssNode   *cssnode,
-                                GtkCssChange  change,
-                                gint64        timestamp,
-                                GtkCssStyle  *style)
+gtk_css_node_real_update_style (GtkCssNode                   *cssnode,
+                                const GtkCountingBloomFilter *filter,
+                                GtkCssChange                  change,
+                                gint64                        timestamp,
+                                GtkCssStyle                  *style)
 {
   GtkCssStyle *static_style, *new_static_style, *new_style;
 
   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, change);
+    new_static_style = gtk_css_node_create_style (cssnode, filter, change);
   else
     new_static_style = g_object_ref (static_style);
 
@@ -950,8 +955,9 @@ gtk_css_node_needs_new_style (GtkCssNode *cssnode)
 }
 
 static void
-gtk_css_node_ensure_style (GtkCssNode *cssnode,
-                           gint64      current_time)
+gtk_css_node_ensure_style (GtkCssNode                   *cssnode,
+                           const GtkCountingBloomFilter *filter,
+                           gint64                        current_time)
 {
   gboolean style_changed;
 
@@ -959,18 +965,19 @@ gtk_css_node_ensure_style (GtkCssNode *cssnode,
     return;
 
   if (cssnode->parent)
-    gtk_css_node_ensure_style (cssnode->parent, current_time);
+    gtk_css_node_ensure_style (cssnode->parent, filter, current_time);
 
   if (cssnode->style_is_invalid)
     {
       GtkCssStyle *new_style;
 
       if (cssnode->previous_sibling)
-        gtk_css_node_ensure_style (cssnode->previous_sibling, current_time);
+        gtk_css_node_ensure_style (cssnode->previous_sibling, filter, current_time);
 
       g_clear_pointer (&cssnode->cache, gtk_css_node_style_cache_unref);
 
       new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
+                                                                  filter,
                                                                   cssnode->pending_changes,
                                                                   current_time,
                                                                   cssnode->style);
@@ -996,7 +1003,7 @@ gtk_css_node_get_style (GtkCssNode *cssnode)
     {
       gint64 timestamp = gtk_css_node_get_timestamp (cssnode);
 
-      gtk_css_node_ensure_style (cssnode, timestamp);
+      gtk_css_node_ensure_style (cssnode, NULL, timestamp);
     }
 
   return cssnode->style;
@@ -1300,15 +1307,17 @@ gtk_css_node_invalidate (GtkCssNode   *cssnode,
 }
 
 static void
-gtk_css_node_validate_internal (GtkCssNode *cssnode,
-                                gint64      timestamp)
+gtk_css_node_validate_internal (GtkCssNode             *cssnode,
+                                GtkCountingBloomFilter *filter,
+                                gint64                  timestamp)
 {
   GtkCssNode *child;
+  gboolean bloomed = FALSE;
 
   if (!cssnode->invalid)
     return;
 
-  gtk_css_node_ensure_style (cssnode, timestamp);
+  gtk_css_node_ensure_style (cssnode, filter, timestamp);
 
   /* need to set to FALSE then to TRUE here to make it chain up */
   gtk_css_node_set_invalid (cssnode, FALSE);
@@ -1321,20 +1330,32 @@ gtk_css_node_validate_internal (GtkCssNode *cssnode,
        child;
        child = gtk_css_node_get_next_sibling (child))
     {
-      if (child->visible)
-        gtk_css_node_validate_internal (child, timestamp);
+      if (!child->visible)
+        continue;
+
+      if (!bloomed)
+        {
+          gtk_css_node_declaration_add_bloom_hashes (cssnode->decl, filter);
+          bloomed = TRUE;
+        }
+
+      gtk_css_node_validate_internal (child, filter, timestamp);
     }
+
+  if (bloomed)
+    gtk_css_node_declaration_remove_bloom_hashes (cssnode->decl, filter);
 }
 
 void
 gtk_css_node_validate (GtkCssNode *cssnode)
 {
+  GtkCountingBloomFilter filter = GTK_COUNTING_BLOOM_FILTER_INIT;
   gint64 timestamp;
   gint64 before = g_get_monotonic_time ();
 
   timestamp = gtk_css_node_get_timestamp (cssnode);
 
-  gtk_css_node_validate_internal (cssnode, timestamp);
+  gtk_css_node_validate_internal (cssnode, &filter, timestamp);
 
   if (cssnode->parent == NULL)
     {
diff --git a/gtk/gtkcssnodedeclaration.c b/gtk/gtkcssnodedeclaration.c
index 4f9bffd8b3..bcd757e5d4 100644
--- a/gtk/gtkcssnodedeclaration.c
+++ b/gtk/gtkcssnodedeclaration.c
@@ -312,6 +312,40 @@ gtk_css_node_declaration_get_classes (const GtkCssNodeDeclaration *decl,
   return decl->classes;
 }
 
+void
+gtk_css_node_declaration_add_bloom_hashes (const GtkCssNodeDeclaration *decl,
+                                           GtkCountingBloomFilter      *filter)
+{
+  guint i;
+
+  if (decl->name)
+    gtk_counting_bloom_filter_add (filter, gtk_css_hash_name (decl->name));
+  if (decl->id)
+    gtk_counting_bloom_filter_add (filter, gtk_css_hash_id (decl->id));
+
+  for (i = 0; i < decl->n_classes; i++)
+    {
+      gtk_counting_bloom_filter_add (filter, gtk_css_hash_class (decl->classes[i]));
+    }
+}
+
+void
+gtk_css_node_declaration_remove_bloom_hashes (const GtkCssNodeDeclaration *decl,
+                                              GtkCountingBloomFilter      *filter)
+{
+  guint i;
+
+  if (decl->name)
+    gtk_counting_bloom_filter_remove (filter, gtk_css_hash_name (decl->name));
+  if (decl->id)
+    gtk_counting_bloom_filter_remove (filter, gtk_css_hash_id (decl->id));
+
+  for (i = 0; i < decl->n_classes; i++)
+    {
+      gtk_counting_bloom_filter_remove (filter, gtk_css_hash_class (decl->classes[i]));
+    }
+}
+
 guint
 gtk_css_node_declaration_hash (gconstpointer elem)
 {
diff --git a/gtk/gtkcssnodedeclarationprivate.h b/gtk/gtkcssnodedeclarationprivate.h
index d0dd6e43fa..663f713846 100644
--- a/gtk/gtkcssnodedeclarationprivate.h
+++ b/gtk/gtkcssnodedeclarationprivate.h
@@ -18,6 +18,7 @@
 #ifndef __GTK_CSS_NODE_DECLARATION_PRIVATE_H__
 #define __GTK_CSS_NODE_DECLARATION_PRIVATE_H__
 
+#include "gtkcountingbloomfilterprivate.h"
 #include "gtkcsstypesprivate.h"
 #include "gtkenums.h"
 
@@ -47,6 +48,11 @@ gboolean                gtk_css_node_declaration_has_class              (const G
 const GQuark *          gtk_css_node_declaration_get_classes            (const GtkCssNodeDeclaration   *decl,
                                                                          guint                         
*n_classes);
 
+void                    gtk_css_node_declaration_add_bloom_hashes       (const GtkCssNodeDeclaration   *decl,
+                                                                         GtkCountingBloomFilter        
*filter);
+void                    gtk_css_node_declaration_remove_bloom_hashes    (const GtkCssNodeDeclaration   *decl,
+                                                                         GtkCountingBloomFilter        
*filter);
+
 guint                   gtk_css_node_declaration_hash                   (gconstpointer                  
elem);
 gboolean                gtk_css_node_declaration_equal                  (gconstpointer                  
elem1,
                                                                          gconstpointer                  
elem2);
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 0dab08ab72..ae07da00cb 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -18,6 +18,7 @@
 #ifndef __GTK_CSS_NODE_PRIVATE_H__
 #define __GTK_CSS_NODE_PRIVATE_H__
 
+#include "gtkcountingbloomfilterprivate.h"
 #include "gtkcssnodedeclarationprivate.h"
 #include "gtkcssnodestylecacheprivate.h"
 #include "gtkcssstylechangeprivate.h"
@@ -81,6 +82,7 @@ struct _GtkCssNodeClass
   /* get frame clock or NULL (only relevant for root node) */
   GdkFrameClock *       (* get_frame_clock)             (GtkCssNode            *cssnode);
   GtkCssStyle *         (* update_style)                (GtkCssNode            *cssnode,
+                                                         const GtkCountingBloomFilter *filter,
                                                          GtkCssChange           pending_changes,
                                                          gint64                 timestamp,
                                                          GtkCssStyle           *old_style);
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 7a70dc0adb..9e4dedb980 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -406,10 +406,11 @@ gtk_css_style_provider_get_keyframes (GtkStyleProvider *provider,
 }
 
 static void
-gtk_css_style_provider_lookup (GtkStyleProvider    *provider,
-                               GtkCssNode          *node,
-                               GtkCssLookup        *lookup,
-                               GtkCssChange        *change)
+gtk_css_style_provider_lookup (GtkStyleProvider             *provider,
+                               const GtkCountingBloomFilter *filter,
+                               GtkCssNode                   *node,
+                               GtkCssLookup                 *lookup,
+                               GtkCssChange                 *change)
 {
   GtkCssProvider *css_provider = GTK_CSS_PROVIDER (provider);
   GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (css_provider);
@@ -427,7 +428,7 @@ gtk_css_style_provider_lookup (GtkStyleProvider    *provider,
       if (ruleset->styles == NULL)
         continue;
 
-      if (!gtk_css_selector_matches_radical (ruleset->selector, node))
+      if (!gtk_css_selector_matches_radical (ruleset->selector, filter, node))
         continue;
 
       if (change)
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index 69c821b8c4..0a948a6e12 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -1632,13 +1632,50 @@ gtk_css_selector_foreach_match (const GtkCssSelector *selector,
   return gtk_css_selector_foreach (selector, node, gtk_css_selector_foreach_match, NULL);
 }
 
+static gboolean
+gtk_css_selector_matches_bloom (const GtkCssSelector         *selector,
+                                const GtkCountingBloomFilter *filter)
+{
+  gboolean skip_all = FALSE;
+
+  for (;
+       selector;
+       selector = gtk_css_selector_previous (selector))
+    {
+      switch (selector->class->category)
+        {
+          case GTK_CSS_SELECTOR_CATEGORY_SIMPLE:
+            break;
+          case GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL:
+            if (skip_all)
+              break;
+            if (!gtk_counting_bloom_filter_may_contain (filter,
+                                                        selector->class->hash_one (selector)))
+              return FALSE;
+            break;
+          case GTK_CSS_SELECTOR_CATEGORY_PARENT:
+            skip_all = FALSE;
+            break;
+          case GTK_CSS_SELECTOR_CATEGORY_SIBLING:
+            skip_all = TRUE;
+            break;
+          default:
+            g_assert_not_reached ();
+            return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
 /* The code for determining matches assumes that the name, id and classes
  * of a node remain unchanged, and anything else can change. This needs to
  * be kept in sync with the definition of 'radical change' in gtkcssnode.c.
  */
 gboolean
-gtk_css_selector_matches_radical (const GtkCssSelector   *selector,
-                                  GtkCssNode             *node)
+gtk_css_selector_matches_radical (const GtkCssSelector         *selector,
+                                  const GtkCountingBloomFilter *filter,
+                                  GtkCssNode                   *node)
 {
   for (;
        selector;
@@ -1654,7 +1691,10 @@ gtk_css_selector_matches_radical (const GtkCssSelector   *selector,
             break;
           case GTK_CSS_SELECTOR_CATEGORY_PARENT:
           case GTK_CSS_SELECTOR_CATEGORY_SIBLING:
-            return TRUE;
+            if (filter)
+              return gtk_css_selector_matches_bloom (selector, filter);
+            else
+              return TRUE;
           default:
             g_assert_not_reached ();
             return FALSE;
diff --git a/gtk/gtkcssselectorprivate.h b/gtk/gtkcssselectorprivate.h
index b70267f6c0..d2896484e2 100644
--- a/gtk/gtkcssselectorprivate.h
+++ b/gtk/gtkcssselectorprivate.h
@@ -18,6 +18,7 @@
 #ifndef __GTK_CSS_SELECTOR_PRIVATE_H__
 #define __GTK_CSS_SELECTOR_PRIVATE_H__
 
+#include "gtk/gtkcountingbloomfilterprivate.h"
 #include "gtk/gtkcsstypesprivate.h"
 #include "gtk/gtkcssparserprivate.h"
 
@@ -33,6 +34,7 @@ void              _gtk_css_selector_print           (const GtkCssSelector   *sel
                                                      GString                *str);
 
 gboolean          gtk_css_selector_matches_radical  (const GtkCssSelector   *selector,
+                                                     const GtkCountingBloomFilter *filter,
                                                      GtkCssNode             *node);
 gboolean          gtk_css_selector_matches          (const GtkCssSelector   *selector,
                                                     GtkCssNode             *node);
diff --git a/gtk/gtkcssstaticstyle.c b/gtk/gtkcssstaticstyle.c
index bbae7098b4..6666128036 100644
--- a/gtk/gtkcssstaticstyle.c
+++ b/gtk/gtkcssstaticstyle.c
@@ -161,10 +161,12 @@ gtk_css_static_style_get_default (void)
    */
   if (default_style == NULL)
     {
+      GtkCountingBloomFilter filter = GTK_COUNTING_BLOOM_FILTER_INIT;
       GtkSettings *settings;
 
       settings = gtk_settings_get_default ();
       default_style = gtk_css_static_style_new_compute (GTK_STYLE_PROVIDER (settings),
+                                                        &filter,
                                                         NULL,
                                                         0);
       g_object_set_data_full (G_OBJECT (settings), I_("gtk-default-style"),
@@ -175,9 +177,10 @@ gtk_css_static_style_get_default (void)
 }
 
 GtkCssStyle *
-gtk_css_static_style_new_compute (GtkStyleProvider    *provider,
-                                  GtkCssNode          *node,
-                                  GtkCssChange         change)
+gtk_css_static_style_new_compute (GtkStyleProvider             *provider,
+                                  const GtkCountingBloomFilter *filter,
+                                  GtkCssNode                   *node,
+                                  GtkCssChange                  change)
 {
   GtkCssStaticStyle *result;
   GtkCssLookup lookup;
@@ -187,6 +190,7 @@ gtk_css_static_style_new_compute (GtkStyleProvider    *provider,
 
   if (node)
     gtk_style_provider_lookup (provider,
+                               filter,
                                node,
                                &lookup,
                                change == 0 ? &change : NULL);
diff --git a/gtk/gtkcssstaticstyleprivate.h b/gtk/gtkcssstaticstyleprivate.h
index 1073f7bb0a..8c1acf11b2 100644
--- a/gtk/gtkcssstaticstyleprivate.h
+++ b/gtk/gtkcssstaticstyleprivate.h
@@ -22,6 +22,8 @@
 
 #include "gtk/gtkcssstyleprivate.h"
 
+#include "gtk/gtkcountingbloomfilterprivate.h"
+
 G_BEGIN_DECLS
 
 #define GTK_TYPE_CSS_STATIC_STYLE           (gtk_css_static_style_get_type ())
@@ -51,18 +53,19 @@ struct _GtkCssStaticStyleClass
 GType                   gtk_css_static_style_get_type           (void) G_GNUC_CONST;
 
 GtkCssStyle *           gtk_css_static_style_get_default        (void);
-GtkCssStyle *           gtk_css_static_style_new_compute        (GtkStyleProvider       *provider,
-                                                                 GtkCssNode             *node,
-                                                                 GtkCssChange            change);
-
-void                    gtk_css_static_style_compute_value      (GtkCssStaticStyle      *style,
-                                                                 GtkStyleProvider       *provider,
-                                                                 GtkCssStyle            *parent_style,
-                                                                 guint                   id,
-                                                                 GtkCssValue            *specified,
-                                                                 GtkCssSection          *section);
-
-GtkCssChange            gtk_css_static_style_get_change         (GtkCssStaticStyle      *style);
+GtkCssStyle *           gtk_css_static_style_new_compute        (GtkStyleProvider               *provider,
+                                                                 const GtkCountingBloomFilter   *filter,
+                                                                 GtkCssNode                     *node,
+                                                                 GtkCssChange                    change);
+
+void                    gtk_css_static_style_compute_value      (GtkCssStaticStyle              *style,
+                                                                 GtkStyleProvider               *provider,
+                                                                 GtkCssStyle                    
*parent_style,
+                                                                 guint                           id,
+                                                                 GtkCssValue                    *specified,
+                                                                 GtkCssSection                  *section);
+
+GtkCssChange            gtk_css_static_style_get_change         (GtkCssStaticStyle              *style);
 
 G_END_DECLS
 
diff --git a/gtk/gtkcsstransientnode.c b/gtk/gtkcsstransientnode.c
index 218358005d..5c8373c862 100644
--- a/gtk/gtkcsstransientnode.c
+++ b/gtk/gtkcsstransientnode.c
@@ -23,13 +23,14 @@
 G_DEFINE_TYPE (GtkCssTransientNode, gtk_css_transient_node, GTK_TYPE_CSS_NODE)
 
 static GtkCssStyle *
-gtk_css_transient_node_update_style (GtkCssNode   *cssnode,
-                                     GtkCssChange  change,
-                                     gint64        timestamp,
-                                     GtkCssStyle  *style)
+gtk_css_transient_node_update_style (GtkCssNode                   *cssnode,
+                                     const GtkCountingBloomFilter *filter,
+                                     GtkCssChange                  change,
+                                     gint64                        timestamp,
+                                     GtkCssStyle                  *style)
 {
   /* This should get rid of animations */
-  return GTK_CSS_NODE_CLASS (gtk_css_transient_node_parent_class)->update_style (cssnode, change, 0, style);
+  return GTK_CSS_NODE_CLASS (gtk_css_transient_node_parent_class)->update_style (cssnode, filter, change, 0, 
style);
 }
 
 static void
diff --git a/gtk/gtkstylecascade.c b/gtk/gtkstylecascade.c
index 1bc60e12be..1871b7073e 100644
--- a/gtk/gtkstylecascade.c
+++ b/gtk/gtkstylecascade.c
@@ -179,10 +179,11 @@ gtk_style_cascade_get_keyframes (GtkStyleProvider *provider,
 }
 
 static void
-gtk_style_cascade_lookup (GtkStyleProvider    *provider,
-                          GtkCssNode          *node,
-                          GtkCssLookup        *lookup,
-                          GtkCssChange        *change)
+gtk_style_cascade_lookup (GtkStyleProvider             *provider,
+                          const GtkCountingBloomFilter *filter,
+                          GtkCssNode                   *node,
+                          GtkCssLookup                 *lookup,
+                          GtkCssChange                 *change)
 {
   GtkStyleCascade *cascade = GTK_STYLE_CASCADE (provider);
   GtkStyleCascadeIter iter;
@@ -193,7 +194,7 @@ gtk_style_cascade_lookup (GtkStyleProvider    *provider,
        item;
        item = gtk_style_cascade_iter_next (cascade, &iter))
     {
-      gtk_style_provider_lookup (item, node, lookup,
+      gtk_style_provider_lookup (item, filter, node, lookup,
                                  change ? &iter_change : NULL);
       if (change)
         *change |= iter_change;
diff --git a/gtk/gtkstyleprovider.c b/gtk/gtkstyleprovider.c
index 6dd380b95c..4bcd241054 100644
--- a/gtk/gtkstyleprovider.c
+++ b/gtk/gtkstyleprovider.c
@@ -92,10 +92,11 @@ gtk_style_provider_get_keyframes (GtkStyleProvider *provider,
 }
 
 void
-gtk_style_provider_lookup (GtkStyleProvider *provider,
-                           GtkCssNode       *node,
-                           GtkCssLookup     *lookup,
-                           GtkCssChange     *out_change)
+gtk_style_provider_lookup (GtkStyleProvider             *provider,
+                           const GtkCountingBloomFilter *filter,
+                           GtkCssNode                   *node,
+                           GtkCssLookup                 *lookup,
+                           GtkCssChange                 *out_change)
 {
   GtkStyleProviderInterface *iface;
 
@@ -111,7 +112,7 @@ gtk_style_provider_lookup (GtkStyleProvider *provider,
   if (!iface->lookup)
     return;
 
-  iface->lookup (provider, node, lookup, out_change);
+  iface->lookup (provider, filter, node, lookup, out_change);
 }
 
 void
diff --git a/gtk/gtkstyleproviderprivate.h b/gtk/gtkstyleproviderprivate.h
index 2cdfbed16b..5ee16e3d00 100644
--- a/gtk/gtkstyleproviderprivate.h
+++ b/gtk/gtkstyleproviderprivate.h
@@ -19,6 +19,7 @@
 #define __GTK_STYLE_PROVIDER_PRIVATE_H__
 
 #include <glib-object.h>
+#include "gtk/gtkcountingbloomfilterprivate.h"
 #include "gtk/gtkcsskeyframesprivate.h"
 #include "gtk/gtkcsslookupprivate.h"
 #include "gtk/gtkcssnodeprivate.h"
@@ -42,6 +43,7 @@ struct _GtkStyleProviderInterface
                                                  const char              *name);
   int                   (* get_scale)           (GtkStyleProvider        *provider);
   void                  (* lookup)              (GtkStyleProvider        *provider,
+                                                 const GtkCountingBloomFilter *filter,
                                                  GtkCssNode              *node,
                                                  GtkCssLookup            *lookup,
                                                  GtkCssChange            *out_change);
@@ -59,6 +61,7 @@ GtkCssKeyframes *       gtk_style_provider_get_keyframes         (GtkStyleProvid
                                                                   const char              *name);
 int                     gtk_style_provider_get_scale             (GtkStyleProvider        *provider);
 void                    gtk_style_provider_lookup                (GtkStyleProvider        *provider,
+                                                                  const GtkCountingBloomFilter *filter,
                                                                   GtkCssNode              *node,
                                                                   GtkCssLookup            *lookup,
                                                                   GtkCssChange            *out_change);


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