mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-03 08:58:03 +02:00
[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.
This commit is contained in:
parent
ba6b2d092a
commit
d9b2e8f004
1 changed files with 24 additions and 17 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue