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