From 256f3e09a8a0d152a33df00604bf2245604b72bc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 26 Mar 2007 10:33:32 +0100 Subject: [PATCH] Destroy the current pattern before replacing with cairo_set_source(). Frequently cairo_set_source_rgb[a]() is used to replace the current solid-pattern source with a new one of a different colour. The current pattern is very likely to be unshared and unmodified and so it is likely just to be immediately freed [or rather simply moved to recently freed cache]. However as the last active pattern it is likely to cache-warm and suitable to satisfy the forthcoming allocation. So by setting the current pattern to 'none' we can move the pattern to the freed list before we create the new pattern and hopefully immediately reuse it. --- src/cairo-pattern.c | 10 ++++++++++ src/cairo.c | 9 +++++++++ src/cairoint.h | 1 + 3 files changed, 20 insertions(+) diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index ed535e1c2..2bc55803c 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -50,6 +50,16 @@ static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = { CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */ }; +const cairo_solid_pattern_t cairo_pattern_none = { + { CAIRO_PATTERN_TYPE_SOLID, /* type */ + CAIRO_REF_COUNT_INVALID, /* ref_count */ + CAIRO_STATUS_SUCCESS, /* status */ + { 0, 0, 0, NULL }, /* user_data */ + { 1., 0., 0., 1., 0., 0., }, /* matrix */ + CAIRO_FILTER_DEFAULT, /* filter */ + CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */ +}; + /** * _cairo_pattern_set_error: * @pattern: a pattern diff --git a/src/cairo.c b/src/cairo.c index 22e15fde8..9a96dda7e 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -671,6 +671,9 @@ cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue) if (cr->status) return; + /* push the current pattern to the freed lists */ + cairo_set_source (cr, (cairo_pattern_t *) &cairo_pattern_none); + pattern = cairo_pattern_create_rgb (red, green, blue); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); @@ -702,6 +705,9 @@ cairo_set_source_rgba (cairo_t *cr, if (cr->status) return; + /* push the current pattern to the freed lists */ + cairo_set_source (cr, (cairo_pattern_t *) &cairo_pattern_none); + pattern = cairo_pattern_create_rgba (red, green, blue, alpha); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); @@ -742,6 +748,9 @@ cairo_set_source_surface (cairo_t *cr, if (cr->status) return; + /* push the current pattern to the freed lists */ + cairo_set_source (cr, (cairo_pattern_t *) &cairo_pattern_none); + pattern = cairo_pattern_create_for_surface (surface); cairo_matrix_init_translate (&matrix, -x, -y); diff --git a/src/cairoint.h b/src/cairoint.h index 4538bece9..1d2c3c782 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1093,6 +1093,7 @@ typedef struct _cairo_solid_pattern { } cairo_solid_pattern_t; extern const cairo_private cairo_solid_pattern_t cairo_pattern_nil; +extern const cairo_private cairo_solid_pattern_t cairo_pattern_none; typedef struct _cairo_surface_pattern { cairo_pattern_t base;