summaryrefslogtreecommitdiff
path: root/src/cairo-traps.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-09-19 10:54:13 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-09-19 14:31:33 +0100
commit9930eefbbd4448d598faff12fc0f7127555c8c94 (patch)
tree581b7628bf9c2fd8c9259bf6a942c155020b5485 /src/cairo-traps.c
parent27ee8dd9c64ac0fd36ce7b58729ee732e3396ee1 (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.c175
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);
}
}