diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-09-19 10:54:13 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-09-19 14:31:33 +0100 |
commit | 9930eefbbd4448d598faff12fc0f7127555c8c94 (patch) | |
tree | 581b7628bf9c2fd8c9259bf6a942c155020b5485 /src/cairo-traps.c | |
parent | 27ee8dd9c64ac0fd36ce7b58729ee732e3396ee1 (diff) |
Simple perf tweaks for a rectilinear Hilbert curve.
Some tweaks to avoid stack copies and branches that save ~25% in
_cairo_traps_tessellate_convex_quad().
Diffstat (limited to 'src/cairo-traps.c')
-rw-r--r-- | src/cairo-traps.c | 175 |
1 files changed, 65 insertions, 110 deletions
diff --git a/src/cairo-traps.c b/src/cairo-traps.c index cdfdadd3..fabfecb0 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -41,13 +41,6 @@ /* private functions */ -static cairo_status_t -_cairo_traps_grow (cairo_traps_t *traps); - -static void -_cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, - cairo_line_t *left, cairo_line_t *right); - static int _compare_point_fixed_by_y (const void *av, const void *bv); @@ -94,12 +87,8 @@ _cairo_traps_clear (cairo_traps_t *traps) void _cairo_traps_fini (cairo_traps_t *traps) { - if (traps->traps && traps->traps != traps->traps_embedded) + if (traps->traps != traps->traps_embedded) free (traps->traps); - - traps->traps = NULL; - traps->traps_size = 0; - traps->num_traps = 0; } /** @@ -111,9 +100,9 @@ _cairo_traps_fini (cairo_traps_t *traps) * Initializes a #cairo_traps_t to contain a single rectangular * trapezoid. **/ -cairo_status_t +void _cairo_traps_init_box (cairo_traps_t *traps, - cairo_box_t *box) + const cairo_box_t *box) { _cairo_traps_init (traps); @@ -131,25 +120,41 @@ _cairo_traps_init_box (cairo_traps_t *traps, traps->traps[0].right.p2 = box->p2; traps->extents = *box; - - return traps->status; } -cairo_status_t -_cairo_traps_status (cairo_traps_t *traps) +/* make room for at least one more trap */ +static cairo_bool_t +_cairo_traps_grow (cairo_traps_t *traps) { - return traps->status; + cairo_trapezoid_t *new_traps; + int new_size = 2 * MAX (traps->traps_size, 16); + + if (traps->traps == traps->traps_embedded) { + new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t)); + if (new_traps != NULL) + memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded)); + } else { + new_traps = _cairo_realloc_ab (traps->traps, + new_size, sizeof (cairo_trapezoid_t)); + } + + if (new_traps == NULL) { + traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + return FALSE; + } + + traps->traps = new_traps; + traps->traps_size = new_size; + return TRUE; } -static void -_cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, +void +_cairo_traps_add_trap (cairo_traps_t *traps, + cairo_fixed_t top, cairo_fixed_t bottom, cairo_line_t *left, cairo_line_t *right) { cairo_trapezoid_t *trap; - if (traps->status) - return; - /* Note: With the goofy trapezoid specification, (where an * arbitrary two points on the lines can specified for the left * and right edges), these limit checks would not work in @@ -209,9 +214,8 @@ _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bo return; } - if (traps->num_traps >= traps->traps_size) { - traps->status = _cairo_traps_grow (traps); - if (traps->status) + if (traps->num_traps == traps->traps_size) { + if (! _cairo_traps_grow (traps)) return; } @@ -246,51 +250,6 @@ _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bo traps->num_traps++; } -void -_cairo_traps_add_trap_from_points (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, - cairo_point_t left_p1, cairo_point_t left_p2, - cairo_point_t right_p1, cairo_point_t right_p2) -{ - cairo_line_t left; - cairo_line_t right; - - if (traps->status) - return; - - left.p1 = left_p1; - left.p2 = left_p2; - - right.p1 = right_p1; - right.p2 = right_p2; - - _cairo_traps_add_trap (traps, top, bottom, &left, &right); -} - -/* make room for at least one more trap */ -static cairo_status_t -_cairo_traps_grow (cairo_traps_t *traps) -{ - cairo_trapezoid_t *new_traps; - int new_size = 2 * MAX (traps->traps_size, 16); - - if (traps->traps == traps->traps_embedded) { - new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t)); - if (new_traps) - memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded)); - } else { - new_traps = _cairo_realloc_ab (traps->traps, - new_size, sizeof (cairo_trapezoid_t)); - } - - if (new_traps == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - traps->traps = new_traps; - traps->traps_size = new_size; - - return CAIRO_STATUS_SUCCESS; -} - static int _compare_point_fixed_by_y (const void *av, const void *bv) { @@ -379,7 +338,8 @@ _cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps, * quadrilateral. We would not benefit from having any distinct * implementation of triangle vs. quadrilateral tessellation here. */ cairo_status_t -_cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3]) +_cairo_traps_tessellate_triangle (cairo_traps_t *traps, + const cairo_point_t t[3]) { cairo_point_t quad[4]; @@ -392,12 +352,15 @@ _cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3]) } cairo_status_t -_cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, cairo_point_t q[4]) +_cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, + const cairo_point_t q[4]) { int a, b, c, d; int i; cairo_slope_t ab, ad; cairo_bool_t b_left_of_d; + cairo_line_t left; + cairo_line_t right; /* Choose a as a point with minimal y */ a = 0; @@ -462,15 +425,13 @@ _cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, cairo_point_t q[4]) * | / \| \ \ c.y d.y cd ad * d d d */ - _cairo_traps_add_trap_from_points (traps, - q[a].y, q[b].y, - q[a], q[b], q[a], q[d]); - _cairo_traps_add_trap_from_points (traps, - q[b].y, q[c].y, - q[b], q[c], q[a], q[d]); - _cairo_traps_add_trap_from_points (traps, - q[c].y, q[d].y, - q[c], q[d], q[a], q[d]); + left.p1 = q[a]; left.p2 = q[b]; + right.p1 = q[a]; right.p2 = q[d]; + _cairo_traps_add_trap (traps, q[a].y, q[b].y, &left, &right); + left.p1 = q[b]; left.p2 = q[c]; + _cairo_traps_add_trap (traps, q[b].y, q[c].y, &left, &right); + left.p1 = q[c]; left.p2 = q[d]; + _cairo_traps_add_trap (traps, q[c].y, q[d].y, &left, &right); } else { /* Y-sort is abcd and b is right of d, (slope(ab) <= slope (ad)) * @@ -482,15 +443,13 @@ _cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, cairo_point_t q[4]) * / / |/ \ | c.y d.y ad cd * d d d */ - _cairo_traps_add_trap_from_points (traps, - q[a].y, q[b].y, - q[a], q[d], q[a], q[b]); - _cairo_traps_add_trap_from_points (traps, - q[b].y, q[c].y, - q[a], q[d], q[b], q[c]); - _cairo_traps_add_trap_from_points (traps, - q[c].y, q[d].y, - q[a], q[d], q[c], q[d]); + left.p1 = q[a]; left.p2 = q[d]; + right.p1 = q[a]; right.p2 = q[b]; + _cairo_traps_add_trap (traps, q[a].y, q[b].y, &left, &right); + right.p1 = q[b]; right.p2 = q[c]; + _cairo_traps_add_trap (traps, q[b].y, q[c].y, &left, &right); + right.p1 = q[c]; right.p2 = q[d]; + _cairo_traps_add_trap (traps, q[c].y, q[d].y, &left, &right); } } else { if (b_left_of_d) { @@ -504,15 +463,13 @@ _cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, cairo_point_t q[4]) * // \ / \| d.y c.y bc dc * c c c */ - _cairo_traps_add_trap_from_points (traps, - q[a].y, q[b].y, - q[a], q[b], q[a], q[d]); - _cairo_traps_add_trap_from_points (traps, - q[b].y, q[d].y, - q[b], q[c], q[a], q[d]); - _cairo_traps_add_trap_from_points (traps, - q[d].y, q[c].y, - q[b], q[c], q[d], q[c]); + left.p1 = q[a]; left.p2 = q[b]; + right.p1 = q[a]; right.p2 = q[d]; + _cairo_traps_add_trap (traps, q[a].y, q[b].y, &left, &right); + left.p1 = q[b]; left.p2 = q[c]; + _cairo_traps_add_trap (traps, q[b].y, q[d].y, &left, &right); + right.p1 = q[d]; right.p2 = q[c]; + _cairo_traps_add_trap (traps, q[d].y, q[c].y, &left, &right); } else { /* Y-sort is abdc and b is right of d, (slope (ab) <= slope (ad)) * @@ -524,15 +481,13 @@ _cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, cairo_point_t q[4]) * |/ \ / \\ d.y c.y dc bc * c c c */ - _cairo_traps_add_trap_from_points (traps, - q[a].y, q[b].y, - q[a], q[d], q[a], q[b]); - _cairo_traps_add_trap_from_points (traps, - q[b].y, q[d].y, - q[a], q[d], q[b], q[c]); - _cairo_traps_add_trap_from_points (traps, - q[d].y, q[c].y, - q[d], q[c], q[b], q[c]); + left.p1 = q[a]; left.p2 = q[d]; + right.p1 = q[a]; right.p2 = q[b]; + _cairo_traps_add_trap (traps, q[a].y, q[b].y, &left, &right); + right.p1 = q[b]; right.p2 = q[c]; + _cairo_traps_add_trap (traps, q[b].y, q[d].y, &left, &right); + left.p1 = q[d]; left.p2 = q[c]; + _cairo_traps_add_trap (traps, q[d].y, q[c].y, &left, &right); } } |