diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-05-07 09:20:17 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-06-13 21:34:41 +0100 |
commit | d9b2e8f0045dcde8beafed7fe08728ae15194ffa (patch) | |
tree | 540cf571191046e8f8d09d2e56bdf85f37028b99 /src/cairo-path-stroke.c | |
parent | ba6b2d092ab45e9d28ab5c016315458d1ad670ff (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.c | 41 |
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; |