summaryrefslogtreecommitdiff
path: root/src/cairo.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-04-29 11:56:21 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-06-13 21:34:41 +0100
commitb2eadb94f8e34d7c997b5ccfbca4d21e173fdd56 (patch)
tree3f4c3338c6835f5c559666a24d7aecd6bc0e15db /src/cairo.c
parentc57b1eca18db12b8d56d73093d5cae28ed388298 (diff)
[cairo] Cache freed gstates.
Reduce the malloc pressure from frequent cairo_save()/cairo_restore() by caching the freed gstates in a list on the context.
Diffstat (limited to 'src/cairo.c')
-rw-r--r--src/cairo.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/src/cairo.c b/src/cairo.c
index e001e70f..ec2616a8 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -52,7 +52,8 @@ static const cairo_t _cairo_nil = {
{{ /* gstate_tail */
0
}},
- {{ /* path */
+ NULL, /* gstate_freelist */
+ {{ /* path */
{ 0, 0 }, /* last_move_point */
{ 0, 0 }, /* current point */
FALSE, /* has_current_point */
@@ -205,6 +206,7 @@ cairo_create (cairo_surface_t *target)
_cairo_path_fixed_init (cr->path);
cr->gstate = cr->gstate_tail;
+ cr->gstate_freelist = NULL;
status = _cairo_gstate_init (cr->gstate, target);
if (status)
@@ -260,11 +262,16 @@ cairo_destroy (cairo_t *cr)
return;
while (cr->gstate != cr->gstate_tail) {
- if (_cairo_gstate_restore (&cr->gstate))
+ if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist))
break;
}
_cairo_gstate_fini (cr->gstate);
+ while (cr->gstate_freelist != NULL) {
+ cairo_gstate_t *gstate = cr->gstate_freelist;
+ cr->gstate_freelist = gstate->next;
+ free (gstate);
+ }
_cairo_path_fixed_fini (cr->path);
@@ -371,10 +378,9 @@ cairo_save (cairo_t *cr)
if (cr->status)
return;
- status = _cairo_gstate_save (&cr->gstate);
- if (status) {
+ status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
+ if (status)
_cairo_set_error (cr, status);
- }
}
slim_hidden_def(cairo_save);
@@ -394,10 +400,9 @@ cairo_restore (cairo_t *cr)
if (cr->status)
return;
- status = _cairo_gstate_restore (&cr->gstate);
- if (status) {
+ status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
+ if (status)
_cairo_set_error (cr, status);
- }
}
slim_hidden_def(cairo_restore);