[cairo-commit] 2 commits - src/cairoint.h src/cairo-pattern.c
Behdad Esfahbod
behdad at kemper.freedesktop.org
Wed Mar 14 14:25:50 PDT 2007
src/cairo-pattern.c | 82 +++++++++++++++++++++++++++++++++++++++-------------
src/cairoint.h | 4 +-
2 files changed, 65 insertions(+), 21 deletions(-)
New commits:
diff-tree e803e2e69ba02a1db316c97eb9a8d386709380e2 (from 4514fdca1ba0f3922c2797744f4b0d42d37f8b42)
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Mar 14 17:23:57 2007 -0400
[cairo-pattern] Add a cache of two color stops to cairo_gradient_pattern_t
Most of gradients have only two color stops. This avoids
calling malloc() for those cases.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 7aef3c7..f076259 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -117,7 +117,9 @@ _cairo_gradient_pattern_init_copy (cairo
*dst = *src;
}
- if (other->n_stops)
+ if (other->stops == other->stops_embedded)
+ pattern->stops = pattern->stops_embedded;
+ else if (other->stops)
{
pattern->stops = malloc (other->stops_size *
sizeof (pixman_gradient_stop_t));
@@ -187,7 +189,7 @@ _cairo_pattern_fini (cairo_pattern_t *pa
cairo_gradient_pattern_t *gradient =
(cairo_gradient_pattern_t *) pattern;
- if (gradient->stops)
+ if (gradient->stops && gradient->stops != gradient->stops_embedded)
free (gradient->stops);
} break;
}
@@ -657,11 +659,26 @@ _cairo_pattern_gradient_grow (cairo_grad
{
pixman_gradient_stop_t *new_stops;
int old_size = pattern->stops_size;
- int new_size = old_size ? 2 * old_size : 8;
+ int embedded_size = sizeof (pattern->stops_embedded) / sizeof (pattern->stops_embedded[0]);
+ int new_size = 2 * MAX (old_size, 4);
+
+ /* we have a local buffer at pattern->stops_embedded. try to fulfill the request
+ * from there. */
+ if (old_size < embedded_size) {
+ pattern->stops = pattern->stops_embedded;
+ pattern->stops_size = embedded_size;
+ return CAIRO_STATUS_SUCCESS;
+ }
assert (pattern->n_stops <= pattern->stops_size);
- new_stops = realloc (pattern->stops, new_size * sizeof (pixman_gradient_stop_t));
+ if (pattern->stops == pattern->stops_embedded) {
+ new_stops = malloc (new_size * sizeof (pixman_gradient_stop_t));
+ if (new_stops)
+ memcpy (new_stops, pattern->stops, old_size * sizeof (pixman_gradient_stop_t));
+ } else {
+ new_stops = realloc (pattern->stops, new_size * sizeof (pixman_gradient_stop_t));
+ }
if (new_stops == NULL) {
return CAIRO_STATUS_NO_MEMORY;
diff --git a/src/cairoint.h b/src/cairoint.h
index ea690f2..17f8187 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1181,6 +1181,7 @@ typedef struct _cairo_gradient_pattern {
unsigned int n_stops;
unsigned int stops_size;
pixman_gradient_stop_t *stops;
+ pixman_gradient_stop_t stops_embedded[2];
} cairo_gradient_pattern_t;
typedef struct _cairo_linear_pattern {
diff-tree 4514fdca1ba0f3922c2797744f4b0d42d37f8b42 (from e878f2259b2512f0411d698bf078fe91b7373246)
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Mar 13 20:49:52 2007 -0400
[cairo-pattern] Grow color-stops array exponentially
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 7cd033c..7aef3c7 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -119,9 +119,11 @@ _cairo_gradient_pattern_init_copy (cairo
if (other->n_stops)
{
- pattern->stops = malloc (other->n_stops *
+ pattern->stops = malloc (other->stops_size *
sizeof (pixman_gradient_stop_t));
if (pattern->stops == NULL) {
+ pattern->stops_size = 0;
+ pattern->n_stops = 0;
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
return;
}
@@ -221,8 +223,9 @@ _cairo_pattern_init_gradient (cairo_grad
{
_cairo_pattern_init (&pattern->base, type);
- pattern->stops = NULL;
- pattern->n_stops = 0;
+ pattern->n_stops = 0;
+ pattern->stops_size = 0;
+ pattern->stops = NULL;
}
void
@@ -648,6 +651,28 @@ cairo_pattern_set_user_data (cairo_patte
key, user_data, destroy);
}
+/* make room for at least one more color stop */
+static cairo_status_t
+_cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
+{
+ pixman_gradient_stop_t *new_stops;
+ int old_size = pattern->stops_size;
+ int new_size = old_size ? 2 * old_size : 8;
+
+ assert (pattern->n_stops <= pattern->stops_size);
+
+ new_stops = realloc (pattern->stops, new_size * sizeof (pixman_gradient_stop_t));
+
+ if (new_stops == NULL) {
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ pattern->stops = new_stops;
+ pattern->stops_size = new_size;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
static void
_cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
double offset,
@@ -656,38 +681,38 @@ _cairo_pattern_add_color_stop (cairo_gra
double blue,
double alpha)
{
- pixman_gradient_stop_t *new_stops;
+ pixman_gradient_stop_t *stops;
cairo_fixed_t x;
unsigned int i;
- new_stops = realloc (pattern->stops, (pattern->n_stops + 1) *
- sizeof (pixman_gradient_stop_t));
- if (new_stops == NULL)
- {
- _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
- return;
+ if (pattern->n_stops >= pattern->stops_size) {
+ cairo_status_t status = _cairo_pattern_gradient_grow (pattern);
+ if (status) {
+ _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
+ return;
+ }
}
- pattern->stops = new_stops;
+ stops = pattern->stops;
x = _cairo_fixed_from_double (offset);
for (i = 0; i < pattern->n_stops; i++)
{
- if (x < new_stops[i].x)
+ if (x < stops[i].x)
{
- memmove (&new_stops[i + 1], &new_stops[i],
+ memmove (&stops[i + 1], &stops[i],
sizeof (pixman_gradient_stop_t) * (pattern->n_stops - i));
break;
}
}
- new_stops[i].x = x;
+ stops[i].x = x;
- new_stops[i].color.red = _cairo_color_double_to_short (red);
- new_stops[i].color.green = _cairo_color_double_to_short (green);
- new_stops[i].color.blue = _cairo_color_double_to_short (blue);
- new_stops[i].color.alpha = _cairo_color_double_to_short (alpha);
+ stops[i].color.red = _cairo_color_double_to_short (red);
+ stops[i].color.green = _cairo_color_double_to_short (green);
+ stops[i].color.blue = _cairo_color_double_to_short (blue);
+ stops[i].color.alpha = _cairo_color_double_to_short (alpha);
pattern->n_stops++;
}
diff --git a/src/cairoint.h b/src/cairoint.h
index c31f1dc..ea690f2 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1178,8 +1178,9 @@ typedef struct _cairo_surface_pattern {
typedef struct _cairo_gradient_pattern {
cairo_pattern_t base;
+ unsigned int n_stops;
+ unsigned int stops_size;
pixman_gradient_stop_t *stops;
- unsigned int n_stops;
} cairo_gradient_pattern_t;
typedef struct _cairo_linear_pattern {
More information about the cairo-commit
mailing list