diff options
author | Alexander Larsson <alexl@redhat.com> | 2017-01-11 11:41:46 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2017-01-11 11:41:46 +0100 |
commit | 6341fab985864cfa337c55cb35e06a7b13119838 (patch) | |
tree | 4d9bbf68074d8522a5e8b48b1a69e22cf2b42b73 | |
parent | f67ae85b7a33bf1a6a141050d5fc659b0c678d1b (diff) | |
download | gtk+-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.c | 40 | ||||
-rw-r--r-- | gtk/gtksnapshotprivate.h | 1 |
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; |