summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2017-01-11 11:41:46 +0100
committerAlexander Larsson <alexl@redhat.com>2017-01-11 11:41:46 +0100
commit6341fab985864cfa337c55cb35e06a7b13119838 (patch)
tree4d9bbf68074d8522a5e8b48b1a69e22cf2b42b73
parentf67ae85b7a33bf1a6a141050d5fc659b0c678d1b (diff)
downloadgtk+-6341fab985864cfa337c55cb35e06a7b13119838.tar.gz
GtkSnapshot: Reuse snapshot state objects
Rather than allocate new ones all the time we reuse the previous ones. We just clear them and save them in the parent for later reuse.
-rw-r--r--gtk/gtksnapshot.c40
-rw-r--r--gtk/gtksnapshotprivate.h1
2 files changed, 30 insertions, 11 deletions
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index e17005828a..72f1b1586f 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -84,11 +84,18 @@ gtk_snapshot_state_new (GtkSnapshotState *parent,
{
GtkSnapshotState *state;
- state = g_slice_new0 (GtkSnapshotState);
-
- state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
+ if (parent != NULL && parent->cached_state != NULL)
+ {
+ state = parent->cached_state;
+ parent->cached_state = NULL;
+ }
+ else
+ {
+ state = g_slice_new0 (GtkSnapshotState);
+ state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
+ state->parent = parent;
+ }
- state->parent = parent;
state->name = name;
if (clip)
state->clip_region = cairo_region_reference (clip);
@@ -100,15 +107,20 @@ gtk_snapshot_state_new (GtkSnapshotState *parent,
}
static void
+gtk_snapshot_state_clear (GtkSnapshotState *state)
+{
+ g_ptr_array_set_size (state->nodes, 0);
+ g_clear_pointer (&state->clip_region, cairo_region_destroy);
+ g_clear_pointer (&state->name, g_free);
+}
+
+static void
gtk_snapshot_state_free (GtkSnapshotState *state)
{
+ if (state->cached_state)
+ gtk_snapshot_state_free (state->cached_state);
+ gtk_snapshot_state_clear (state);
g_ptr_array_unref (state->nodes);
-
- if (state->clip_region)
- cairo_region_destroy (state->clip_region);
-
- g_free (state->name);
-
g_slice_free (GtkSnapshotState, state);
}
@@ -697,7 +709,13 @@ gtk_snapshot_pop (GtkSnapshot *snapshot)
state->nodes->len,
state->name);
- gtk_snapshot_state_free (state);
+ if (snapshot->state == NULL)
+ gtk_snapshot_state_free (state);
+ else
+ {
+ gtk_snapshot_state_clear (state);
+ snapshot->state->cached_state = state;
+ }
return node;
}
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index 31415588ba..2384a8b55f 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -31,6 +31,7 @@ typedef GskRenderNode * (* GtkSnapshotCollectFunc) (GtkSnapshotState *state,
struct _GtkSnapshotState {
GtkSnapshotState *parent;
+ GtkSnapshotState *cached_state; /* A cleared state object we can (re)use */
char *name;
GPtrArray *nodes;