Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/core/SkScan_Path.cpp

Issue 692583002: WIP: GPU-accelerated trapezoidal path renderer. Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rename GrTrapezoidalPathRenderer -> GrAAConcavePathRenderer; swap MSAA support for a coverage ramp. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkScan_AntiPath.cpp ('k') | src/core/SkStroke.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkScanPriv.h" 8 #include "SkScanPriv.h"
9 #include "SkBlitter.h" 9 #include "SkBlitter.h"
10 #include "SkEdge.h" 10 #include "SkEdge.h"
11 #include "SkEdgeBuilder.h" 11 #include "SkEdgeBuilder.h"
12 #include "SkGeometry.h" 12 #include "SkGeometry.h"
13 #include "SkPath.h" 13 #include "SkPath.h"
14 #include "SkQuadClipper.h" 14 #include "SkQuadClipper.h"
15 #include "SkRasterClip.h" 15 #include "SkRasterClip.h"
16 #include "SkRegion.h" 16 #include "SkRegion.h"
17 #include "SkStroke.h"
17 #include "SkTemplates.h" 18 #include "SkTemplates.h"
18 #include "SkTSort.h" 19 #include "SkTSort.h"
19 20
21 #include <stdio.h> // FIXME
22
23 static bool dumping;
24
20 #define kEDGE_HEAD_Y SK_MinS32 25 #define kEDGE_HEAD_Y SK_MinS32
21 #define kEDGE_TAIL_Y SK_MaxS32 26 #define kEDGE_TAIL_Y SK_MaxS32
22 27
23 #ifdef SK_DEBUG 28 #ifdef SK_DEBUG
24 static void validate_sort(const SkEdge* edge) { 29 static void validate_sort(const SkEdge* edge) {
25 int y = kEDGE_HEAD_Y; 30 int y = kEDGE_HEAD_Y;
26 31
27 while (edge->fFirstY != SK_MaxS32) { 32 while (edge->fFirstY != SK_MaxS32) {
28 edge->validate(); 33 edge->validate();
29 SkASSERT(y <= edge->fFirstY); 34 SkASSERT(y <= edge->fFirstY);
(...skipping 11 matching lines...) Expand all
41 edge->fNext->fPrev = edge->fPrev; 46 edge->fNext->fPrev = edge->fPrev;
42 } 47 }
43 48
44 static inline void insert_edge_after(SkEdge* edge, SkEdge* afterMe) { 49 static inline void insert_edge_after(SkEdge* edge, SkEdge* afterMe) {
45 edge->fPrev = afterMe; 50 edge->fPrev = afterMe;
46 edge->fNext = afterMe->fNext; 51 edge->fNext = afterMe->fNext;
47 afterMe->fNext->fPrev = edge; 52 afterMe->fNext->fPrev = edge;
48 afterMe->fNext = edge; 53 afterMe->fNext = edge;
49 } 54 }
50 55
56 static void emit_wireframe_triangle(SkPoint t[3], SkTDArray<SkPoint>* points) {
57 SkPoint *p = points->append(6);
58 p[0] = t[0];
59 p[1] = t[1];
60 p[2] = t[1];
61 p[3] = t[2];
62 p[4] = t[2];
63 p[5] = t[0];
64 }
65
66 static void emit_trapezoid(SkEdge* left, SkEdge* right, float top, float bottom, SkTDArray<SkPoint>* points)
67 {
68 // If this edge was already neutered by its partner, don't emit.
69 if (top > bottom) {
70 return;
71 }
72
73 if (!left || !right) {
74 return;
75 }
76
77 float top_left = left->fFirstXf;
78 float top_right = right->fFirstXf;
79 float bottom_left = left->fFirstXf + SkFixedToFloat(left->fDX * (bottom - to p));
80 float bottom_right = right->fFirstXf + SkFixedToFloat(right->fDX * (bottom - top));
81 if (dumping) {
82 printf("top %g bot %g tl %g tr %g bl %g br %g\n",
83 top, bottom, left->fFirstXf, right->fFirstXf, bottom_left, bottom _right);
84 }
85 if (SkScan::gWireframe) {
86 if (top_left == top_right) {
87 SkPoint p[3];
88 p[0] = SkPoint::Make(top_right, top);
89 p[1] = SkPoint::Make(bottom_right, bottom);
90 p[2] = SkPoint::Make(bottom_left , bottom);
91 emit_wireframe_triangle(p, points);
92 } else if (bottom_left == bottom_right) {
93 SkPoint p[3];
94 p[0] = SkPoint::Make(top_left, top);
95 p[1] = SkPoint::Make(top_right, top);
96 p[2] = SkPoint::Make(bottom_left, bottom);
97 emit_wireframe_triangle(p, points);
98 } else {
99 SkPoint p[3];
100 p[0] = SkPoint::Make(top_left, top);
101 p[1] = SkPoint::Make(top_right, top);
102 p[2] = SkPoint::Make(bottom_left , bottom);
103 emit_wireframe_triangle(p, points);
104 p[0] = SkPoint::Make(top_right, top);
105 p[1] = SkPoint::Make(bottom_right, bottom);
106 p[2] = SkPoint::Make(bottom_left , bottom);
107 emit_wireframe_triangle(p, points);
108 }
109 } else {
110 if (top_left == top_right) {
111 SkPoint *p = points->append(3);
112 p[0] = SkPoint::Make(top_right, top);
113 p[1] = SkPoint::Make(bottom_right, bottom);
114 p[2] = SkPoint::Make(bottom_left , bottom);
115 } else if (bottom_left == bottom_right) {
116 SkPoint *p = points->append(3);
117 p[0] = SkPoint::Make(top_left, top);
118 p[1] = SkPoint::Make(top_right, top);
119 p[2] = SkPoint::Make(bottom_left, bottom);
120 } else {
121 SkPoint *p = points->append(6);
122 p[0] = SkPoint::Make(top_left, top);
123 p[1] = SkPoint::Make(top_right, top);
124 p[2] = SkPoint::Make(bottom_left , bottom);
125 p[3] = SkPoint::Make(top_right, top);
126 p[4] = SkPoint::Make(bottom_right, bottom);
127 p[5] = SkPoint::Make(bottom_left , bottom);
128 }
129 }
130 left->fFirstXf = bottom_left;
131 left->fFirstYf = bottom;
132 right->fFirstXf = bottom_right;
133 right->fFirstYf = bottom;
134 }
135
136 static void emit_all_trapezoids(SkEdge* start, int windingMask, int curr_y, SkTD Array<SkPoint>* points)
137 {
138 int w = 0;
139 SkEdge* left = NULL;
140 for (SkEdge* edge = start; edge != NULL && edge->fFirstY < curr_y && edge->f FirstYf < curr_y; edge = edge->fNext) {
141 w += edge->fWinding;
142 if ((w & windingMask) == 0) {
143 SkASSERT(left);
144 emit_trapezoid(left, edge, left->fFirstYf, curr_y, points);
145 left = NULL;
146 } else if (!left) {
147 left = edge;
148 } else {
149 edge->fFirstXf += SkFixedToFloat(edge->fDX * (curr_y - edge->fFirstY f));
150 edge->fFirstYf = (float) curr_y;
151 }
152 }
153 }
154
51 static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, cur r_y)) { 155 static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, cur r_y)) {
52 SkFixed x = edge->fX; 156 SkFixed x = edge->fX;
53 157
54 SkEdge* prev = edge->fPrev; 158 SkEdge* prev = edge->fPrev;
55 while (prev->fX > x) { 159 while (prev->fX > x) {
56 prev = prev->fPrev; 160 prev = prev->fPrev;
57 } 161 }
58 if (prev->fNext != edge) { 162 if (prev->fNext != edge) {
59 remove_edge(edge); 163 remove_edge(edge);
60 insert_edge_after(edge, prev); 164 insert_edge_after(edge, prev);
(...skipping 29 matching lines...) Expand all
90 #if defined _WIN32 && _MSC_VER >= 1300 // disable warning : local variable used without having been initialized 194 #if defined _WIN32 && _MSC_VER >= 1300 // disable warning : local variable used without having been initialized
91 #pragma warning ( push ) 195 #pragma warning ( push )
92 #pragma warning ( disable : 4701 ) 196 #pragma warning ( disable : 4701 )
93 #endif 197 #endif
94 198
95 typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline); 199 typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline);
96 #define PREPOST_START true 200 #define PREPOST_START true
97 #define PREPOST_END false 201 #define PREPOST_END false
98 202
99 static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType, 203 static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType,
100 SkBlitter* blitter, int start_y, int stop_y, 204 SkBlitter* blitter, SkTDArray<SkPoint>* points,
101 PrePostProc proc, int rightClip) { 205 int start_y, int stop_y, PrePostProc proc, int rightClip) {
102 validate_sort(prevHead->fNext); 206 validate_sort(prevHead->fNext);
103 207
104 int curr_y = start_y; 208 int curr_y = start_y;
105 // returns 1 for evenodd, -1 for winding, regardless of inverse-ness 209 // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
106 int windingMask = (fillType & 1) ? 1 : -1; 210 int windingMask = (fillType & 1) ? 1 : -1;
107 211
108 for (;;) { 212 for (;;) {
109 int w = 0; 213 int w = 0;
110 int left SK_INIT_TO_AVOID_WARNING; 214 int left SK_INIT_TO_AVOID_WARNING;
111 bool in_interval = false; 215 bool in_interval = false;
112 SkEdge* currE = prevHead->fNext; 216 SkEdge* currE = prevHead->fNext;
113 SkFixed prevX = prevHead->fX; 217 SkFixed prevX = prevHead->fX;
114 218
115 validate_edges_for_y(currE, curr_y); 219 validate_edges_for_y(currE, curr_y);
116 220
117 if (proc) { 221 if (proc && blitter) {
118 proc(blitter, curr_y, PREPOST_START); // pre-proc 222 proc(blitter, curr_y, PREPOST_START); // pre-proc
119 } 223 }
120 224
121 while (currE->fFirstY <= curr_y) { 225 while (currE->fFirstY <= curr_y) {
122 SkASSERT(currE->fLastY >= curr_y); 226 SkASSERT(currE->fLastY >= curr_y);
123 227
124 int x = SkFixedRoundToInt(currE->fX); 228 int x = SkFixedRoundToInt(currE->fX);
125 w += currE->fWinding; 229 w += currE->fWinding;
126 if ((w & windingMask) == 0) { // we finished an interval 230 if ((w & windingMask) == 0) { // we finished an interval
127 SkASSERT(in_interval); 231 SkASSERT(in_interval);
128 int width = x - left; 232 int width = x - left;
129 SkASSERT(width >= 0); 233 SkASSERT(width >= 0);
130 if (width) 234 if (width) {
131 blitter->blitH(left, curr_y, width); 235 if (blitter) {
236 blitter->blitH(left, curr_y, width);
237 }
238 }
132 in_interval = false; 239 in_interval = false;
133 } else if (!in_interval) { 240 } else if (!in_interval) {
134 left = x; 241 left = x;
135 in_interval = true; 242 in_interval = true;
136 } 243 }
137 244
138 SkEdge* next = currE->fNext; 245 SkEdge* next = currE->fNext;
139 SkFixed newX; 246 SkFixed newX;
140 247
141 if (currE->fLastY == curr_y) { // are we done with this edge? 248 if (currE->fLastY == curr_y) { // are we done with this edge?
249 if (points) emit_all_trapezoids(prevHead->fNext, windingMask, cu rr_y + 1, points);
142 if (currE->fCurveCount < 0) { 250 if (currE->fCurveCount < 0) {
143 if (((SkCubicEdge*)currE)->updateCubic()) { 251 if (((SkCubicEdge*)currE)->updateCubic()) {
144 SkASSERT(currE->fFirstY == curr_y + 1); 252 SkASSERT(currE->fFirstY == curr_y + 1);
145 253
146 newX = currE->fX; 254 newX = currE->fX;
147 goto NEXT_X; 255 goto NEXT_X;
148 } 256 }
149 } else if (currE->fCurveCount > 0) { 257 } else if (currE->fCurveCount > 0) {
150 if (((SkQuadraticEdge*)currE)->updateQuadratic()) { 258 if (((SkQuadraticEdge*)currE)->updateQuadratic()) {
151 newX = currE->fX; 259 newX = currE->fX;
152 goto NEXT_X; 260 goto NEXT_X;
153 } 261 }
154 } 262 }
155 remove_edge(currE); 263 remove_edge(currE);
156 } else { 264 } else {
157 SkASSERT(currE->fLastY > curr_y); 265 SkASSERT(currE->fLastY > curr_y);
158 newX = currE->fX + currE->fDX; 266 newX = currE->fX + currE->fDX;
159 currE->fX = newX; 267 currE->fX = newX;
160 NEXT_X: 268 NEXT_X:
161 if (newX < prevX) { // ripple currE backwards until it is x-sort ed 269 if (newX < prevX) { // ripple currE backwards until it is x-sort ed
270 if (points) emit_all_trapezoids(prevHead->fNext, windingMask , curr_y + 1, points);
162 backward_insert_edge_based_on_x(currE SkPARAM(curr_y)); 271 backward_insert_edge_based_on_x(currE SkPARAM(curr_y));
163 } else { 272 } else {
164 prevX = newX; 273 prevX = newX;
165 } 274 }
166 } 275 }
167 currE = next; 276 currE = next;
168 SkASSERT(currE); 277 SkASSERT(currE);
169 } 278 }
170 279
171 // was our right-edge culled away? 280 // was our right-edge culled away?
172 if (in_interval) { 281 if (in_interval && blitter) {
173 int width = rightClip - left; 282 int width = rightClip - left;
174 if (width > 0) { 283 if (width > 0) {
175 blitter->blitH(left, curr_y, width); 284 blitter->blitH(left, curr_y, width);
176 } 285 }
177 } 286 }
178 287
179 if (proc) { 288 if (proc && blitter) {
180 proc(blitter, curr_y, PREPOST_END); // post-proc 289 proc(blitter, curr_y, PREPOST_END); // post-proc
181 } 290 }
182 291
183 curr_y += 1; 292 curr_y += 1;
184 if (curr_y >= stop_y) { 293 if (curr_y >= stop_y) {
185 break; 294 break;
186 } 295 }
296 if (points && currE->fFirstY == curr_y) {
297 emit_all_trapezoids(prevHead->fNext, windingMask, curr_y, points);
298 }
187 // now currE points to the first edge with a Yint larger than curr_y 299 // now currE points to the first edge with a Yint larger than curr_y
188 insert_new_edges(currE, curr_y); 300 insert_new_edges(currE, curr_y);
189 } 301 }
190 } 302 }
191 303
192 // return true if we're done with this edge 304 // return true if we're done with this edge
193 static bool update_edge(SkEdge* edge, int last_y) { 305 static bool update_edge(SkEdge* edge, int last_y) {
194 SkASSERT(edge->fLastY >= last_y); 306 SkASSERT(edge->fLastY >= last_y);
195 if (last_y == edge->fLastY) { 307 if (last_y == edge->fLastY) {
196 if (edge->fCurveCount < 0) { 308 if (edge->fCurveCount < 0) {
197 if (((SkCubicEdge*)edge)->updateCubic()) { 309 if (((SkCubicEdge*)edge)->updateCubic()) {
198 SkASSERT(edge->fFirstY == last_y + 1); 310 SkASSERT(edge->fFirstY == last_y + 1);
199 return false; 311 return false;
200 } 312 }
201 } else if (edge->fCurveCount > 0) { 313 } else if (edge->fCurveCount > 0) {
202 if (((SkQuadraticEdge*)edge)->updateQuadratic()) { 314 if (((SkQuadraticEdge*)edge)->updateQuadratic()) {
203 SkASSERT(edge->fFirstY == last_y + 1); 315 SkASSERT(edge->fFirstY == last_y + 1);
204 return false; 316 return false;
205 } 317 }
206 } 318 }
207 return true; 319 return true;
208 } 320 }
209 return false; 321 return false;
210 } 322 }
211 323
212 static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, 324 static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType,
213 SkBlitter* blitter, int start_y, int stop_y, 325 SkBlitter* blitter, SkTDArray<SkPoint>* points,
326 int start_y, int stop_y,
214 PrePostProc proc) { 327 PrePostProc proc) {
215 validate_sort(prevHead->fNext); 328 validate_sort(prevHead->fNext);
216 329
217 SkEdge* leftE = prevHead->fNext; 330 SkEdge* leftE = prevHead->fNext;
218 SkEdge* riteE = leftE->fNext; 331 SkEdge* riteE = leftE->fNext;
219 SkEdge* currE = riteE->fNext; 332 SkEdge* currE = riteE->fNext;
220 333
221 #if 0 334 #if 0
222 int local_top = leftE->fFirstY; 335 int local_top = leftE->fFirstY;
223 SkASSERT(local_top == riteE->fFirstY); 336 SkASSERT(local_top == riteE->fFirstY);
(...skipping 16 matching lines...) Expand all
240 int local_bot = SkMin32(leftE->fLastY, riteE->fLastY); 353 int local_bot = SkMin32(leftE->fLastY, riteE->fLastY);
241 local_bot = SkMin32(local_bot, stop_y - 1); 354 local_bot = SkMin32(local_bot, stop_y - 1);
242 SkASSERT(local_top <= local_bot); 355 SkASSERT(local_top <= local_bot);
243 356
244 SkFixed left = leftE->fX; 357 SkFixed left = leftE->fX;
245 SkFixed dLeft = leftE->fDX; 358 SkFixed dLeft = leftE->fDX;
246 SkFixed rite = riteE->fX; 359 SkFixed rite = riteE->fX;
247 SkFixed dRite = riteE->fDX; 360 SkFixed dRite = riteE->fDX;
248 int count = local_bot - local_top; 361 int count = local_bot - local_top;
249 SkASSERT(count >= 0); 362 SkASSERT(count >= 0);
250 if (0 == (dLeft | dRite)) { 363 if (points) {
364 emit_trapezoid(leftE, riteE, (float) local_top, (float) (local_bot + 1), points);
365 if (left < rite) {
366 count += 1;
367 left += count * dLeft;
368 rite += count * dRite;
369 }
370 local_top = local_bot + 1;
371 } else if (0 == (dLeft | dRite)) {
251 int L = SkFixedRoundToInt(left); 372 int L = SkFixedRoundToInt(left);
252 int R = SkFixedRoundToInt(rite); 373 int R = SkFixedRoundToInt(rite);
253 if (L < R) { 374 if (L < R) {
254 count += 1; 375 count += 1;
255 blitter->blitRect(L, local_top, R - L, count); 376 blitter->blitRect(L, local_top, R - L, count);
377 left += count * dLeft;
378 rite += count * dRite;
256 } 379 }
257 local_top = local_bot + 1; 380 local_top = local_bot + 1;
258 } else { 381 } else {
259 do { 382 do {
260 int L = SkFixedRoundToInt(left); 383 int L = SkFixedRoundToInt(left);
261 int R = SkFixedRoundToInt(rite); 384 int R = SkFixedRoundToInt(rite);
262 if (L < R) { 385 if (L < R) {
263 blitter->blitH(L, local_top, R - L); 386 blitter->blitH(L, local_top, R - L);
264 } 387 }
265 left += dLeft; 388 left += dLeft;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 510
388 *last = list[count - 1]; 511 *last = list[count - 1];
389 return list[0]; 512 return list[0];
390 } 513 }
391 514
392 // clipRect may be null, even though we always have a clip. This indicates that 515 // clipRect may be null, even though we always have a clip. This indicates that
393 // the path is contained in the clip, and so we can ignore it during the blit 516 // the path is contained in the clip, and so we can ignore it during the blit
394 // 517 //
395 // clipRect (if no null) has already been shifted up 518 // clipRect (if no null) has already been shifted up
396 // 519 //
397 void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte r, 520 void sk_fill_path(const SkPath& path, const SkIRect* clipRect,
398 int start_y, int stop_y, int shiftEdgesUp, const SkRegion& cli pRgn) { 521 SkBlitter* blitter, SkTDArray<SkPoint>* points,
399 SkASSERT(blitter); 522 int start_y, int stop_y, int shiftEdgesUp,
523 const SkRegion& clipRgn) {
524 SkASSERT(blitter || points);
400 525
401 SkEdgeBuilder builder; 526 SkEdgeBuilder builder;
402 527
403 // If we're convex, then we need both edges, even the right edge is past the clip 528 // If we're convex, then we need both edges, even the right edge is past the clip
404 const bool canCullToTheRight = !path.isConvex(); 529 const bool canCullToTheRight = !path.isConvex() && !points;
405 530
406 int count = builder.build(path, clipRect, shiftEdgesUp, canCullToTheRight); 531 int count = builder.build(path, clipRect, shiftEdgesUp, canCullToTheRight);
407 SkASSERT(count >= 0); 532 SkASSERT(count >= 0);
408 533
409 SkEdge** list = builder.edgeList(); 534 SkEdge** list = builder.edgeList();
410 535
411 if (0 == count) { 536 if (0 == count) {
412 if (path.isInverseFillType()) { 537 if (path.isInverseFillType()) {
413 /* 538 /*
414 * Since we are in inverse-fill, our caller has already drawn above 539 * Since we are in inverse-fill, our caller has already drawn above
415 * our top (start_y) and will draw below our bottom (stop_y). Thus 540 * our top (start_y) and will draw below our bottom (stop_y). Thus
416 * we need to restrict our drawing to the intersection of the clip 541 * we need to restrict our drawing to the intersection of the clip
417 * and those two limits. 542 * and those two limits.
418 */ 543 */
419 SkIRect rect = clipRgn.getBounds(); 544 SkIRect rect = clipRgn.getBounds();
420 if (rect.fTop < start_y) { 545 if (rect.fTop < start_y) {
421 rect.fTop = start_y; 546 rect.fTop = start_y;
422 } 547 }
423 if (rect.fBottom > stop_y) { 548 if (rect.fBottom > stop_y) {
424 rect.fBottom = stop_y; 549 rect.fBottom = stop_y;
425 } 550 }
426 if (!rect.isEmpty()) { 551 if (!rect.isEmpty()) {
427 blitter->blitRect(rect.fLeft << shiftEdgesUp, 552 if (blitter) {
428 rect.fTop << shiftEdgesUp, 553 blitter->blitRect(rect.fLeft << shiftEdgesUp,
429 rect.width() << shiftEdgesUp, 554 rect.fTop << shiftEdgesUp,
430 rect.height() << shiftEdgesUp); 555 rect.width() << shiftEdgesUp,
556 rect.height() << shiftEdgesUp);
557 } else {
558 SkRect r = SkRect::Make(rect);
559 r.toQuad(points->append(4));
560 }
431 } 561 }
432 } 562 }
563
433 return; 564 return;
434 } 565 }
435 566
436 SkEdge headEdge, tailEdge, *last; 567 SkEdge headEdge, tailEdge, *last;
437 // this returns the first and last edge after they're sorted into a dlink li st 568 // this returns the first and last edge after they're sorted into a dlink li st
438 SkEdge* edge = sort_edges(list, count, &last); 569 SkEdge* edge = sort_edges(list, count, &last);
570 if (dumping) {
571 printf("sorted into %d edges:\n", count);
572 SkEdge* e = edge;
573 for (int i = 0; i < count; i++) {
574 printf("edge %p fFirstXf %g fFirstYf %g fLastY %d fDX %g\n", e, e->f FirstXf, e->fFirstYf, e->fLastY, e->fDX / 65536.0);
575 e = e->fNext;
576 }
577 }
439 578
440 headEdge.fPrev = nullptr; 579 headEdge.fPrev = nullptr;
441 headEdge.fNext = edge; 580 headEdge.fNext = edge;
442 headEdge.fFirstY = kEDGE_HEAD_Y; 581 headEdge.fFirstY = kEDGE_HEAD_Y;
443 headEdge.fX = SK_MinS32; 582 headEdge.fX = SK_MinS32;
444 edge->fPrev = &headEdge; 583 edge->fPrev = &headEdge;
445 584
446 tailEdge.fPrev = last; 585 tailEdge.fPrev = last;
447 tailEdge.fNext = nullptr; 586 tailEdge.fNext = nullptr;
448 tailEdge.fFirstY = kEDGE_TAIL_Y; 587 tailEdge.fFirstY = kEDGE_TAIL_Y;
449 last->fNext = &tailEdge; 588 last->fNext = &tailEdge;
450 589
451 // now edge is the head of the sorted linklist 590 // now edge is the head of the sorted linklist
452 591
453 start_y <<= shiftEdgesUp; 592 start_y <<= shiftEdgesUp;
454 stop_y <<= shiftEdgesUp; 593 stop_y <<= shiftEdgesUp;
455 if (clipRect && start_y < clipRect->fTop) { 594 if (clipRect && start_y < clipRect->fTop) {
456 start_y = clipRect->fTop; 595 start_y = clipRect->fTop;
457 } 596 }
458 if (clipRect && stop_y > clipRect->fBottom) { 597 if (clipRect && stop_y > clipRect->fBottom) {
459 stop_y = clipRect->fBottom; 598 stop_y = clipRect->fBottom;
460 } 599 }
461 600
462 InverseBlitter ib; 601 InverseBlitter ib;
463 PrePostProc proc = nullptr; 602 PrePostProc proc = nullptr;
464 603
465 if (path.isInverseFillType()) { 604 if (path.isInverseFillType() && blitter) {
466 ib.setBlitter(blitter, clipRgn.getBounds(), shiftEdgesUp); 605 ib.setBlitter(blitter, clipRgn.getBounds(), shiftEdgesUp);
467 blitter = &ib; 606 blitter = &ib;
468 proc = PrePostInverseBlitterProc; 607 proc = PrePostInverseBlitterProc;
469 } 608 }
470 609
471 if (path.isConvex() && (nullptr == proc)) { 610 if (path.isConvex() && (nullptr == proc) && blitter) {
472 SkASSERT(count >= 2); // convex walker does not handle missing right e dges 611 SkASSERT(count >= 2); // convex walker does not handle missing right e dges
473 walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_ y, nullptr); 612 walk_convex_edges(&headEdge, path.getFillType(), blitter, points, start_ y, stop_y, NULL);
474 } else { 613 } else {
475 int rightEdge; 614 int rightEdge;
476 if (clipRect) { 615 if (clipRect) {
477 rightEdge = clipRect->right(); 616 rightEdge = clipRect->right();
478 } else { 617 } else {
479 rightEdge = SkScalarRoundToInt(path.getBounds().right()) << shiftEdg esUp; 618 rightEdge = SkScalarRoundToInt(path.getBounds().right()) << shiftEdg esUp;
480 } 619 }
481 620
482 walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc , rightEdge); 621 walk_edges(&headEdge, path.getFillType(), blitter, points, start_y, stop _y, proc, rightEdge);
483 } 622 }
484 } 623 }
485 624
486 void sk_blit_above(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip) { 625 void sk_blit_above(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip) {
487 const SkIRect& cr = clip.getBounds(); 626 const SkIRect& cr = clip.getBounds();
488 SkIRect tmp; 627 SkIRect tmp;
489 628
490 tmp.fLeft = cr.fLeft; 629 tmp.fLeft = cr.fLeft;
491 tmp.fRight = cr.fRight; 630 tmp.fRight = cr.fRight;
492 tmp.fTop = cr.fTop; 631 tmp.fTop = cr.fTop;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 731
593 SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType()); 732 SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType());
594 733
595 blitter = clipper.getBlitter(); 734 blitter = clipper.getBlitter();
596 if (blitter) { 735 if (blitter) {
597 // we have to keep our calls to blitter in sorted order, so we 736 // we have to keep our calls to blitter in sorted order, so we
598 // must blit the above section first, then the middle, then the bottom. 737 // must blit the above section first, then the middle, then the bottom.
599 if (path.isInverseFillType()) { 738 if (path.isInverseFillType()) {
600 sk_blit_above(blitter, ir, *clipPtr); 739 sk_blit_above(blitter, ir, *clipPtr);
601 } 740 }
602 sk_fill_path(path, clipper.getClipRect(), blitter, ir.fTop, ir.fBottom, 741 sk_fill_path(path, clipper.getClipRect(), blitter, NULL, ir.fTop, ir.fBo ttom,
603 0, *clipPtr); 742 0, *clipPtr);
604 if (path.isInverseFillType()) { 743 if (path.isInverseFillType()) {
605 sk_blit_below(blitter, ir, *clipPtr); 744 sk_blit_below(blitter, ir, *clipPtr);
606 } 745 }
607 } else { 746 } else {
608 // what does it mean to not have a blitter if path.isInverseFillType??? 747 // what does it mean to not have a blitter if path.isInverseFillType???
609 } 748 }
610 } 749 }
611 750
612 void SkScan::FillPath(const SkPath& path, const SkIRect& ir, 751 void SkScan::FillPath(const SkPath& path, const SkIRect& ir,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 805
667 // now edge is the head of the sorted linklist 806 // now edge is the head of the sorted linklist
668 int stop_y = ir.fBottom; 807 int stop_y = ir.fBottom;
669 if (clipRect && stop_y > clipRect->fBottom) { 808 if (clipRect && stop_y > clipRect->fBottom) {
670 stop_y = clipRect->fBottom; 809 stop_y = clipRect->fBottom;
671 } 810 }
672 int start_y = ir.fTop; 811 int start_y = ir.fTop;
673 if (clipRect && start_y < clipRect->fTop) { 812 if (clipRect && start_y < clipRect->fTop) {
674 start_y = clipRect->fTop; 813 start_y = clipRect->fTop;
675 } 814 }
676 walk_convex_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, st op_y, nullptr); 815 walk_convex_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, nullptr, st art_y, stop_y, nullptr);
677 // walk_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, nullptr); 816 // walk_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, NULL);
678 } 817 }
679 818
680 void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, 819 void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip,
681 SkBlitter* blitter) { 820 SkBlitter* blitter) {
682 if (clip.isEmpty()) { 821 if (clip.isEmpty()) {
683 return; 822 return;
684 } 823 }
685 824
686 SkRect r; 825 SkRect r;
687 SkIRect ir; 826 SkIRect ir;
(...skipping 12 matching lines...) Expand all
700 clipRgn = &wrap.getRgn(); 839 clipRgn = &wrap.getRgn();
701 blitter = wrap.getBlitter(); 840 blitter = wrap.getBlitter();
702 } 841 }
703 842
704 SkScanClipper clipper(blitter, clipRgn, ir); 843 SkScanClipper clipper(blitter, clipRgn, ir);
705 blitter = clipper.getBlitter(); 844 blitter = clipper.getBlitter();
706 if (blitter) { 845 if (blitter) {
707 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir); 846 sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir);
708 } 847 }
709 } 848 }
849
850 void SkScan::PathToTriangles(const SkPath& path, const SkIRect& clipBounds,
851 bool antiAlias, SkTDArray<SkPoint>* points) {
852 // dumping = true;
853 // printf("*** SkScan::PathToTriangles start\n");
854 points->setReserve(path.countPoints());
855 SkPath localPath = path;
856 SkIRect localClipBounds = clipBounds;
857 if (antiAlias) {
858 // Stroke 1-pix wide around path.
859 SkStroke stroker;
860 stroker.setJoin(SkPaint::kMiter_Join);
861 stroker.setWidth(5);
862 SkPath strokedPath;
863 // We want even open paths to become closed, so we can fill them.
864 stroker.setAutoClose(true);
865 // Don't reverse the inner path direction, since want the interior to be filled.
866 stroker.setReverseInner(false);
867 stroker.strokePath(localPath, &strokedPath);
868 localPath = strokedPath;
869 }
870 SkRect pathBounds = localPath.getBounds();
871 SkRegion clipRgn(localClipBounds);
872 if (localPath.isInverseFillType()) {
873 localPath.addRect(SkRect::Make(localClipBounds), SkPath::kCCW_Direction) ;
874 sk_fill_path(localPath, &localClipBounds, NULL, points,
875 localClipBounds.top(), localClipBounds.bottom(), 0,
876 clipRgn);
877 } else {
878 sk_fill_path(localPath, &localClipBounds, NULL, points,
879 pathBounds.top() - 1, pathBounds.bottom() + 1, 0,
880 clipRgn);
881 }
882 // printf("*** SkScan::PathToTriangles end\n");
883 // dumping = false;
884 }
OLDNEW
« no previous file with comments | « src/core/SkScan_AntiPath.cpp ('k') | src/core/SkStroke.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698