wok annotate cairo/stuff/cairo-1.12.2-reduce-broken-stopped-edge-continuation.patch @ rev 19214

Up tzdata(2016e)
author Aleksej Bobylev <al.bobylev@gmail.com>
date Tue Jun 14 23:10:20 2016 +0300 (2016-06-14)
parents
children
rev   line source
slaxemulator@13173 1 From f228769dfe5a8b5d73c49a41e95e31ed73a77fb3 Mon Sep 17 00:00:00 2001
slaxemulator@13173 2 From: Chris Wilson <chris@chris-wilson.co.uk>
slaxemulator@13173 3 Date: Fri, 08 Jun 2012 16:22:41 +0000
slaxemulator@13173 4 Subject: polygon-reduce: Reduce broken stopped-edge continuation
slaxemulator@13173 5
slaxemulator@13173 6 This is hopefully a lesser used path and the attempted optimisation to
slaxemulator@13173 7 continue a stopped edge with a colinear stopped edge highly unlikely and
slaxemulator@13173 8 lost in the noise of the general inefficiency of the routine. As it was
slaxemulator@13173 9 broken, rather than attempt to rectify the "optimisation" remove it.
slaxemulator@13173 10
slaxemulator@13173 11 Reported-by: Evangelos Foutras <evangelos@foutrelis.com>
slaxemulator@13173 12 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50852
slaxemulator@13173 13 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
slaxemulator@13173 14 ---
slaxemulator@13173 15 diff --git a/src/cairo-polygon-reduce.c b/src/cairo-polygon-reduce.c
slaxemulator@13173 16 index 8758070..ea457fe 100644
slaxemulator@13173 17 --- a/src/cairo-polygon-reduce.c
slaxemulator@13173 18 +++ b/src/cairo-polygon-reduce.c
slaxemulator@13173 19 @@ -42,6 +42,8 @@
slaxemulator@13173 20 #include "cairo-freelist-private.h"
slaxemulator@13173 21 #include "cairo-combsort-inline.h"
slaxemulator@13173 22
slaxemulator@13173 23 +#define DEBUG_POLYGON 0
slaxemulator@13173 24 +
slaxemulator@13173 25 typedef cairo_point_t cairo_bo_point32_t;
slaxemulator@13173 26
slaxemulator@13173 27 typedef struct _cairo_bo_intersect_ordinate {
slaxemulator@13173 28 @@ -114,7 +116,6 @@ typedef struct _cairo_bo_event_queue {
slaxemulator@13173 29
slaxemulator@13173 30 typedef struct _cairo_bo_sweep_line {
slaxemulator@13173 31 cairo_bo_edge_t *head;
slaxemulator@13173 32 - cairo_bo_edge_t *stopped;
slaxemulator@13173 33 int32_t current_y;
slaxemulator@13173 34 cairo_bo_edge_t *current_edge;
slaxemulator@13173 35 } cairo_bo_sweep_line_t;
slaxemulator@13173 36 @@ -476,8 +477,8 @@ edges_compare_x_for_y (const cairo_bo_edge_t *a,
slaxemulator@13173 37 static inline int
slaxemulator@13173 38 _line_equal (const cairo_line_t *a, const cairo_line_t *b)
slaxemulator@13173 39 {
slaxemulator@13173 40 - return a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
slaxemulator@13173 41 - a->p2.x == b->p2.x && a->p2.y == b->p2.y;
slaxemulator@13173 42 + return (a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
slaxemulator@13173 43 + a->p2.x == b->p2.x && a->p2.y == b->p2.y);
slaxemulator@13173 44 }
slaxemulator@13173 45
slaxemulator@13173 46 static int
slaxemulator@13173 47 @@ -1024,7 +1025,6 @@ static void
slaxemulator@13173 48 _cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
slaxemulator@13173 49 {
slaxemulator@13173 50 sweep_line->head = NULL;
slaxemulator@13173 51 - sweep_line->stopped = NULL;
slaxemulator@13173 52 sweep_line->current_y = INT32_MIN;
slaxemulator@13173 53 sweep_line->current_edge = NULL;
slaxemulator@13173 54 }
slaxemulator@13173 55 @@ -1139,6 +1139,8 @@ edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b)
slaxemulator@13173 56 */
slaxemulator@13173 57 if (a->edge.line.p1.y == b->edge.line.p1.y) {
slaxemulator@13173 58 return a->edge.line.p1.x == b->edge.line.p1.x;
slaxemulator@13173 59 + } else if (a->edge.line.p2.y == b->edge.line.p2.y) {
slaxemulator@13173 60 + return a->edge.line.p2.x == b->edge.line.p2.x;
slaxemulator@13173 61 } else if (a->edge.line.p1.y < b->edge.line.p1.y) {
slaxemulator@13173 62 return edge_compare_for_y_against_x (b,
slaxemulator@13173 63 a->edge.line.p1.y,
slaxemulator@13173 64 @@ -1205,82 +1207,48 @@ _active_edges_to_polygon (cairo_bo_edge_t *left,
slaxemulator@13173 65 cairo_polygon_t *polygon)
slaxemulator@13173 66 {
slaxemulator@13173 67 cairo_bo_edge_t *right;
slaxemulator@13173 68 + unsigned int mask;
slaxemulator@13173 69
slaxemulator@13173 70 - if (fill_rule == CAIRO_FILL_RULE_WINDING) {
slaxemulator@13173 71 - while (left != NULL) {
slaxemulator@13173 72 - int in_out = left->edge.dir;
slaxemulator@13173 73 -
slaxemulator@13173 74 - right = left->next;
slaxemulator@13173 75 - if (left->deferred.right == NULL) {
slaxemulator@13173 76 - while (right != NULL && right->deferred.right == NULL)
slaxemulator@13173 77 - right = right->next;
slaxemulator@13173 78 -
slaxemulator@13173 79 - if (right != NULL && edges_colinear (left, right)) {
slaxemulator@13173 80 - /* continuation on left */
slaxemulator@13173 81 - left->deferred = right->deferred;
slaxemulator@13173 82 - right->deferred.right = NULL;
slaxemulator@13173 83 - }
slaxemulator@13173 84 - }
slaxemulator@13173 85 -
slaxemulator@13173 86 - right = left->next;
slaxemulator@13173 87 - while (right != NULL) {
slaxemulator@13173 88 - if (right->deferred.right != NULL)
slaxemulator@13173 89 - _cairo_bo_edge_end (right, top, polygon);
slaxemulator@13173 90 -
slaxemulator@13173 91 - in_out += right->edge.dir;
slaxemulator@13173 92 - if (in_out == 0) {
slaxemulator@13173 93 - cairo_bo_edge_t *next;
slaxemulator@13173 94 - cairo_bool_t skip = FALSE;
slaxemulator@13173 95 -
slaxemulator@13173 96 - /* skip co-linear edges */
slaxemulator@13173 97 - next = right->next;
slaxemulator@13173 98 - if (next != NULL)
slaxemulator@13173 99 - skip = edges_colinear (right, next);
slaxemulator@13173 100 + if (fill_rule == CAIRO_FILL_RULE_WINDING)
slaxemulator@13173 101 + mask = ~0;
slaxemulator@13173 102 + else
slaxemulator@13173 103 + mask = 1;
slaxemulator@13173 104
slaxemulator@13173 105 - if (! skip)
slaxemulator@13173 106 - break;
slaxemulator@13173 107 - }
slaxemulator@13173 108 + while (left != NULL) {
slaxemulator@13173 109 + int in_out = left->edge.dir;
slaxemulator@13173 110
slaxemulator@13173 111 + right = left->next;
slaxemulator@13173 112 + if (left->deferred.right == NULL) {
slaxemulator@13173 113 + while (right != NULL && right->deferred.right == NULL)
slaxemulator@13173 114 right = right->next;
slaxemulator@13173 115 - }
slaxemulator@13173 116 -
slaxemulator@13173 117 - _cairo_bo_edge_start_or_continue (left, right, top, polygon);
slaxemulator@13173 118
slaxemulator@13173 119 - left = right;
slaxemulator@13173 120 - if (left != NULL)
slaxemulator@13173 121 - left = left->next;
slaxemulator@13173 122 + if (right != NULL && edges_colinear (left, right)) {
slaxemulator@13173 123 + /* continuation on left */
slaxemulator@13173 124 + left->deferred = right->deferred;
slaxemulator@13173 125 + right->deferred.right = NULL;
slaxemulator@13173 126 + }
slaxemulator@13173 127 }
slaxemulator@13173 128 - } else {
slaxemulator@13173 129 - while (left != NULL) {
slaxemulator@13173 130 - int in_out = 0;
slaxemulator@13173 131
slaxemulator@13173 132 - right = left->next;
slaxemulator@13173 133 - while (right != NULL) {
slaxemulator@13173 134 - if (right->deferred.right != NULL)
slaxemulator@13173 135 - _cairo_bo_edge_end (right, top, polygon);
slaxemulator@13173 136 + right = left->next;
slaxemulator@13173 137 + while (right != NULL) {
slaxemulator@13173 138 + if (right->deferred.right != NULL)
slaxemulator@13173 139 + _cairo_bo_edge_end (right, top, polygon);
slaxemulator@13173 140
slaxemulator@13173 141 - if ((in_out++ & 1) == 0) {
slaxemulator@13173 142 - cairo_bo_edge_t *next;
slaxemulator@13173 143 - cairo_bool_t skip = FALSE;
slaxemulator@13173 144 -
slaxemulator@13173 145 - /* skip co-linear edges */
slaxemulator@13173 146 - next = right->next;
slaxemulator@13173 147 - if (next != NULL)
slaxemulator@13173 148 - skip = edges_colinear (right, next);
slaxemulator@13173 149 -
slaxemulator@13173 150 - if (! skip)
slaxemulator@13173 151 - break;
slaxemulator@13173 152 - }
slaxemulator@13173 153 -
slaxemulator@13173 154 - right = right->next;
slaxemulator@13173 155 + in_out += right->edge.dir;
slaxemulator@13173 156 + if ((in_out & mask) == 0) {
slaxemulator@13173 157 + /* skip co-linear edges */
slaxemulator@13173 158 + if (right->next == NULL || !edges_colinear (right, right->next))
slaxemulator@13173 159 + break;
slaxemulator@13173 160 }
slaxemulator@13173 161
slaxemulator@13173 162 - _cairo_bo_edge_start_or_continue (left, right, top, polygon);
slaxemulator@13173 163 -
slaxemulator@13173 164 - left = right;
slaxemulator@13173 165 - if (left != NULL)
slaxemulator@13173 166 - left = left->next;
slaxemulator@13173 167 + right = right->next;
slaxemulator@13173 168 }
slaxemulator@13173 169 +
slaxemulator@13173 170 + _cairo_bo_edge_start_or_continue (left, right, top, polygon);
slaxemulator@13173 171 +
slaxemulator@13173 172 + left = right;
slaxemulator@13173 173 + if (left != NULL)
slaxemulator@13173 174 + left = left->next;
slaxemulator@13173 175 }
slaxemulator@13173 176 }
slaxemulator@13173 177
slaxemulator@13173 178 @@ -1303,12 +1271,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events,
slaxemulator@13173 179
slaxemulator@13173 180 while ((event = _cairo_bo_event_dequeue (&event_queue))) {
slaxemulator@13173 181 if (event->point.y != sweep_line.current_y) {
slaxemulator@13173 182 - for (e1 = sweep_line.stopped; e1; e1 = e1->next) {
slaxemulator@13173 183 - if (e1->deferred.right != NULL)
slaxemulator@13173 184 - _cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
slaxemulator@13173 185 - }
slaxemulator@13173 186 - sweep_line.stopped = NULL;
slaxemulator@13173 187 -
slaxemulator@13173 188 _active_edges_to_polygon (sweep_line.head,
slaxemulator@13173 189 sweep_line.current_y,
slaxemulator@13173 190 fill_rule, polygon);
slaxemulator@13173 191 @@ -1328,23 +1290,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events,
slaxemulator@13173 192 if (unlikely (status))
slaxemulator@13173 193 goto unwind;
slaxemulator@13173 194
slaxemulator@13173 195 - /* check to see if this is a continuation of a stopped edge */
slaxemulator@13173 196 - /* XXX change to an infinitesimal lengthening rule */
slaxemulator@13173 197 - for (left = sweep_line.stopped; left; left = left->next) {
slaxemulator@13173 198 - if (e1->edge.top <= left->edge.bottom &&
slaxemulator@13173 199 - edges_colinear (e1, left))
slaxemulator@13173 200 - {
slaxemulator@13173 201 - e1->deferred = left->deferred;
slaxemulator@13173 202 - if (left->prev != NULL)
slaxemulator@13173 203 - left->prev = left->next;
slaxemulator@13173 204 - else
slaxemulator@13173 205 - sweep_line.stopped = left->next;
slaxemulator@13173 206 - if (left->next != NULL)
slaxemulator@13173 207 - left->next->prev = left->prev;
slaxemulator@13173 208 - break;
slaxemulator@13173 209 - }
slaxemulator@13173 210 - }
slaxemulator@13173 211 -
slaxemulator@13173 212 left = e1->prev;
slaxemulator@13173 213 right = e1->next;
slaxemulator@13173 214
slaxemulator@13173 215 @@ -1371,14 +1316,8 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events,
slaxemulator@13173 216
slaxemulator@13173 217 _cairo_bo_sweep_line_delete (&sweep_line, e1);
slaxemulator@13173 218
slaxemulator@13173 219 - /* first, check to see if we have a continuation via a fresh edge */
slaxemulator@13173 220 - if (e1->deferred.right != NULL) {
slaxemulator@13173 221 - e1->next = sweep_line.stopped;
slaxemulator@13173 222 - if (sweep_line.stopped != NULL)
slaxemulator@13173 223 - sweep_line.stopped->prev = e1;
slaxemulator@13173 224 - sweep_line.stopped = e1;
slaxemulator@13173 225 - e1->prev = NULL;
slaxemulator@13173 226 - }
slaxemulator@13173 227 + if (e1->deferred.right != NULL)
slaxemulator@13173 228 + _cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
slaxemulator@13173 229
slaxemulator@13173 230 if (left != NULL && right != NULL) {
slaxemulator@13173 231 status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
slaxemulator@13173 232 @@ -1420,10 +1359,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events,
slaxemulator@13173 233 }
slaxemulator@13173 234 }
slaxemulator@13173 235
slaxemulator@13173 236 - for (e1 = sweep_line.stopped; e1; e1 = e1->next) {
slaxemulator@13173 237 - if (e1->deferred.right != NULL)
slaxemulator@13173 238 - _cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
slaxemulator@13173 239 - }
slaxemulator@13173 240 unwind:
slaxemulator@13173 241 _cairo_bo_event_queue_fini (&event_queue);
slaxemulator@13173 242
slaxemulator@13173 243 @@ -1447,6 +1382,12 @@ _cairo_polygon_reduce (cairo_polygon_t *polygon,
slaxemulator@13173 244 if (unlikely (0 == num_events))
slaxemulator@13173 245 return CAIRO_STATUS_SUCCESS;
slaxemulator@13173 246
slaxemulator@13173 247 + if (DEBUG_POLYGON) {
slaxemulator@13173 248 + FILE *file = fopen ("reduce_in.txt", "w");
slaxemulator@13173 249 + _cairo_debug_print_polygon (file, polygon);
slaxemulator@13173 250 + fclose (file);
slaxemulator@13173 251 + }
slaxemulator@13173 252 +
slaxemulator@13173 253 events = stack_events;
slaxemulator@13173 254 event_ptrs = stack_event_ptrs;
slaxemulator@13173 255 if (num_events > ARRAY_LENGTH (stack_events)) {
slaxemulator@13173 256 @@ -1482,10 +1423,16 @@ _cairo_polygon_reduce (cairo_polygon_t *polygon,
slaxemulator@13173 257 num_events,
slaxemulator@13173 258 fill_rule,
slaxemulator@13173 259 polygon);
slaxemulator@13173 260 - polygon->num_limits = num_limits;
slaxemulator@13173 261 + polygon->num_limits = num_limits;
slaxemulator@13173 262
slaxemulator@13173 263 if (events != stack_events)
slaxemulator@13173 264 free (events);
slaxemulator@13173 265
slaxemulator@13173 266 + if (DEBUG_POLYGON) {
slaxemulator@13173 267 + FILE *file = fopen ("reduce_out.txt", "w");
slaxemulator@13173 268 + _cairo_debug_print_polygon (file, polygon);
slaxemulator@13173 269 + fclose (file);
slaxemulator@13173 270 + }
slaxemulator@13173 271 +
slaxemulator@13173 272 return status;
slaxemulator@13173 273 }
slaxemulator@13173 274 --
slaxemulator@13173 275 cgit v0.9.0.2-2-gbebe