[gtk] snapshot: Add gtk_snapshot_from_parent
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk] snapshot: Add gtk_snapshot_from_parent
- Date: Wed, 16 Jan 2019 18:24:14 +0000 (UTC)
commit cf1526cca62a956d1605fa6cdcc241e59c039600
Author: Timm Bäder <tbaeder redhat com>
Date: Wed Jan 16 08:30:42 2019 +0100
snapshot: Add gtk_snapshot_from_parent
Most of the time, the GtkSnapshot objects we create while snapshotting
widgets don't end up containing all that many nodes or states in their
respective node or state stack. This undermines the amortized allocation
behavior of the G(Ptr)Array we use for the stacks. So instead, use the
(until now unused) parent_snapshot GtkSnapshot* passed to
gtk_widget_create_render_node and reuse its node and state stack.
We do not avoid allocating a new GtkSnapshot object, but we do avoid
allocating a ton of G(Ptr)Array objects and we also avoid realloc'ing
their storage.
gtk/gtksnapshot.c | 36 ++++++++++++++++++++++++++++++------
gtk/gtksnapshotprivate.h | 4 ++++
gtk/gtkwidget.c | 2 +-
3 files changed, 35 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 3bc18cd4e8..7eb12dd33e 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -162,6 +162,7 @@ gtk_snapshot_new (void)
snapshot = g_object_new (GTK_TYPE_SNAPSHOT, NULL);
+ snapshot->from_parent = FALSE;
snapshot->state_stack = g_array_new (FALSE, TRUE, sizeof (GtkSnapshotState));
g_array_set_clear_func (snapshot->state_stack, (GDestroyNotify)gtk_snapshot_state_clear);
snapshot->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_render_node_unref);
@@ -173,6 +174,24 @@ gtk_snapshot_new (void)
return snapshot;
}
+/* Private. Does the same as _new but does not allocate a NEW
+ * state/node stack. */
+GtkSnapshot *
+gtk_snapshot_new_with_parent (GtkSnapshot *parent_snapshot)
+{
+ GtkSnapshot *snapshot = g_object_new (GTK_TYPE_SNAPSHOT, NULL);
+
+ snapshot->state_stack = parent_snapshot->state_stack;
+ snapshot->nodes = parent_snapshot->nodes;
+ snapshot->from_parent = TRUE;
+
+ gtk_snapshot_push_state (snapshot,
+ 0, 0,
+ gtk_snapshot_collect_default);
+
+ return snapshot;
+}
+
/**
* gtk_snapshot_free_to_node: (skip)
* @snapshot: (transfer full): a #GtkSnapshot
@@ -904,7 +923,8 @@ gtk_snapshot_pop_internal (GtkSnapshot *snapshot)
guint state_index;
GskRenderNode *node;
- if (snapshot->state_stack->len == 0)
+ if (snapshot->state_stack->len == 0 &&
+ !snapshot->from_parent)
{
g_warning ("Too many gtk_snapshot_pop() calls.");
return NULL;
@@ -950,17 +970,21 @@ gtk_snapshot_to_node (GtkSnapshot *snapshot)
GskRenderNode *result;
/* We should have exactly our initial state */
- if (snapshot->state_stack->len > 1)
+ if (snapshot->state_stack->len > 1 &&
+ !snapshot->from_parent)
{
g_warning ("Too many gtk_snapshot_push() calls. %u states remaining.", snapshot->state_stack->len);
}
-
+
result = gtk_snapshot_pop_internal (snapshot);
- g_array_free (snapshot->state_stack, TRUE);
- snapshot->state_stack = NULL;
+ if (!snapshot->from_parent)
+ {
+ g_array_free (snapshot->state_stack, TRUE);
+ g_ptr_array_free (snapshot->nodes, TRUE);
+ }
- g_ptr_array_free (snapshot->nodes, TRUE);
+ snapshot->state_stack = NULL;
snapshot->nodes = NULL;
return result;
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index b54fb4b702..5e554ca85e 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -90,6 +90,8 @@ struct _GdkSnapshot {
GArray *state_stack;
GPtrArray *nodes;
+
+ guint from_parent : 1;
};
struct _GtkSnapshotClass {
@@ -99,6 +101,8 @@ struct _GtkSnapshotClass {
void gtk_snapshot_append_node_internal (GtkSnapshot *snapshot,
GskRenderNode *node);
+GtkSnapshot * gtk_snapshot_new_with_parent (GtkSnapshot *parent_snapshot);
+
G_END_DECLS
#endif /* __GTK_SNAPSHOT_PRIVATE_H__ */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 4fadd96534..7e03bfc987 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -12961,7 +12961,7 @@ gtk_widget_create_render_node (GtkWidget *widget,
if (opacity <= 0.0)
return NULL;
- snapshot = gtk_snapshot_new ();
+ snapshot = gtk_snapshot_new_with_parent (parent_snapshot);
_gtk_widget_get_allocation (widget, &allocation);
gtk_snapshot_push_debug (snapshot,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]