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.
This commit is contained in:
Chris Wilson 2007-03-26 10:33:32 +01:00
parent 38442d4948
commit 256f3e09a8
3 changed files with 20 additions and 0 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;