summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-10-02 07:52:05 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-10-02 08:46:44 +0100
commit950f1e7103a3b4f3405fbb3ee2844ed24b902834 (patch)
tree191a7b829a39d94eccc72099e49d13664521ff68
parent1a32ce83e4c1f3ca22a3f137b0126003a0e3d6e7 (diff)
downloadcairo-950f1e7103a3b4f3405fbb3ee2844ed24b902834.tar.gz
tor: Enable analytic processing for starting rows
If all the edges start at the very beginning of the whole row, we can merge them and include check for intersections/endings during the row. This allows us to enable fast analytic processing for even the very first row on pixel aligned vertices. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/cairo-tor-scan-converter.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/cairo-tor-scan-converter.c b/src/cairo-tor-scan-converter.c
index d1aff2551..4adcafb4c 100644
--- a/src/cairo-tor-scan-converter.c
+++ b/src/cairo-tor-scan-converter.c
@@ -1167,8 +1167,8 @@ can_do_full_row (struct active_list *active)
if (e->dy) {
struct quorem x = e->x;
- x.quo += e->dxdy_full.quo;
- x.rem += e->dxdy_full.rem;
+ x.quo += e->dxdy_full.quo - e->dxdy.quo/2;
+ x.rem += e->dxdy_full.rem - e->dxdy.rem/2;
if (x.rem < 0) {
x.quo--;
x.rem += e->dy;
@@ -1198,7 +1198,7 @@ active_list_merge_edges_from_bucket(struct active_list *active,
active->head.next = merge_unsorted_edges (active->head.next, edges);
}
-inline static void
+inline static int
polygon_fill_buckets (struct active_list *active,
struct edge *edge,
int y,
@@ -1206,6 +1206,7 @@ polygon_fill_buckets (struct active_list *active,
{
grid_scaled_y_t min_height = active->min_height;
int is_vertical = active->is_vertical;
+ int max_suby = 0;
while (edge) {
struct edge *next = edge->next;
@@ -1219,10 +1220,14 @@ polygon_fill_buckets (struct active_list *active,
min_height = edge->height_left;
is_vertical &= edge->dy == 0;
edge = next;
+ if (suby > max_suby)
+ max_suby = suby;
}
active->is_vertical = is_vertical;
active->min_height = min_height;
+
+ return max_suby;
}
static void step (struct edge *edge)
@@ -1729,7 +1734,15 @@ glitter_scan_converter_render(glitter_scan_converter_t *converter,
/* Determine if we can ignore this row or use the full pixel
* stepper. */
- if (! polygon->y_buckets[i]) {
+ if (polygon_fill_buckets (active,
+ polygon->y_buckets[i],
+ (i+ymin_i)*GRID_Y,
+ buckets) == 0) {
+ if (buckets[0]) {
+ active_list_merge_edges_from_bucket (active, buckets[0]);
+ buckets[0] = NULL;
+ }
+
if (active->head.next == &active->tail) {
active->min_height = INT_MAX;
active->is_vertical = 1;
@@ -1759,18 +1772,12 @@ glitter_scan_converter_render(glitter_scan_converter_t *converter,
} else {
int sub;
- polygon_fill_buckets (active,
- polygon->y_buckets[i],
- (i+ymin_i)*GRID_Y,
- buckets);
-
/* Subsample this row. */
for (sub = 0; sub < GRID_Y; sub++) {
if (buckets[sub]) {
active_list_merge_edges_from_bucket (active, buckets[sub]);
buckets[sub] = NULL;
}
-
sub_row (active, coverages, winding_mask);
}
}