diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-04 18:31:20 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-04 22:54:02 +0000 |
commit | c45822886aae53def2e76ef582aac167adf7fd56 (patch) | |
tree | e1d5d186a4974e1f2faca56a2d58b1538fe51fa2 /src/cairo-traps.c | |
parent | 38a242a380d24c669f10dd542c3bab606434b8ad (diff) | |
download | cairo-c45822886aae53def2e76ef582aac167adf7fd56.tar.gz |
traps: Use the mono-scan-converter to reduce the number of traps
This trick only seems effective with mono-rasterisation, with a win of
about 10% for tiger-demo --antialias=none. At other antialias setting,
performance is reduced.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-traps.c')
-rw-r--r-- | src/cairo-traps.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 30e626fae..c776d33b2 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -44,6 +44,7 @@ #include "cairo-region-private.h" #include "cairo-slope-private.h" #include "cairo-traps-private.h" +#include "cairo-spans-private.h" /* private functions */ @@ -750,3 +751,64 @@ _cairo_debug_print_traps (FILE *file, const cairo_traps_t *traps) traps->traps[n].right.p2.y); } } + +struct cairo_trap_renderer { + cairo_span_renderer_t base; + cairo_traps_t *traps; +}; + +static cairo_status_t +span_to_traps (void *abstract_renderer, int y, int h, + const cairo_half_open_span_t *spans, unsigned num_spans) +{ + struct cairo_trap_renderer *r = abstract_renderer; + cairo_fixed_t top, bot; + + if (num_spans == 0) + return CAIRO_STATUS_SUCCESS; + + top = _cairo_fixed_from_int (y); + bot = _cairo_fixed_from_int (y + h); + do { + if (spans[0].coverage) { + cairo_fixed_t x0 = _cairo_fixed_from_int(spans[0].x); + cairo_fixed_t x1 = _cairo_fixed_from_int(spans[1].x); + cairo_line_t left = { { x0, top }, { x0, bot } }, + right = { { x1, top }, { x1, bot } }; + _cairo_traps_add_trap (r->traps, top, bot, &left, &right); + } + spans++; + } while (--num_spans > 1); + + return CAIRO_STATUS_SUCCESS; +} + +cairo_int_status_t +_cairo_rasterise_polygon_to_traps (cairo_polygon_t *polygon, + cairo_fill_rule_t fill_rule, + cairo_antialias_t antialias, + cairo_traps_t *traps) +{ + struct cairo_trap_renderer renderer; + cairo_scan_converter_t *converter; + cairo_int_status_t status; + cairo_rectangle_int_t r; + + TRACE ((stderr, "%s: fill_rule=%d, antialias=%d\n", + __FUNCTION__, fill_rule, antialias)); + assert(antialias == CAIRO_ANTIALIAS_NONE); + + renderer.traps = traps; + renderer.base.render_rows = span_to_traps; + + _cairo_box_round_to_rectangle (&polygon->extents, &r); + converter = _cairo_mono_scan_converter_create (r.x, r.y, + r.x + r.width, + r.y + r.height, + fill_rule); + status = _cairo_mono_scan_converter_add_polygon (converter, polygon); + if (likely (status == CAIRO_INT_STATUS_SUCCESS)) + status = converter->generate (converter, &renderer.base); + converter->destroy (converter); + return status; +} |