[gtk+] cssnode: Split out the style cache
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] cssnode: Split out the style cache
- Date: Sat, 16 Jan 2016 23:08:28 +0000 (UTC)
commit 5d562b6a2aca6c1d0db93286eb7eb719fe2e3c98
Author: Benjamin Otte <otte redhat com>
Date: Fri Jan 15 23:27:51 2016 +0100
cssnode: Split out the style cache
For now, the split out style cache doesn't cache anything. This is
mostly to make sure that bisections of wrong caching behavior will
bisect down to the commit that actually adds caching.
gtk/Makefile.am | 2 +
gtk/gtkcssnode.c | 123 ++++++++-----------------------------
gtk/gtkcssnodeprivate.h | 2 +
gtk/gtkcssnodestylecache.c | 76 +++++++++++++++++++++++
gtk/gtkcssnodestylecacheprivate.h | 44 +++++++++++++
5 files changed, 151 insertions(+), 96 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 120e245..516f1bb 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -416,6 +416,7 @@ gtk_private_h_sources = \
gtkcssmatcherprivate.h \
gtkcssnodeprivate.h \
gtkcssnodedeclarationprivate.h \
+ gtkcssnodestylecacheprivate.h \
gtkcssnumbervalueprivate.h \
gtkcsspalettevalueprivate.h \
gtkcssparserprivate.h \
@@ -676,6 +677,7 @@ gtk_base_c_sources = \
gtkcssmatcher.c \
gtkcssnode.c \
gtkcssnodedeclaration.c \
+ gtkcssnodestylecache.c \
gtkcssnumbervalue.c \
gtkcsspalettevalue.c \
gtkcssparser.c \
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index a5dda31..1106bdb 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -20,13 +20,13 @@
#include "gtkcssnodeprivate.h"
#include "gtkcssanimatedstyleprivate.h"
+#include "gtkcsssectionprivate.h"
+#include "gtkcssstylepropertyprivate.h"
#include "gtkdebug.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtksettingsprivate.h"
#include "gtktypebuiltins.h"
-#include "gtkcssstylepropertyprivate.h"
-#include "gtkcsssectionprivate.h"
/*
* CSS nodes are the backbone of the GtkStyleContext implementation and
@@ -116,8 +116,6 @@ struct _GtkCssNodeStyleChange {
static guint cssnode_signals[LAST_SIGNAL] = { 0 };
static GParamSpec *cssnode_properties[NUM_PROPERTIES];
-static GQuark quark_global_cache;
-
static GtkStyleProviderPrivate *
gtk_css_node_get_style_provider_or_null (GtkCssNode *cssnode)
{
@@ -285,10 +283,6 @@ gtk_css_node_is_last_child (GtkCssNode *node)
return TRUE;
}
-#define UNPACK_DECLARATION(packed) ((GtkCssNodeDeclaration *) (GPOINTER_TO_SIZE (packed) & ~0x3))
-#define UNPACK_FLAGS(packed) (GPOINTER_TO_SIZE (packed) & 0x3)
-#define PACK(decl, first_child, last_child) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (decl) | ((first_child) ? 0x2
: 0) | ((last_child) ? 0x1 : 0))
-
static gboolean
may_use_global_parent_cache (GtkCssNode *node)
{
@@ -308,109 +302,52 @@ may_use_global_parent_cache (GtkCssNode *node)
static GtkCssStyle *
lookup_in_global_parent_cache (GtkCssNode *node,
- GtkCssStyle *parent,
const GtkCssNodeDeclaration *decl)
{
- GHashTable *cache;
- GtkCssStyle *style;
+ GtkCssNode *parent;
+
+ parent = node->parent;
if (parent == NULL ||
!may_use_global_parent_cache (node))
return NULL;
- cache = g_object_get_qdata (G_OBJECT (parent), quark_global_cache);
- if (cache == NULL)
+ if (parent->cache == NULL)
return NULL;
- style = g_hash_table_lookup (cache,
- PACK (decl,
- gtk_css_node_is_first_child (node),
- gtk_css_node_is_last_child (node)));
-
- return style;
-}
-
-static gboolean
-may_be_stored_in_parent_cache (GtkCssStyle *style)
-{
- GtkCssChange change;
-
- change = gtk_css_static_style_get_change (GTK_CSS_STATIC_STYLE (style));
-
- /* The cache is shared between all children of the parent, so if a
- * style depends on a sibling it is not independant of the child.
- */
- if (change & GTK_CSS_CHANGE_ANY_SIBLING)
- return FALSE;
-
- /* Again, the cache is shared between all children of the parent.
- * If the position is relevant, no child has the same style.
- */
- if (change & (GTK_CSS_CHANGE_NTH_CHILD | GTK_CSS_CHANGE_NTH_LAST_CHILD))
- return FALSE;
-
- return TRUE;
-}
-
-static guint
-gtk_global_parent_cache_hash (gconstpointer item)
-{
- return gtk_css_node_declaration_hash (UNPACK_DECLARATION (item)) << 2
- | UNPACK_FLAGS (item);
-}
-
-static gboolean
-gtk_global_parent_cache_equal (gconstpointer item1,
- gconstpointer item2)
-{
- if (UNPACK_FLAGS (item1) != UNPACK_FLAGS (item2))
- return FALSE;
-
- return gtk_css_node_declaration_equal (UNPACK_DECLARATION (item1),
- UNPACK_DECLARATION (item2));
-}
+ node->cache = gtk_css_node_style_cache_lookup (parent->cache,
+ (GtkCssNodeDeclaration *) decl,
+ gtk_css_node_is_first_child (node),
+ gtk_css_node_is_last_child (node));
+ if (node->cache == NULL)
+ return NULL;
-static void
-gtk_global_parent_cache_free (gpointer item)
-{
- gtk_css_node_declaration_unref (UNPACK_DECLARATION (item));
+ return gtk_css_node_style_cache_get_style (node->cache);
}
static void
store_in_global_parent_cache (GtkCssNode *node,
- GtkCssStyle *parent,
const GtkCssNodeDeclaration *decl,
GtkCssStyle *style)
{
- GHashTable *cache;
+ GtkCssNode *parent;
g_assert (GTK_IS_CSS_STATIC_STYLE (style));
+ parent = node->parent;
+
if (parent == NULL ||
!may_use_global_parent_cache (node))
return;
- if (!may_be_stored_in_parent_cache (style))
- return;
-
- cache = g_object_get_qdata (G_OBJECT (parent), quark_global_cache);
- if (cache == NULL)
- {
- cache = g_hash_table_new_full (gtk_global_parent_cache_hash,
- gtk_global_parent_cache_equal,
- gtk_global_parent_cache_free,
- g_object_unref);
- g_object_set_qdata_full (G_OBJECT (parent),
- quark_global_cache,
- cache,
- (GDestroyNotify) g_hash_table_destroy);
- }
+ if (parent->cache == NULL)
+ parent->cache = gtk_css_node_style_cache_new (parent->style);
- g_hash_table_insert (cache,
- PACK (gtk_css_node_declaration_ref ((GtkCssNodeDeclaration *) decl),
- gtk_css_node_is_first_child (node),
- gtk_css_node_is_last_child (node)),
- g_object_ref (style));
+ node->cache = gtk_css_node_style_cache_insert (parent->cache,
+ (GtkCssNodeDeclaration *) decl,
+ gtk_css_node_is_first_child (node),
+ gtk_css_node_is_last_child (node),
+ style);
}
static GtkCssStyle *
@@ -424,7 +361,7 @@ gtk_css_node_create_style (GtkCssNode *cssnode)
decl = gtk_css_node_get_declaration (cssnode);
parent = cssnode->parent ? cssnode->parent->style : NULL;
- style = lookup_in_global_parent_cache (cssnode, parent, decl);
+ style = lookup_in_global_parent_cache (cssnode, decl);
if (style)
return g_object_ref (style);
@@ -437,7 +374,7 @@ gtk_css_node_create_style (GtkCssNode *cssnode)
NULL,
parent);
- store_in_global_parent_cache (cssnode, parent, decl, style);
+ store_in_global_parent_cache (cssnode, decl, style);
return style;
}
@@ -625,8 +562,6 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- quark_global_cache = g_quark_from_static_string ("gtk-global-cache");
-
object_class->get_property = gtk_css_node_get_property;
object_class->set_property = gtk_css_node_set_property;
object_class->dispose = gtk_css_node_dispose;
@@ -1059,6 +994,8 @@ gtk_css_node_ensure_style (GtkCssNode *cssnode,
if (cssnode->previous_sibling)
gtk_css_node_ensure_style (cssnode->previous_sibling, current_time);
+ g_clear_pointer (&cssnode->cache, gtk_css_node_style_cache_unref);
+
new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
cssnode->pending_changes,
current_time,
@@ -1066,12 +1003,6 @@ gtk_css_node_ensure_style (GtkCssNode *cssnode,
style_changed = gtk_css_node_set_style (cssnode, new_style);
g_object_unref (new_style);
-
- if (!style_changed && (cssnode->pending_changes & GTK_CSS_CHANGE_SOURCE))
- {
- /* clear the global cache if we reuse the same style after the CSS changed */
- g_object_set_qdata (G_OBJECT (cssnode->style), quark_global_cache, NULL);
- }
}
else
{
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 065b8e7..51d6cea 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -19,6 +19,7 @@
#define __GTK_CSS_NODE_PRIVATE_H__
#include "gtkcssnodedeclarationprivate.h"
+#include "gtkcssnodestylecacheprivate.h"
#include "gtkcssstylechangeprivate.h"
#include "gtkbitmaskprivate.h"
#include "gtkcsstypesprivate.h"
@@ -46,6 +47,7 @@ struct _GtkCssNode
GtkCssNodeDeclaration *decl;
GtkCssStyle *style;
+ GtkCssNodeStyleCache *cache; /* cache for children to look up styles */
GtkCssChange pending_changes; /* changes that accumulated since the style was last
computed */
diff --git a/gtk/gtkcssnodestylecache.c b/gtk/gtkcssnodestylecache.c
new file mode 100644
index 0000000..5c4e61d
--- /dev/null
+++ b/gtk/gtkcssnodestylecache.c
@@ -0,0 +1,76 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2015 Benjamin Otte <otte gnome org>
+ *
+ * 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 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/>.
+ */
+
+#include "config.h"
+
+#include "gtkcssnodestylecacheprivate.h"
+
+struct _GtkCssNodeStyleCache {
+ guint ref_count;
+ GtkCssStyle *style;
+ GHashTable *children;
+};
+
+GtkCssNodeStyleCache *
+gtk_css_node_style_cache_new (GtkCssStyle *style)
+{
+ GtkCssNodeStyleCache *result;
+
+ result = g_slice_new0 (GtkCssNodeStyleCache);
+
+ result->ref_count = 1;
+ result->style = g_object_ref (style);
+
+ return result;
+}
+
+void
+gtk_css_node_style_cache_unref (GtkCssNodeStyleCache *cache)
+{
+ cache->ref_count--;
+
+ if (cache->ref_count > 0)
+ return;
+
+ g_object_unref (cache->style);
+}
+
+GtkCssStyle *
+gtk_css_node_style_cache_get_style (GtkCssNodeStyleCache *cache)
+{
+ return cache->style;
+}
+
+GtkCssNodeStyleCache *
+gtk_css_node_style_cache_insert (GtkCssNodeStyleCache *parent,
+ GtkCssNodeDeclaration *decl,
+ gboolean is_first,
+ gboolean is_last,
+ GtkCssStyle *style)
+{
+ return gtk_css_node_style_cache_new (style);
+}
+
+GtkCssNodeStyleCache *
+gtk_css_node_style_cache_lookup (GtkCssNodeStyleCache *parent,
+ GtkCssNodeDeclaration *decl,
+ gboolean is_first,
+ gboolean is_last)
+{
+ return NULL;
+}
+
diff --git a/gtk/gtkcssnodestylecacheprivate.h b/gtk/gtkcssnodestylecacheprivate.h
new file mode 100644
index 0000000..c406fbf
--- /dev/null
+++ b/gtk/gtkcssnodestylecacheprivate.h
@@ -0,0 +1,44 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2016 Benjamin Otte <otte gnome org>
+ *
+ * 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 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/>.
+ */
+
+#ifndef __GTK_CSS_NODE_STYLE_CACHE_PRIVATE_H__
+#define __GTK_CSS_NODE_STYLE_CACHE_PRIVATE_H__
+
+#include "gtkcssstyleprivate.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GtkCssNodeStyleCache GtkCssNodeStyleCache;
+
+GtkCssNodeStyleCache * gtk_css_node_style_cache_new (GtkCssStyle *style);
+void gtk_css_node_style_cache_unref (GtkCssNodeStyleCache *cache);
+
+GtkCssStyle * gtk_css_node_style_cache_get_style (GtkCssNodeStyleCache *cache);
+
+GtkCssNodeStyleCache * gtk_css_node_style_cache_insert (GtkCssNodeStyleCache *parent,
+ GtkCssNodeDeclaration *decl,
+ gboolean is_first,
+ gboolean is_last,
+ GtkCssStyle *style);
+GtkCssNodeStyleCache * gtk_css_node_style_cache_lookup (GtkCssNodeStyleCache *parent,
+ GtkCssNodeDeclaration *decl,
+ gboolean is_first,
+ gboolean is_last);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_NODE_STYLE_CACHE_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]