summaryrefslogtreecommitdiff
path: root/src/cairo-path-stroke.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-05-07 09:20:17 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-06-13 21:34:41 +0100
commitd9b2e8f0045dcde8beafed7fe08728ae15194ffa (patch)
tree540cf571191046e8f8d09d2e56bdf85f37028b99 /src/cairo-path-stroke.c
parentba6b2d092ab45e9d28ab5c016315458d1ad670ff (diff)
[cairo-path-stroke] Avoid allocation for single rectangle.
The most common case for path stroking is a single rectangle, so embed sufficient segments into the stroker to avoid an extra allocation.
Diffstat (limited to 'src/cairo-path-stroke.c')
-rw-r--r--src/cairo-path-stroke.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 3032df55..d72ccf37 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -1191,9 +1191,10 @@ typedef struct _cairo_rectilinear_stroker
cairo_point_t current_point;
cairo_point_t first_point;
cairo_bool_t open_sub_path;
- cairo_line_t *segments;
- int segments_size;
int num_segments;
+ int segments_size;
+ cairo_line_t *segments;
+ cairo_line_t segments_embedded[8]; /* common case is a single rectangle */
} cairo_rectilinear_stroker_t;
static void
@@ -1206,15 +1207,16 @@ _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker,
_cairo_fixed_from_double (stroke_style->line_width / 2.0);
stroker->traps = traps;
stroker->open_sub_path = FALSE;
- stroker->segments = NULL;
- stroker->segments_size = 0;
+ stroker->segments = stroker->segments_embedded;
+ stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded);
stroker->num_segments = 0;
}
static void
_cairo_rectilinear_stroker_fini (cairo_rectilinear_stroker_t *stroker)
{
- free (stroker->segments);
+ if (stroker->segments != stroker->segments_embedded)
+ free (stroker->segments);
}
static cairo_status_t
@@ -1222,18 +1224,24 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
cairo_point_t *p1,
cairo_point_t *p2)
{
- int new_size;
- cairo_line_t *new_segments;
if (stroker->num_segments == stroker->segments_size) {
- new_size = stroker->segments_size * 2;
- /* Common case is one rectangle of exactly 4 segments. */
- if (new_size == 0)
- new_size = 4;
- new_segments = _cairo_realloc_ab (stroker->segments,
- new_size, sizeof (cairo_line_t));
- if (new_segments == NULL)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ int new_size = stroker->segments_size * 2;
+ cairo_line_t *new_segments;
+
+ if (stroker->segments == stroker->segments_embedded) {
+ new_segments = _cairo_malloc_ab (new_size, sizeof (cairo_line_t));
+ if (new_segments == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ memcpy (new_segments, stroker->segments,
+ stroker->num_segments * sizeof (cairo_line_t));
+ } else {
+ new_segments = _cairo_realloc_ab (stroker->segments,
+ new_size, sizeof (cairo_line_t));
+ if (new_segments == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
stroker->segments_size = new_size;
stroker->segments = new_segments;
@@ -1390,8 +1398,7 @@ _cairo_rectilinear_stroker_line_to (void *closure,
if (a->x == b->x && a->y == b->y)
return CAIRO_STATUS_SUCCESS;
- status = _cairo_rectilinear_stroker_add_segment (stroker,
- a, b);
+ status = _cairo_rectilinear_stroker_add_segment (stroker, a, b);
stroker->current_point = *point;
stroker->open_sub_path = TRUE;