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

Side by Side Diff: src/gpu/GrTessellator.cpp

Issue 1152733009: Screenspace AA tessellated path rendering. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Cleanup, and fix call to PathToTriangles(). Created 4 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
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 "GrTessellator.h" 8 #include "GrTessellator.h"
9 9
10 #include "GrDefaultGeoProcFactory.h"
10 #include "GrPathUtils.h" 11 #include "GrPathUtils.h"
11 12
12 #include "SkChunkAlloc.h" 13 #include "SkChunkAlloc.h"
13 #include "SkGeometry.h" 14 #include "SkGeometry.h"
14 #include "SkPath.h" 15 #include "SkPath.h"
15 16
16 #include <stdio.h> 17 #include <stdio.h>
17 18
18 /* 19 /*
19 * There are six stages to the algorithm: 20 * There are six stages to the algorithm:
bsalomon 2016/08/31 14:19:19 Can you update this to document the AA steps?
Stephen White 2016/08/31 15:16:38 Done.
20 * 21 *
21 * 1) Linearize the path contours into piecewise linear segments (path_to_contou rs()). 22 * 1) Linearize the path contours into piecewise linear segments (path_to_contou rs()).
22 * 2) Build a mesh of edges connecting the vertices (build_edges()). 23 * 2) Build a mesh of edges connecting the vertices (build_edges()).
23 * 3) Sort the vertices in Y (and secondarily in X) (merge_sort()). 24 * 3) Sort the vertices in Y (and secondarily in X) (merge_sort()).
24 * 4) Simplify the mesh by inserting new vertices at intersecting edges (simplif y()). 25 * 4) Simplify the mesh by inserting new vertices at intersecting edges (simplif y()).
25 * 5) Tessellate the simplified mesh into monotone polygons (tessellate()). 26 * 5) Tessellate the simplified mesh into monotone polygons (tessellate()).
26 * 6) Triangulate the monotone polygons directly into a vertex buffer (polys_to_ triangles()). 27 * 6) Triangulate the monotone polygons directly into a vertex buffer (polys_to_ triangles()).
27 * 28 *
28 * The vertex sorting in step (3) is a merge sort, since it plays well with the linked list 29 * The vertex sorting in step (3) is a merge sort, since it plays well with the linked list
29 * of vertices (and the necessity of inserting new vertices on intersection). 30 * of vertices (and the necessity of inserting new vertices on intersection).
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 * circularly-linked list of Vertices for each contour. After edge construction, the same Vertices 124 * circularly-linked list of Vertices for each contour. After edge construction, the same Vertices
124 * are re-ordered by the merge sort according to the sweep_lt comparator (usuall y, increasing 125 * are re-ordered by the merge sort according to the sweep_lt comparator (usuall y, increasing
125 * in Y) using the same fPrev/fNext pointers that were used for the contours, to avoid 126 * in Y) using the same fPrev/fNext pointers that were used for the contours, to avoid
126 * reallocation. Finally, MonotonePolys are built containing a circularly-linked list of 127 * reallocation. Finally, MonotonePolys are built containing a circularly-linked list of
127 * Vertices. (Currently, those Vertices are newly-allocated for the MonotonePoly s, since 128 * Vertices. (Currently, those Vertices are newly-allocated for the MonotonePoly s, since
128 * an individual Vertex from the path mesh may belong to multiple 129 * an individual Vertex from the path mesh may belong to multiple
129 * MonotonePolys, so the original Vertices cannot be re-used. 130 * MonotonePolys, so the original Vertices cannot be re-used.
130 */ 131 */
131 132
132 struct Vertex { 133 struct Vertex {
133 Vertex(const SkPoint& point) 134 Vertex(const SkPoint& point, uint8_t alpha)
134 : fPoint(point), fPrev(nullptr), fNext(nullptr) 135 : fPoint(point), fPrev(nullptr), fNext(nullptr)
135 , fFirstEdgeAbove(nullptr), fLastEdgeAbove(nullptr) 136 , fFirstEdgeAbove(nullptr), fLastEdgeAbove(nullptr)
136 , fFirstEdgeBelow(nullptr), fLastEdgeBelow(nullptr) 137 , fFirstEdgeBelow(nullptr), fLastEdgeBelow(nullptr)
137 , fProcessed(false) 138 , fProcessed(false)
139 , fAlpha(alpha)
138 #if LOGGING_ENABLED 140 #if LOGGING_ENABLED
139 , fID (-1.0f) 141 , fID (-1.0f)
140 #endif 142 #endif
141 {} 143 {}
142 SkPoint fPoint; // Vertex position 144 SkPoint fPoint; // Vertex position
143 Vertex* fPrev; // Linked list of contours, then Y-sorted vertices . 145 Vertex* fPrev; // Linked list of contours, then Y-sorted vertices .
144 Vertex* fNext; // " 146 Vertex* fNext; // "
145 Edge* fFirstEdgeAbove; // Linked list of edges above this vertex. 147 Edge* fFirstEdgeAbove; // Linked list of edges above this vertex.
146 Edge* fLastEdgeAbove; // " 148 Edge* fLastEdgeAbove; // "
147 Edge* fFirstEdgeBelow; // Linked list of edges below this vertex. 149 Edge* fFirstEdgeBelow; // Linked list of edges below this vertex.
148 Edge* fLastEdgeBelow; // " 150 Edge* fLastEdgeBelow; // "
149 bool fProcessed; // Has this vertex been seen in simplify()? 151 bool fProcessed; // Has this vertex been seen in simplify()?
152 uint8_t fAlpha;
150 #if LOGGING_ENABLED 153 #if LOGGING_ENABLED
151 float fID; // Identifier used for logging. 154 float fID; // Identifier used for logging.
152 #endif 155 #endif
153 }; 156 };
154 157
155 /******************************************************************************* ********/ 158 /******************************************************************************* ********/
156 159
160 struct AAParams {
161 bool fTweakAlpha;
162 GrColor fColor;
163 };
164
157 typedef bool (*CompareFunc)(const SkPoint& a, const SkPoint& b); 165 typedef bool (*CompareFunc)(const SkPoint& a, const SkPoint& b);
158 166
159 struct Comparator { 167 struct Comparator {
160 CompareFunc sweep_lt; 168 CompareFunc sweep_lt;
161 CompareFunc sweep_gt; 169 CompareFunc sweep_gt;
162 }; 170 };
163 171
164 bool sweep_lt_horiz(const SkPoint& a, const SkPoint& b) { 172 bool sweep_lt_horiz(const SkPoint& a, const SkPoint& b) {
165 return a.fX == b.fX ? a.fY > b.fY : a.fX < b.fX; 173 return a.fX == b.fX ? a.fY > b.fY : a.fX < b.fX;
166 } 174 }
167 175
168 bool sweep_lt_vert(const SkPoint& a, const SkPoint& b) { 176 bool sweep_lt_vert(const SkPoint& a, const SkPoint& b) {
169 return a.fY == b.fY ? a.fX < b.fX : a.fY < b.fY; 177 return a.fY == b.fY ? a.fX < b.fX : a.fY < b.fY;
170 } 178 }
171 179
172 bool sweep_gt_horiz(const SkPoint& a, const SkPoint& b) { 180 bool sweep_gt_horiz(const SkPoint& a, const SkPoint& b) {
173 return a.fX == b.fX ? a.fY < b.fY : a.fX > b.fX; 181 return a.fX == b.fX ? a.fY < b.fY : a.fX > b.fX;
174 } 182 }
175 183
176 bool sweep_gt_vert(const SkPoint& a, const SkPoint& b) { 184 bool sweep_gt_vert(const SkPoint& a, const SkPoint& b) {
177 return a.fY == b.fY ? a.fX > b.fX : a.fY > b.fY; 185 return a.fY == b.fY ? a.fX > b.fX : a.fY > b.fY;
178 } 186 }
179 187
180 inline SkPoint* emit_vertex(Vertex* v, SkPoint* data) { 188 inline void* emit_vertex(Vertex* v, const AAParams* aaParams, void* data) {
181 *data++ = v->fPoint; 189 if (!aaParams) {
182 return data; 190 SkPoint* d = static_cast<SkPoint*>(data);
191 *d++ = v->fPoint;
192 return d;
193 }
194 if (aaParams->fTweakAlpha) {
195 auto d = static_cast<GrDefaultGeoProcFactory::PositionColorAttr*>(data);
196 d->fPosition = v->fPoint;
197 d->fColor = SkAlphaMulQ(aaParams->fColor, v->fAlpha);
198 d++;
199 return d;
200 }
201 auto d = static_cast<GrDefaultGeoProcFactory::PositionColorCoverageAttr*>(da ta);
202 d->fPosition = v->fPoint;
203 d->fColor = aaParams->fColor;
204 d->fCoverage = GrNormalizeByteToFloat(v->fAlpha);
205 d++;
206 return d;
183 } 207 }
184 208
185 SkPoint* emit_triangle(Vertex* v0, Vertex* v1, Vertex* v2, SkPoint* data) { 209 void* emit_triangle(Vertex* v0, Vertex* v1, Vertex* v2, const AAParams* aaParams , void* data) {
186 #if WIREFRAME 210 #if TESSELLATOR_WIREFRAME
187 data = emit_vertex(v0, data); 211 data = emit_vertex(v0, aaParams, data);
188 data = emit_vertex(v1, data); 212 data = emit_vertex(v1, aaParams, data);
189 data = emit_vertex(v1, data); 213 data = emit_vertex(v1, aaParams, data);
190 data = emit_vertex(v2, data); 214 data = emit_vertex(v2, aaParams, data);
191 data = emit_vertex(v2, data); 215 data = emit_vertex(v2, aaParams, data);
192 data = emit_vertex(v0, data); 216 data = emit_vertex(v0, aaParams, data);
193 #else 217 #else
194 data = emit_vertex(v0, data); 218 data = emit_vertex(v0, aaParams, data);
195 data = emit_vertex(v1, data); 219 data = emit_vertex(v1, aaParams, data);
196 data = emit_vertex(v2, data); 220 data = emit_vertex(v2, aaParams, data);
197 #endif 221 #endif
198 return data; 222 return data;
199 } 223 }
200 224
201 struct EdgeList {
202 EdgeList() : fHead(nullptr), fTail(nullptr) {}
203 Edge* fHead;
204 Edge* fTail;
205 };
206
207 struct VertexList { 225 struct VertexList {
208 VertexList() : fHead(nullptr), fTail(nullptr) {} 226 VertexList() : fHead(nullptr), fTail(nullptr) {}
209 Vertex* fHead; 227 Vertex* fHead;
210 Vertex* fTail; 228 Vertex* fTail;
211 void insert(Vertex* v, Vertex* prev, Vertex* next) { 229 void insert(Vertex* v, Vertex* prev, Vertex* next) {
212 list_insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, prev, next, &fHea d, &fTail); 230 list_insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, prev, next, &fHea d, &fTail);
213 } 231 }
214 void append(Vertex* v) { 232 void append(Vertex* v) {
215 insert(v, fTail, nullptr); 233 insert(v, fTail, nullptr);
216 } 234 }
217 void prepend(Vertex* v) { 235 void prepend(Vertex* v) {
218 insert(v, nullptr, fHead); 236 insert(v, nullptr, fHead);
219 } 237 }
238 void close() {
239 if (fHead && fTail) {
240 fTail->fNext = fHead;
241 fHead->fPrev = fTail;
242 }
243 }
220 }; 244 };
221 245
246 inline void round(SkPoint* p) {
bsalomon 2016/08/31 14:19:19 Is this rounding to 1/4 pixel values?
Stephen White 2016/08/31 15:16:38 Yes; added a comment.
247 p->fX = SkScalarRoundToScalar(p->fX * SkFloatToScalar(4.0f)) * SkFloatToScal ar(0.25f);
248 p->fY = SkScalarRoundToScalar(p->fY * SkFloatToScalar(4.0f)) * SkFloatToScal ar(0.25f);
249 }
250
222 /** 251 /**
223 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of "edges above" and 252 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of "edges above" and
224 * "edge below" a vertex as well as for the active edge list is handled by isLef tOf()/isRightOf(). 253 * "edge below" a vertex as well as for the active edge list is handled by isLef tOf()/isRightOf().
225 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b ecause floating 254 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b ecause floating
226 * point). For speed, that case is only tested by the callers which require it ( e.g., 255 * point). For speed, that case is only tested by the callers which require it ( e.g.,
227 * cleanup_active_edges()). Edges also handle checking for intersection with oth er edges. 256 * cleanup_active_edges()). Edges also handle checking for intersection with oth er edges.
228 * Currently, this converts the edges to the parametric form, in order to avoid doing a division 257 * Currently, this converts the edges to the parametric form, in order to avoid doing a division
229 * until an intersection has been confirmed. This is slightly slower in the "fou nd" case, but 258 * until an intersection has been confirmed. This is slightly slower in the "fou nd" case, but
230 * a lot faster in the "not found" case. 259 * a lot faster in the "not found" case.
231 * 260 *
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 if (denom > 0.0 ? (sNumer < 0.0 || sNumer > denom || tNumer < 0.0 || tNu mer > denom) 342 if (denom > 0.0 ? (sNumer < 0.0 || sNumer > denom || tNumer < 0.0 || tNu mer > denom)
314 : (sNumer > 0.0 || sNumer < denom || tNumer > 0.0 || tNu mer < denom)) { 343 : (sNumer > 0.0 || sNumer < denom || tNumer > 0.0 || tNu mer < denom)) {
315 return false; 344 return false;
316 } 345 }
317 double s = sNumer / denom; 346 double s = sNumer / denom;
318 SkASSERT(s >= 0.0 && s <= 1.0); 347 SkASSERT(s >= 0.0 && s <= 1.0);
319 p->fX = SkDoubleToScalar(fTop->fPoint.fX + s * fDX); 348 p->fX = SkDoubleToScalar(fTop->fPoint.fX + s * fDX);
320 p->fY = SkDoubleToScalar(fTop->fPoint.fY + s * fDY); 349 p->fY = SkDoubleToScalar(fTop->fPoint.fY + s * fDY);
321 return true; 350 return true;
322 } 351 }
323 bool isActive(EdgeList* activeEdges) const { 352 };
324 return activeEdges && (fLeft || fRight || activeEdges->fHead == this); 353
354 struct EdgeList {
355 EdgeList() : fHead(nullptr), fTail(nullptr), fNext(nullptr), fCount(0) {}
356 Edge* fHead;
357 Edge* fTail;
358 EdgeList* fNext;
359 int fCount;
360 void insert(Edge* edge, Edge* prev, Edge* next) {
361 list_insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &fHead, &fTail);
362 fCount++;
363 }
364 void append(Edge* e) {
365 insert(e, fTail, nullptr);
366 }
367 void remove(Edge* edge) {
368 list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &fHead, &fTail);
369 fCount--;
370 }
371 void close() {
372 if (fHead && fTail) {
373 fTail->fRight = fHead;
374 fHead->fLeft = fTail;
375 }
376 }
377 bool contains(Edge* edge) const {
378 return edge->fLeft || edge->fRight || fHead == edge;
325 } 379 }
326 }; 380 };
327 381
328 /******************************************************************************* ********/ 382 /******************************************************************************* ********/
329 383
330 struct Poly { 384 struct Poly {
331 Poly(Vertex* v, int winding) 385 Poly(Vertex* v, int winding)
332 : fFirstVertex(v) 386 : fFirstVertex(v)
333 , fWinding(winding) 387 , fWinding(winding)
334 , fHead(nullptr) 388 , fHead(nullptr)
(...skipping 30 matching lines...) Expand all
365 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge); 419 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge);
366 edge->fUsedInRightPoly = true; 420 edge->fUsedInRightPoly = true;
367 } else { 421 } else {
368 SkASSERT(!edge->fUsedInLeftPoly); 422 SkASSERT(!edge->fUsedInLeftPoly);
369 list_insert<Edge, &Edge::fLeftPolyPrev, &Edge::fLeftPolyNext>( 423 list_insert<Edge, &Edge::fLeftPolyPrev, &Edge::fLeftPolyNext>(
370 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge); 424 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge);
371 edge->fUsedInLeftPoly = true; 425 edge->fUsedInLeftPoly = true;
372 } 426 }
373 } 427 }
374 428
375 SkPoint* emit(SkPoint* data) { 429 void* emit(const AAParams* aaParams, void* data) {
376 Edge* e = fFirstEdge; 430 Edge* e = fFirstEdge;
377 e->fTop->fPrev = e->fTop->fNext = nullptr; 431 e->fTop->fPrev = e->fTop->fNext = nullptr;
378 VertexList vertices; 432 VertexList vertices;
379 vertices.append(e->fTop); 433 vertices.append(e->fTop);
380 while (e != nullptr) { 434 while (e != nullptr) {
381 e->fBottom->fPrev = e->fBottom->fNext = nullptr; 435 e->fBottom->fPrev = e->fBottom->fNext = nullptr;
382 if (kRight_Side == fSide) { 436 if (kRight_Side == fSide) {
383 vertices.append(e->fBottom); 437 vertices.append(e->fBottom);
384 e = e->fRightPolyNext; 438 e = e->fRightPolyNext;
385 } else { 439 } else {
386 vertices.prepend(e->fBottom); 440 vertices.prepend(e->fBottom);
387 e = e->fLeftPolyNext; 441 e = e->fLeftPolyNext;
388 } 442 }
389 } 443 }
390 Vertex* first = vertices.fHead; 444 Vertex* first = vertices.fHead;
391 Vertex* v = first->fNext; 445 Vertex* v = first->fNext;
392 while (v != vertices.fTail) { 446 while (v != vertices.fTail) {
393 SkASSERT(v && v->fPrev && v->fNext); 447 SkASSERT(v && v->fPrev && v->fNext);
394 Vertex* prev = v->fPrev; 448 Vertex* prev = v->fPrev;
395 Vertex* curr = v; 449 Vertex* curr = v;
396 Vertex* next = v->fNext; 450 Vertex* next = v->fNext;
397 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint. fX; 451 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint. fX;
398 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint. fY; 452 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint. fY;
399 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint. fX; 453 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint. fX;
400 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint. fY; 454 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint. fY;
401 if (ax * by - ay * bx >= 0.0) { 455 if (ax * by - ay * bx >= 0.0) {
402 data = emit_triangle(prev, curr, next, data); 456 data = emit_triangle(prev, curr, next, aaParams, data);
403 v->fPrev->fNext = v->fNext; 457 v->fPrev->fNext = v->fNext;
404 v->fNext->fPrev = v->fPrev; 458 v->fNext->fPrev = v->fPrev;
405 if (v->fPrev == first) { 459 if (v->fPrev == first) {
406 v = v->fNext; 460 v = v->fNext;
407 } else { 461 } else {
408 v = v->fPrev; 462 v = v->fPrev;
409 } 463 }
410 } else { 464 } else {
411 v = v->fNext; 465 v = v->fNext;
412 } 466 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 poly = partner; 502 poly = partner;
449 } else { 503 } else {
450 MonotonePoly* m = ALLOC_NEW(MonotonePoly, (e, side), alloc); 504 MonotonePoly* m = ALLOC_NEW(MonotonePoly, (e, side), alloc);
451 m->fPrev = fTail; 505 m->fPrev = fTail;
452 fTail->fNext = m; 506 fTail->fNext = m;
453 fTail = m; 507 fTail = m;
454 } 508 }
455 } 509 }
456 return poly; 510 return poly;
457 } 511 }
458 SkPoint* emit(SkPoint *data) { 512 void* emit(const AAParams* aaParams, void *data) {
459 if (fCount < 3) { 513 if (fCount < 3) {
460 return data; 514 return data;
461 } 515 }
462 LOG("emit() %d, size %d\n", fID, fCount); 516 LOG("emit() %d, size %d\n", fID, fCount);
463 for (MonotonePoly* m = fHead; m != nullptr; m = m->fNext) { 517 for (MonotonePoly* m = fHead; m != nullptr; m = m->fNext) {
464 data = m->emit(data); 518 data = m->emit(aaParams, data);
465 } 519 }
466 return data; 520 return data;
467 } 521 }
468 Vertex* lastVertex() const { return fTail ? fTail->fLastEdge->fBottom : fFir stVertex; } 522 Vertex* lastVertex() const { return fTail ? fTail->fLastEdge->fBottom : fFir stVertex; }
469 Vertex* fFirstVertex; 523 Vertex* fFirstVertex;
470 int fWinding; 524 int fWinding;
471 MonotonePoly* fHead; 525 MonotonePoly* fHead;
472 MonotonePoly* fTail; 526 MonotonePoly* fTail;
473 Poly* fNext; 527 Poly* fNext;
474 Poly* fPartner; 528 Poly* fPartner;
475 int fCount; 529 int fCount;
476 #if LOGGING_ENABLED 530 #if LOGGING_ENABLED
477 int fID; 531 int fID;
478 #endif 532 #endif
479 }; 533 };
480 534
481 /******************************************************************************* ********/ 535 /******************************************************************************* ********/
482 536
483 bool coincident(const SkPoint& a, const SkPoint& b) { 537 bool coincident(const SkPoint& a, const SkPoint& b) {
484 return a == b; 538 return a == b;
485 } 539 }
486 540
487 Poly* new_poly(Poly** head, Vertex* v, int winding, SkChunkAlloc& alloc) { 541 Poly* new_poly(Poly** head, Vertex* v, int winding, SkChunkAlloc& alloc) {
488 Poly* poly = ALLOC_NEW(Poly, (v, winding), alloc); 542 Poly* poly = ALLOC_NEW(Poly, (v, winding), alloc);
489 poly->fNext = *head; 543 poly->fNext = *head;
490 *head = poly; 544 *head = poly;
491 return poly; 545 return poly;
492 } 546 }
493 547
548 EdgeList* new_contour(EdgeList** head, SkChunkAlloc& alloc) {
549 EdgeList* contour = ALLOC_NEW(EdgeList, (), alloc);
550 contour->fNext = *head;
551 *head = contour;
552 return contour;
553 }
554
494 Vertex* append_point_to_contour(const SkPoint& p, Vertex* prev, Vertex** head, 555 Vertex* append_point_to_contour(const SkPoint& p, Vertex* prev, Vertex** head,
495 SkChunkAlloc& alloc) { 556 SkChunkAlloc& alloc) {
496 Vertex* v = ALLOC_NEW(Vertex, (p), alloc); 557 Vertex* v = ALLOC_NEW(Vertex, (p, 255), alloc);
497 #if LOGGING_ENABLED 558 #if LOGGING_ENABLED
498 static float gID = 0.0f; 559 static float gID = 0.0f;
499 v->fID = gID++; 560 v->fID = gID++;
500 #endif 561 #endif
501 if (prev) { 562 if (prev) {
502 prev->fNext = v; 563 prev->fNext = v;
503 v->fPrev = prev; 564 v->fPrev = prev;
504 } else { 565 } else {
505 *head = v; 566 *head = v;
506 } 567 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 632
572 SkPoint pts[4]; 633 SkPoint pts[4];
573 bool done = false; 634 bool done = false;
574 *isLinear = true; 635 *isLinear = true;
575 SkPath::Iter iter(path, false); 636 SkPath::Iter iter(path, false);
576 Vertex* prev = nullptr; 637 Vertex* prev = nullptr;
577 Vertex* head = nullptr; 638 Vertex* head = nullptr;
578 if (path.isInverseFillType()) { 639 if (path.isInverseFillType()) {
579 SkPoint quad[4]; 640 SkPoint quad[4];
580 clipBounds.toQuad(quad); 641 clipBounds.toQuad(quad);
581 for (int i = 3; i >= 0; i--) { 642 for (int i = 0; i < 4; i++) {
582 prev = append_point_to_contour(quad[i], prev, &head, alloc); 643 prev = append_point_to_contour(quad[i], prev, &head, alloc);
583 } 644 }
584 head->fPrev = prev; 645 head->fPrev = prev;
585 prev->fNext = head; 646 prev->fNext = head;
586 *contours++ = head; 647 *contours++ = head;
587 head = prev = nullptr; 648 head = prev = nullptr;
588 } 649 }
589 SkAutoConicToQuads converter; 650 SkAutoConicToQuads converter;
590 while (!done) { 651 while (!done) {
591 SkPath::Verb verb = iter.next(pts); 652 SkPath::Verb verb = iter.next(pts);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 head->fPrev = prev; 703 head->fPrev = prev;
643 prev->fNext = head; 704 prev->fNext = head;
644 *contours++ = head; 705 *contours++ = head;
645 } 706 }
646 done = true; 707 done = true;
647 break; 708 break;
648 } 709 }
649 } 710 }
650 } 711 }
651 712
652 inline bool apply_fill_type(SkPath::FillType fillType, int winding) { 713 inline bool apply_fill_type(SkPath::FillType fillType, Poly* poly) {
714 if (!poly) {
715 return false;
716 }
717 int winding = poly->fWinding;
653 switch (fillType) { 718 switch (fillType) {
654 case SkPath::kWinding_FillType: 719 case SkPath::kWinding_FillType:
655 return winding != 0; 720 return winding != 0;
656 case SkPath::kEvenOdd_FillType: 721 case SkPath::kEvenOdd_FillType:
657 return (winding & 1) != 0; 722 return (winding & 1) != 0;
658 case SkPath::kInverseWinding_FillType: 723 case SkPath::kInverseWinding_FillType:
659 return winding == 1; 724 return winding == -1;
660 case SkPath::kInverseEvenOdd_FillType: 725 case SkPath::kInverseEvenOdd_FillType:
661 return (winding & 1) == 1; 726 return (winding & 1) == 1;
662 default: 727 default:
663 SkASSERT(false); 728 SkASSERT(false);
664 return false; 729 return false;
665 } 730 }
666 } 731 }
667 732
668 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c) { 733 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c,
669 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; 734 int winding_scale = 1) {
735 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? winding_scale : -wind ing_scale;
670 Vertex* top = winding < 0 ? next : prev; 736 Vertex* top = winding < 0 ? next : prev;
671 Vertex* bottom = winding < 0 ? prev : next; 737 Vertex* bottom = winding < 0 ? prev : next;
672 return ALLOC_NEW(Edge, (top, bottom, winding), alloc); 738 return ALLOC_NEW(Edge, (top, bottom, winding), alloc);
673 } 739 }
674 740
675 void remove_edge(Edge* edge, EdgeList* edges) { 741 void remove_edge(Edge* edge, EdgeList* edges) {
676 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); 742 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID);
677 SkASSERT(edge->isActive(edges)); 743 SkASSERT(edges->contains(edge));
678 list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &edges->fHead, &edges-> fTail); 744 edges->remove(edge);
679 } 745 }
680 746
681 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) { 747 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) {
682 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); 748 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID);
683 SkASSERT(!edge->isActive(edges)); 749 SkASSERT(!edges->contains(edge));
684 Edge* next = prev ? prev->fRight : edges->fHead; 750 Edge* next = prev ? prev->fRight : edges->fHead;
685 list_insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &edges->fHe ad, &edges->fTail); 751 edges->insert(edge, prev, next);
686 } 752 }
687 753
688 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right) { 754 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right) {
689 if (v->fFirstEdgeAbove) { 755 if (v->fFirstEdgeAbove) {
690 *left = v->fFirstEdgeAbove->fLeft; 756 *left = v->fFirstEdgeAbove->fLeft;
691 *right = v->fLastEdgeAbove->fRight; 757 *right = v->fLastEdgeAbove->fRight;
692 return; 758 return;
693 } 759 }
694 Edge* next = nullptr; 760 Edge* next = nullptr;
695 Edge* prev; 761 Edge* prev;
(...skipping 19 matching lines...) Expand all
715 edge->isLeftOf(next->fBottom))) { 781 edge->isLeftOf(next->fBottom))) {
716 break; 782 break;
717 } 783 }
718 prev = next; 784 prev = next;
719 } 785 }
720 *left = prev; 786 *left = prev;
721 *right = next; 787 *right = next;
722 } 788 }
723 789
724 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) { 790 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) {
725 if (edge->isActive(activeEdges)) { 791 if (activeEdges && activeEdges->contains(edge)) {
726 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { 792 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) {
727 remove_edge(edge, activeEdges); 793 remove_edge(edge, activeEdges);
728 } 794 }
729 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { 795 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) {
730 Edge* left; 796 Edge* left;
731 Edge* right; 797 Edge* right;
732 find_enclosing_edges(edge, activeEdges, c, &left, &right); 798 find_enclosing_edges(edge, activeEdges, c, &left, &right);
733 insert_edge(edge, left, activeEdges); 799 insert_edge(edge, left, activeEdges);
734 } 800 }
735 } 801 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); 850 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow);
785 } 851 }
786 852
787 void erase_edge_if_zero_winding(Edge* edge, EdgeList* edges) { 853 void erase_edge_if_zero_winding(Edge* edge, EdgeList* edges) {
788 if (edge->fWinding != 0) { 854 if (edge->fWinding != 0) {
789 return; 855 return;
790 } 856 }
791 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); 857 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID);
792 remove_edge_above(edge); 858 remove_edge_above(edge);
793 remove_edge_below(edge); 859 remove_edge_below(edge);
794 if (edge->isActive(edges)) { 860 if (edges && edges->contains(edge)) {
795 remove_edge(edge, edges); 861 remove_edge(edge, edges);
796 } 862 }
797 } 863 }
798 864
799 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Comparator& c); 865 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Comparator& c);
800 866
801 void set_top(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c) { 867 void set_top(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c) {
802 remove_edge_below(edge); 868 remove_edge_below(edge);
803 edge->fTop = v; 869 edge->fTop = v;
804 edge->recompute(); 870 edge->recompute();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 Edge* newEdge = ALLOC_NEW(Edge, (v, edge->fBottom, edge->fWinding), allo c); 987 Edge* newEdge = ALLOC_NEW(Edge, (v, edge->fBottom, edge->fWinding), allo c);
922 insert_edge_below(newEdge, v, c); 988 insert_edge_below(newEdge, v, c);
923 insert_edge_above(newEdge, edge->fBottom, c); 989 insert_edge_above(newEdge, edge->fBottom, c);
924 set_bottom(edge, v, activeEdges, c); 990 set_bottom(edge, v, activeEdges, c);
925 cleanup_active_edges(edge, activeEdges, c, alloc); 991 cleanup_active_edges(edge, activeEdges, c, alloc);
926 fix_active_state(newEdge, activeEdges, c); 992 fix_active_state(newEdge, activeEdges, c);
927 merge_collinear_edges(newEdge, activeEdges, c); 993 merge_collinear_edges(newEdge, activeEdges, c);
928 } 994 }
929 } 995 }
930 996
997 Edge* connect(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator c,
998 int winding_scale = 1) {
999 Edge* edge = new_edge(prev, next, alloc, c, winding_scale);
1000 if (edge->fWinding > 0) {
1001 insert_edge_below(edge, prev, c);
1002 insert_edge_above(edge, next, c);
1003 } else {
1004 insert_edge_below(edge, next, c);
1005 insert_edge_above(edge, prev, c);
1006 }
1007 merge_collinear_edges(edge, nullptr, c);
1008 return edge;
1009 }
1010
931 void merge_vertices(Vertex* src, Vertex* dst, Vertex** head, Comparator& c, SkCh unkAlloc& alloc) { 1011 void merge_vertices(Vertex* src, Vertex* dst, Vertex** head, Comparator& c, SkCh unkAlloc& alloc) {
932 LOG("found coincident verts at %g, %g; merging %g into %g\n", src->fPoint.fX , src->fPoint.fY, 1012 LOG("found coincident verts at %g, %g; merging %g into %g\n", src->fPoint.fX , src->fPoint.fY,
933 src->fID, dst->fID); 1013 src->fID, dst->fID);
1014 dst->fAlpha = SkTMax(src->fAlpha, dst->fAlpha);
934 for (Edge* edge = src->fFirstEdgeAbove; edge;) { 1015 for (Edge* edge = src->fFirstEdgeAbove; edge;) {
935 Edge* next = edge->fNextEdgeAbove; 1016 Edge* next = edge->fNextEdgeAbove;
936 set_bottom(edge, dst, nullptr, c); 1017 set_bottom(edge, dst, nullptr, c);
937 edge = next; 1018 edge = next;
938 } 1019 }
939 for (Edge* edge = src->fFirstEdgeBelow; edge;) { 1020 for (Edge* edge = src->fFirstEdgeBelow; edge;) {
940 Edge* next = edge->fNextEdgeBelow; 1021 Edge* next = edge->fNextEdgeBelow;
941 set_top(edge, dst, nullptr, c); 1022 set_top(edge, dst, nullptr, c);
942 edge = next; 1023 edge = next;
943 } 1024 }
944 list_remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, nullptr); 1025 list_remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, nullptr);
945 } 1026 }
946 1027
1028 uint8_t max_edge_alpha(Edge* a, Edge* b) {
1029 return SkTMax(SkTMax(a->fTop->fAlpha, a->fBottom->fAlpha),
1030 SkTMax(b->fTop->fAlpha, b->fBottom->fAlpha));
1031 }
1032
947 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C omparator& c, 1033 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C omparator& c,
948 SkChunkAlloc& alloc) { 1034 SkChunkAlloc& alloc) {
949 SkPoint p; 1035 SkPoint p;
950 if (!edge || !other) { 1036 if (!edge || !other) {
951 return nullptr; 1037 return nullptr;
952 } 1038 }
953 if (edge->intersect(*other, &p)) { 1039 if (edge->intersect(*other, &p)) {
954 Vertex* v; 1040 Vertex* v;
955 LOG("found intersection, pt is %g, %g\n", p.fX, p.fY); 1041 LOG("found intersection, pt is %g, %g\n", p.fX, p.fY);
956 if (p == edge->fTop->fPoint || c.sweep_lt(p, edge->fTop->fPoint)) { 1042 if (p == edge->fTop->fPoint || c.sweep_lt(p, edge->fTop->fPoint)) {
(...skipping 15 matching lines...) Expand all
972 } 1058 }
973 while (c.sweep_lt(nextV->fPoint, p)) { 1059 while (c.sweep_lt(nextV->fPoint, p)) {
974 nextV = nextV->fNext; 1060 nextV = nextV->fNext;
975 } 1061 }
976 Vertex* prevV = nextV->fPrev; 1062 Vertex* prevV = nextV->fPrev;
977 if (coincident(prevV->fPoint, p)) { 1063 if (coincident(prevV->fPoint, p)) {
978 v = prevV; 1064 v = prevV;
979 } else if (coincident(nextV->fPoint, p)) { 1065 } else if (coincident(nextV->fPoint, p)) {
980 v = nextV; 1066 v = nextV;
981 } else { 1067 } else {
982 v = ALLOC_NEW(Vertex, (p), alloc); 1068 uint8_t alpha = max_edge_alpha(edge, other);
1069 v = ALLOC_NEW(Vertex, (p, alpha), alloc);
983 LOG("inserting between %g (%g, %g) and %g (%g, %g)\n", 1070 LOG("inserting between %g (%g, %g) and %g (%g, %g)\n",
984 prevV->fID, prevV->fPoint.fX, prevV->fPoint.fY, 1071 prevV->fID, prevV->fPoint.fX, prevV->fPoint.fY,
985 nextV->fID, nextV->fPoint.fX, nextV->fPoint.fY); 1072 nextV->fID, nextV->fPoint.fX, nextV->fPoint.fY);
986 #if LOGGING_ENABLED 1073 #if LOGGING_ENABLED
987 v->fID = (nextV->fID + prevV->fID) * 0.5f; 1074 v->fID = (nextV->fID + prevV->fID) * 0.5f;
988 #endif 1075 #endif
989 v->fPrev = prevV; 1076 v->fPrev = prevV;
990 v->fNext = nextV; 1077 v->fNext = nextV;
991 prevV->fNext = v; 1078 prevV->fNext = v;
992 nextV->fPrev = v; 1079 nextV->fPrev = v;
993 } 1080 }
994 split_edge(edge, v, activeEdges, c, alloc); 1081 split_edge(edge, v, activeEdges, c, alloc);
995 split_edge(other, v, activeEdges, c, alloc); 1082 split_edge(other, v, activeEdges, c, alloc);
996 } 1083 }
997 return v; 1084 return v;
998 } 1085 }
999 return nullptr; 1086 return nullptr;
1000 } 1087 }
1001 1088
1002 void sanitize_contours(Vertex** contours, int contourCnt) { 1089 void sanitize_contours(Vertex** contours, int contourCnt, bool approximate) {
1003 for (int i = 0; i < contourCnt; ++i) { 1090 for (int i = 0; i < contourCnt; ++i) {
1004 SkASSERT(contours[i]); 1091 SkASSERT(contours[i]);
1005 for (Vertex* v = contours[i];;) { 1092 for (Vertex* v = contours[i];;) {
1093 if (approximate) {
1094 round(&v->fPoint);
1095 }
1006 if (coincident(v->fPrev->fPoint, v->fPoint)) { 1096 if (coincident(v->fPrev->fPoint, v->fPoint)) {
1007 LOG("vertex %g,%g coincident; removing\n", v->fPoint.fX, v->fPoi nt.fY); 1097 LOG("vertex %g,%g coincident; removing\n", v->fPoint.fX, v->fPoi nt.fY);
1008 if (v->fPrev == v) { 1098 if (v->fPrev == v) {
1009 contours[i] = nullptr; 1099 contours[i] = nullptr;
1010 break; 1100 break;
1011 } 1101 }
1012 v->fPrev->fNext = v->fNext; 1102 v->fPrev->fNext = v->fNext;
1013 v->fNext->fPrev = v->fPrev; 1103 v->fNext->fPrev = v->fPrev;
1014 if (contours[i] == v) { 1104 if (contours[i] == v) {
1015 contours[i] = v->fNext; 1105 contours[i] = v->fNext;
(...skipping 19 matching lines...) Expand all
1035 } 1125 }
1036 1126
1037 // Stage 2: convert the contours to a mesh of edges connecting the vertices. 1127 // Stage 2: convert the contours to a mesh of edges connecting the vertices.
1038 1128
1039 Vertex* build_edges(Vertex** contours, int contourCnt, Comparator& c, SkChunkAll oc& alloc) { 1129 Vertex* build_edges(Vertex** contours, int contourCnt, Comparator& c, SkChunkAll oc& alloc) {
1040 Vertex* vertices = nullptr; 1130 Vertex* vertices = nullptr;
1041 Vertex* prev = nullptr; 1131 Vertex* prev = nullptr;
1042 for (int i = 0; i < contourCnt; ++i) { 1132 for (int i = 0; i < contourCnt; ++i) {
1043 for (Vertex* v = contours[i]; v != nullptr;) { 1133 for (Vertex* v = contours[i]; v != nullptr;) {
1044 Vertex* vNext = v->fNext; 1134 Vertex* vNext = v->fNext;
1045 Edge* edge = new_edge(v->fPrev, v, alloc, c); 1135 connect(v->fPrev, v, alloc, c);
1046 if (edge->fWinding > 0) {
1047 insert_edge_below(edge, v->fPrev, c);
1048 insert_edge_above(edge, v, c);
1049 } else {
1050 insert_edge_below(edge, v, c);
1051 insert_edge_above(edge, v->fPrev, c);
1052 }
1053 merge_collinear_edges(edge, nullptr, c);
1054 if (prev) { 1136 if (prev) {
1055 prev->fNext = v; 1137 prev->fNext = v;
1056 v->fPrev = prev; 1138 v->fPrev = prev;
1057 } else { 1139 } else {
1058 vertices = v; 1140 vertices = v;
1059 } 1141 }
1060 prev = v; 1142 prev = v;
1061 v = vNext; 1143 v = vNext;
1062 if (v == contours[i]) break; 1144 if (v == contours[i]) break;
1063 } 1145 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. 1220 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges.
1139 1221
1140 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) { 1222 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) {
1141 LOG("simplifying complex polygons\n"); 1223 LOG("simplifying complex polygons\n");
1142 EdgeList activeEdges; 1224 EdgeList activeEdges;
1143 for (Vertex* v = vertices; v != nullptr; v = v->fNext) { 1225 for (Vertex* v = vertices; v != nullptr; v = v->fNext) {
1144 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { 1226 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) {
1145 continue; 1227 continue;
1146 } 1228 }
1147 #if LOGGING_ENABLED 1229 #if LOGGING_ENABLED
1148 LOG("\nvertex %g: (%g,%g)\n", v->fID, v->fPoint.fX, v->fPoint.fY); 1230 LOG("\nvertex %g: (%g,%g), alpha %d\n", v->fID, v->fPoint.fX, v->fPoint. fY, v->fAlpha);
1149 #endif 1231 #endif
1150 Edge* leftEnclosingEdge = nullptr; 1232 Edge* leftEnclosingEdge = nullptr;
1151 Edge* rightEnclosingEdge = nullptr; 1233 Edge* rightEnclosingEdge = nullptr;
1152 bool restartChecks; 1234 bool restartChecks;
1153 do { 1235 do {
1154 restartChecks = false; 1236 restartChecks = false;
1155 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEncl osingEdge); 1237 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEncl osingEdge);
1156 if (v->fFirstEdgeBelow) { 1238 if (v->fFirstEdgeBelow) {
1157 for (Edge* edge = v->fFirstEdgeBelow; edge != nullptr; edge = ed ge->fNextEdgeBelow) { 1239 for (Edge* edge = v->fFirstEdgeBelow; edge != nullptr; edge = ed ge->fNextEdgeBelow) {
1158 if (check_for_intersection(edge, leftEnclosingEdge, &activeE dges, c, alloc)) { 1240 if (check_for_intersection(edge, leftEnclosingEdge, &activeE dges, c, alloc)) {
1159 restartChecks = true; 1241 restartChecks = true;
1160 break; 1242 break;
1161 } 1243 }
1162 if (check_for_intersection(edge, rightEnclosingEdge, &active Edges, c, alloc)) { 1244 if (check_for_intersection(edge, rightEnclosingEdge, &active Edges, c, alloc)) {
1163 restartChecks = true; 1245 restartChecks = true;
1164 break; 1246 break;
1165 } 1247 }
1166 } 1248 }
1167 } else { 1249 } else {
1168 if (Vertex* pv = check_for_intersection(leftEnclosingEdge, right EnclosingEdge, 1250 if (Vertex* pv = check_for_intersection(leftEnclosingEdge, right EnclosingEdge,
1169 &activeEdges, c, alloc)) { 1251 &activeEdges, c, alloc)) {
1170 if (c.sweep_lt(pv->fPoint, v->fPoint)) { 1252 if (c.sweep_lt(pv->fPoint, v->fPoint)) {
1171 v = pv; 1253 v = pv;
1172 } 1254 }
1173 restartChecks = true; 1255 restartChecks = true;
1174 } 1256 }
1175 1257
1176 } 1258 }
1177 } while (restartChecks); 1259 } while (restartChecks);
1260 if (v->fAlpha == 0) {
1261 if ((leftEnclosingEdge && leftEnclosingEdge->fWinding < 0) &&
1262 (rightEnclosingEdge && rightEnclosingEdge->fWinding > 0)) {
1263 v->fAlpha = max_edge_alpha(leftEnclosingEdge, rightEnclosingEdge );
1264 }
1265 }
1178 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) { 1266 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
1179 remove_edge(e, &activeEdges); 1267 remove_edge(e, &activeEdges);
1180 } 1268 }
1181 Edge* leftEdge = leftEnclosingEdge; 1269 Edge* leftEdge = leftEnclosingEdge;
1182 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { 1270 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
1183 insert_edge(e, leftEdge, &activeEdges); 1271 insert_edge(e, leftEdge, &activeEdges);
1184 leftEdge = e; 1272 leftEdge = e;
1185 } 1273 }
1186 v->fProcessed = true; 1274 v->fProcessed = true;
1187 } 1275 }
1188 } 1276 }
1189 1277
1190 // Stage 5: Tessellate the simplified mesh into monotone polygons. 1278 // Stage 5: Tessellate the simplified mesh into monotone polygons.
1191 1279
1192 Poly* tessellate(Vertex* vertices, SkChunkAlloc& alloc) { 1280 Poly* tessellate(Vertex* vertices, SkChunkAlloc& alloc) {
1193 LOG("tessellating simple polygons\n"); 1281 LOG("tessellating simple polygons\n");
1194 EdgeList activeEdges; 1282 EdgeList activeEdges;
1195 Poly* polys = nullptr; 1283 Poly* polys = nullptr;
1196 for (Vertex* v = vertices; v != nullptr; v = v->fNext) { 1284 for (Vertex* v = vertices; v != nullptr; v = v->fNext) {
1197 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { 1285 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) {
1198 continue; 1286 continue;
1199 } 1287 }
1200 #if LOGGING_ENABLED 1288 #if LOGGING_ENABLED
1201 LOG("\nvertex %g: (%g,%g)\n", v->fID, v->fPoint.fX, v->fPoint.fY); 1289 LOG("\nvertex %g: (%g,%g), alpha %d\n", v->fID, v->fPoint.fX, v->fPoint. fY, v->fAlpha);
1202 #endif 1290 #endif
1203 Edge* leftEnclosingEdge = nullptr; 1291 Edge* leftEnclosingEdge = nullptr;
1204 Edge* rightEnclosingEdge = nullptr; 1292 Edge* rightEnclosingEdge = nullptr;
1205 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosin gEdge); 1293 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosin gEdge);
1206 Poly* leftPoly = nullptr; 1294 Poly* leftPoly = nullptr;
1207 Poly* rightPoly = nullptr; 1295 Poly* rightPoly = nullptr;
1208 if (v->fFirstEdgeAbove) { 1296 if (v->fFirstEdgeAbove) {
1209 leftPoly = v->fFirstEdgeAbove->fLeftPoly; 1297 leftPoly = v->fFirstEdgeAbove->fLeftPoly;
1210 rightPoly = v->fLastEdgeAbove->fRightPoly; 1298 rightPoly = v->fLastEdgeAbove->fRightPoly;
1211 } else { 1299 } else {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 LOG("\nactive edges:\n"); 1379 LOG("\nactive edges:\n");
1292 for (Edge* e = activeEdges.fHead; e != nullptr; e = e->fRight) { 1380 for (Edge* e = activeEdges.fHead; e != nullptr; e = e->fRight) {
1293 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, 1381 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID,
1294 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight Poly->fID : -1); 1382 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight Poly->fID : -1);
1295 } 1383 }
1296 #endif 1384 #endif
1297 } 1385 }
1298 return polys; 1386 return polys;
1299 } 1387 }
1300 1388
1389 bool is_boundary_edge(Edge* edge, SkPath::FillType fillType) {
1390 return apply_fill_type(fillType, edge->fLeftPoly) !=
1391 apply_fill_type(fillType, edge->fRightPoly);
1392 }
1393
1394 bool is_boundary_start(Edge* edge, SkPath::FillType fillType) {
1395 return !apply_fill_type(fillType, edge->fLeftPoly) &&
1396 apply_fill_type(fillType, edge->fRightPoly);
1397 }
1398
1399 Vertex* remove_non_boundary_edges(Vertex* vertices, SkPath::FillType fillType,
1400 SkChunkAlloc& alloc) {
1401 for (Vertex* v = vertices; v != nullptr; v = v->fNext) {
1402 for (Edge* e = v->fFirstEdgeBelow; e != nullptr;) {
1403 Edge* next = e->fNextEdgeBelow;
1404 if (!is_boundary_edge(e, fillType)) {
1405 remove_edge_above(e);
1406 remove_edge_below(e);
1407 }
1408 e = next;
1409 }
1410 }
1411 return vertices;
1412 }
1413
1414 // This is different from Edge::intersect, in that it intersects lines, not line segments.
1415 bool intersect(const Edge& a, const Edge& b, SkPoint* point) {
1416 double denom = a.fDX * b.fDY - a.fDY * b.fDX;
1417 if (denom == 0.0) {
1418 return false;
1419 }
1420 double scale = 1.0f / denom;
1421 point->fX = SkDoubleToScalar((b.fDX * a.fC - a.fDX * b.fC) * scale);
1422 point->fY = SkDoubleToScalar((b.fDY * a.fC - a.fDY * b.fC) * scale);
1423 round(point);
1424 return true;
1425 }
1426
1427 void get_edge_normal(const Edge* e, SkVector* normal) {
1428 normal->setNormalize(SkDoubleToScalar(e->fDX) * e->fWinding,
1429 SkDoubleToScalar(e->fDY) * e->fWinding);
1430 }
1431
1432 void simplify_boundary(EdgeList* boundary, Comparator& c, SkChunkAlloc& alloc) {
1433 Edge* prevEdge = boundary->fTail;
1434 SkVector prevNormal;
1435 get_edge_normal(prevEdge, &prevNormal);
1436 for (Edge* e = boundary->fHead; e != nullptr;) {
1437 Vertex* prev = prevEdge->fWinding == 1 ? prevEdge->fTop : prevEdge->fBot tom;
1438 Vertex* next = e->fWinding == 1 ? e->fBottom : e->fTop;
1439 double dist = e->dist(prev->fPoint);
1440 SkVector normal;
1441 get_edge_normal(e, &normal);
1442 float denom = 0.25f * static_cast<float>(e->fDX * e->fDX + e->fDY * e->f DY);
1443 if (prevNormal.dot(normal) < 0.0 && (dist * dist) <= denom) {
1444 Edge* join = new_edge(prev, next, alloc, c);
1445 insert_edge(join, e, boundary);
1446 remove_edge(prevEdge, boundary);
1447 remove_edge(e, boundary);
1448 if (join->fLeft && join->fRight) {
1449 prevEdge = join->fLeft;
1450 e = join;
1451 } else {
1452 prevEdge = boundary->fTail;
1453 e = boundary->fHead; // join->fLeft ? join->fLeft : join;
1454 }
1455 get_edge_normal(prevEdge, &prevNormal);
1456 } else {
1457 prevEdge = e;
1458 prevNormal = normal;
1459 e = e->fRight;
1460 }
1461 }
1462 }
1463
1464 void boundary_to_aa_mesh(EdgeList* boundary, VertexList* mesh, Comparator& c, Sk ChunkAlloc& alloc) {
1465 EdgeList outerContour;
1466 Edge* prevEdge = boundary->fTail;
1467 float radius = 0.5f;
1468 double offset = radius * sqrt(prevEdge->fDX * prevEdge->fDX + prevEdge->fDY * prevEdge->fDY)
1469 * prevEdge->fWinding;
1470 Edge prevInner(prevEdge->fTop, prevEdge->fBottom, prevEdge->fWinding);
1471 prevInner.fC -= offset;
1472 Edge prevOuter(prevEdge->fTop, prevEdge->fBottom, prevEdge->fWinding);
1473 prevOuter.fC += offset;
1474 VertexList innerVertices;
1475 VertexList outerVertices;
1476 SkScalar innerCount = SK_Scalar1, outerCount = SK_Scalar1;
1477 for (Edge* e = boundary->fHead; e != nullptr; e = e->fRight) {
1478 double offset = radius * sqrt(e->fDX * e->fDX + e->fDY * e->fDY) * e->fW inding;
1479 Edge inner(e->fTop, e->fBottom, e->fWinding);
1480 inner.fC -= offset;
1481 Edge outer(e->fTop, e->fBottom, e->fWinding);
1482 outer.fC += offset;
1483 SkPoint innerPoint, outerPoint;
1484 if (intersect(prevInner, inner, &innerPoint) &&
1485 intersect(prevOuter, outer, &outerPoint)) {
1486 Vertex* innerVertex = ALLOC_NEW(Vertex, (innerPoint, 255), alloc);
1487 Vertex* outerVertex = ALLOC_NEW(Vertex, (outerPoint, 0), alloc);
1488 if (innerVertices.fTail && outerVertices.fTail) {
1489 Edge innerEdge(innerVertices.fTail, innerVertex, 1);
1490 Edge outerEdge(outerVertices.fTail, outerVertex, 1);
1491 SkVector innerNormal;
1492 get_edge_normal(&innerEdge, &innerNormal);
1493 SkVector outerNormal;
1494 get_edge_normal(&outerEdge, &outerNormal);
1495 SkVector normal;
1496 get_edge_normal(prevEdge, &normal);
1497 if (normal.dot(innerNormal) < 0) {
1498 innerPoint += innerVertices.fTail->fPoint * innerCount;
1499 innerCount++;
1500 innerPoint *= SkScalarInvert(innerCount);
1501 innerVertices.fTail->fPoint = innerVertex->fPoint = innerPoi nt;
1502 } else {
1503 innerCount = SK_Scalar1;
1504 }
1505 if (normal.dot(outerNormal) < 0) {
1506 outerPoint += outerVertices.fTail->fPoint * outerCount;
1507 outerCount++;
1508 outerPoint *= SkScalarInvert(outerCount);
1509 outerVertices.fTail->fPoint = outerVertex->fPoint = outerPoi nt;
1510 } else {
1511 outerCount = SK_Scalar1;
1512 }
1513 }
1514 innerVertices.append(innerVertex);
1515 outerVertices.append(outerVertex);
1516 prevEdge = e;
1517 }
1518 prevInner = inner;
1519 prevOuter = outer;
1520 }
1521 innerVertices.close();
1522 outerVertices.close();
1523
1524 Vertex* innerVertex = innerVertices.fHead;
1525 Vertex* outerVertex = outerVertices.fHead;
1526 // Alternate clockwise and counterclockwise polys, so the tesselator
1527 // doesn't cancel out the interior edges.
1528 if (!innerVertex || !outerVertex) {
1529 return;
1530 }
1531 do {
1532 connect(outerVertex->fNext, outerVertex, alloc, c);
1533 connect(innerVertex->fNext, innerVertex, alloc, c, 2);
1534 connect(innerVertex, outerVertex->fNext, alloc, c, 2);
1535 connect(outerVertex, innerVertex, alloc, c, 2);
1536 Vertex* innerNext = innerVertex->fNext;
1537 Vertex* outerNext = outerVertex->fNext;
1538 mesh->append(innerVertex);
1539 mesh->append(outerVertex);
1540 innerVertex = innerNext;
1541 outerVertex = outerNext;
1542 } while (innerVertex != innerVertices.fHead && outerVertex != outerVertices. fHead);
1543 }
1544
1545 void extract_boundary(EdgeList* boundary, Edge* e, SkPath::FillType fillType, Sk ChunkAlloc& alloc) {
1546 bool down = is_boundary_start(e, fillType);
1547 while (e) {
1548 e->fWinding = down ? 1 : -1;
1549 Edge* next;
1550 boundary->append(e);
1551 if (down) {
1552 // Find outgoing edge, in clockwise order.
1553 if ((next = e->fNextEdgeAbove)) {
1554 down = false;
1555 } else if ((next = e->fBottom->fLastEdgeBelow)) {
1556 down = true;
1557 } else if ((next = e->fPrevEdgeAbove)) {
1558 down = false;
1559 }
1560 } else {
1561 // Find outgoing edge, in counter-clockwise order.
1562 if ((next = e->fPrevEdgeBelow)) {
1563 down = true;
1564 } else if ((next = e->fTop->fFirstEdgeAbove)) {
1565 down = false;
1566 } else if ((next = e->fNextEdgeBelow)) {
1567 down = true;
1568 }
1569 }
1570 remove_edge_above(e);
1571 remove_edge_below(e);
1572 e = next;
1573 }
1574 }
1575
1576 // Stage 5b: Extract boundary edges.
1577
1578 EdgeList* extract_boundaries(Vertex* vertices, SkPath::FillType fillType, SkChun kAlloc& alloc) {
1579 LOG("extracting boundaries\n");
1580 vertices = remove_non_boundary_edges(vertices, fillType, alloc);
1581 EdgeList* boundaries = nullptr;
1582 for (Vertex* v = vertices; v != nullptr; v = v->fNext) {
1583 while (v->fFirstEdgeBelow) {
1584 EdgeList* boundary = new_contour(&boundaries, alloc);
1585 extract_boundary(boundary, v->fFirstEdgeBelow, fillType, alloc);
1586 }
1587 }
1588 return boundaries;
1589 }
1590
1301 // This is a driver function which calls stages 2-5 in turn. 1591 // This is a driver function which calls stages 2-5 in turn.
1302 1592
1303 Poly* contours_to_polys(Vertex** contours, int contourCnt, const SkRect& pathBou nds, 1593 Vertex* contours_to_mesh(Vertex** contours, int contourCnt, bool antialias,
1304 SkChunkAlloc& alloc) { 1594 Comparator& c, SkChunkAlloc& alloc) {
1305 Comparator c;
1306 if (pathBounds.width() > pathBounds.height()) {
1307 c.sweep_lt = sweep_lt_horiz;
1308 c.sweep_gt = sweep_gt_horiz;
1309 } else {
1310 c.sweep_lt = sweep_lt_vert;
1311 c.sweep_gt = sweep_gt_vert;
1312 }
1313 #if LOGGING_ENABLED 1595 #if LOGGING_ENABLED
1314 for (int i = 0; i < contourCnt; ++i) { 1596 for (int i = 0; i < contourCnt; ++i) {
1315 Vertex* v = contours[i]; 1597 Vertex* v = contours[i];
1316 SkASSERT(v); 1598 SkASSERT(v);
1317 LOG("path.moveTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); 1599 LOG("path.moveTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY);
1318 for (v = v->fNext; v != contours[i]; v = v->fNext) { 1600 for (v = v->fNext; v != contours[i]; v = v->fNext) {
1319 LOG("path.lineTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); 1601 LOG("path.lineTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY);
1320 } 1602 }
1321 } 1603 }
1322 #endif 1604 #endif
1323 sanitize_contours(contours, contourCnt); 1605 sanitize_contours(contours, contourCnt, antialias);
1324 Vertex* vertices = build_edges(contours, contourCnt, c, alloc); 1606 return build_edges(contours, contourCnt, c, alloc);
1325 if (!vertices) { 1607 }
1608
1609 Poly* mesh_to_polys(Vertex** vertices, SkPath::FillType fillType, Comparator& c,
1610 SkChunkAlloc& alloc) {
1611 if (!vertices || !*vertices) {
1326 return nullptr; 1612 return nullptr;
1327 } 1613 }
1328 1614
1329 // Sort vertices in Y (secondarily in X). 1615 // Sort vertices in Y (secondarily in X).
1330 merge_sort(&vertices, c); 1616 merge_sort(vertices, c);
1331 merge_coincident_vertices(&vertices, c, alloc); 1617 merge_coincident_vertices(vertices, c, alloc);
1332 #if LOGGING_ENABLED 1618 #if LOGGING_ENABLED
1333 for (Vertex* v = vertices; v != nullptr; v = v->fNext) { 1619 for (Vertex* v = *vertices; v != nullptr; v = v->fNext) {
1334 static float gID = 0.0f; 1620 static float gID = 0.0f;
1335 v->fID = gID++; 1621 v->fID = gID++;
1336 } 1622 }
1337 #endif 1623 #endif
1338 simplify(vertices, c, alloc); 1624 simplify(*vertices, c, alloc);
1339 return tessellate(vertices, alloc); 1625 return tessellate(*vertices, alloc);
1626 }
1627
1628 Poly* contours_to_polys(Vertex** contours, int contourCnt, SkPath::FillType fill Type,
1629 const SkRect& pathBounds, bool antialias,
1630 SkChunkAlloc& alloc) {
1631 Comparator c;
1632 if (pathBounds.width() > pathBounds.height()) {
1633 c.sweep_lt = sweep_lt_horiz;
1634 c.sweep_gt = sweep_gt_horiz;
1635 } else {
1636 c.sweep_lt = sweep_lt_vert;
1637 c.sweep_gt = sweep_gt_vert;
1638 }
1639 Vertex* mesh = contours_to_mesh(contours, contourCnt, antialias, c, alloc);
1640 Poly* polys = mesh_to_polys(&mesh, fillType, c, alloc);
1641 if (antialias) {
1642 EdgeList* boundaries = extract_boundaries(mesh, fillType, alloc);
1643 VertexList aaMesh;
1644 for (EdgeList* boundary = boundaries; boundary != nullptr; boundary = bo undary->fNext) {
1645 simplify_boundary(boundary, c, alloc);
1646 if (boundary->fCount > 2) {
1647 boundary_to_aa_mesh(boundary, &aaMesh, c, alloc);
1648 }
1649 }
1650 return mesh_to_polys(&aaMesh.fHead, SkPath::kWinding_FillType, c, alloc) ;
1651 }
1652 return polys;
1653 }
1654
1655 // Stage 6: Triangulate the monotone polygons into a vertex buffer.
1656 void* polys_to_triangles(Poly* polys, SkPath::FillType fillType, const AAParams* aaParams,
1657 void* data) {
1658 for (Poly* poly = polys; poly; poly = poly->fNext) {
1659 if (apply_fill_type(fillType, poly)) {
1660 data = poly->emit(aaParams, data);
1661 }
1662 }
1663 return data;
1340 } 1664 }
1341 1665
1342 Poly* path_to_polys(const SkPath& path, SkScalar tolerance, const SkRect& clipBo unds, 1666 Poly* path_to_polys(const SkPath& path, SkScalar tolerance, const SkRect& clipBo unds,
1343 int contourCnt, SkChunkAlloc& alloc, bool* isLinear) { 1667 int contourCnt, SkChunkAlloc& alloc, bool antialias, bool* i sLinear) {
1344 SkPath::FillType fillType = path.getFillType(); 1668 SkPath::FillType fillType = path.getFillType();
1345 if (SkPath::IsInverseFillType(fillType)) { 1669 if (SkPath::IsInverseFillType(fillType)) {
1346 contourCnt++; 1670 contourCnt++;
1347 } 1671 }
1348 SkAutoTDeleteArray<Vertex*> contours(new Vertex* [contourCnt]); 1672 SkAutoTDeleteArray<Vertex*> contours(new Vertex* [contourCnt]);
1349 1673
1350 path_to_contours(path, tolerance, clipBounds, contours.get(), alloc, isLinea r); 1674 path_to_contours(path, tolerance, clipBounds, contours.get(), alloc, isLinea r);
1351 return contours_to_polys(contours.get(), contourCnt, path.getBounds(), alloc ); 1675 return contours_to_polys(contours.get(), contourCnt, path.getFillType(), pat h.getBounds(),
1676 antialias, alloc);
1352 } 1677 }
1353 1678
1354 void get_contour_count_and_size_estimate(const SkPath& path, SkScalar tolerance, int* contourCnt, 1679 void get_contour_count_and_size_estimate(const SkPath& path, SkScalar tolerance, int* contourCnt,
1355 int* sizeEstimate) { 1680 int* sizeEstimate) {
1356 int maxPts = GrPathUtils::worstCasePointCount(path, contourCnt, tolerance); 1681 int maxPts = GrPathUtils::worstCasePointCount(path, contourCnt, tolerance);
1357 if (maxPts <= 0) { 1682 if (maxPts <= 0) {
1358 *contourCnt = 0; 1683 *contourCnt = 0;
1359 return; 1684 return;
1360 } 1685 }
1361 if (maxPts > ((int)SK_MaxU16 + 1)) { 1686 if (maxPts > ((int)SK_MaxU16 + 1)) {
1362 SkDebugf("Path not rendered, too many verts (%d)\n", maxPts); 1687 SkDebugf("Path not rendered, too many verts (%d)\n", maxPts);
1363 *contourCnt = 0; 1688 *contourCnt = 0;
1364 return; 1689 return;
1365 } 1690 }
1366 // For the initial size of the chunk allocator, estimate based on the point count: 1691 // For the initial size of the chunk allocator, estimate based on the point count:
1367 // one vertex per point for the initial passes, plus two for the vertices in the 1692 // one vertex per point for the initial passes, plus two for the vertices in the
1368 // resulting Polys, since the same point may end up in two Polys. Assume mi nimal 1693 // resulting Polys, since the same point may end up in two Polys. Assume mi nimal
1369 // connectivity of one Edge per Vertex (will grow for intersections). 1694 // connectivity of one Edge per Vertex (will grow for intersections).
1370 *sizeEstimate = maxPts * (3 * sizeof(Vertex) + sizeof(Edge)); 1695 *sizeEstimate = maxPts * (3 * sizeof(Vertex) + sizeof(Edge));
1371 } 1696 }
1372 1697
1373 int count_points(Poly* polys, SkPath::FillType fillType) { 1698 int count_points(Poly* polys, SkPath::FillType fillType) {
1374 int count = 0; 1699 int count = 0;
1375 for (Poly* poly = polys; poly; poly = poly->fNext) { 1700 for (Poly* poly = polys; poly; poly = poly->fNext) {
1376 if (apply_fill_type(fillType, poly->fWinding) && poly->fCount >= 3) { 1701 if (apply_fill_type(fillType, poly) && poly->fCount >= 3) {
1377 count += (poly->fCount - 2) * (TESSELLATOR_WIREFRAME ? 6 : 3); 1702 count += (poly->fCount - 2) * (TESSELLATOR_WIREFRAME ? 6 : 3);
1378 } 1703 }
1379 } 1704 }
1380 return count; 1705 return count;
1381 } 1706 }
1382 1707
1383 } // namespace 1708 } // namespace
1384 1709
1385 namespace GrTessellator { 1710 namespace GrTessellator {
1386 1711
1387 // Stage 6: Triangulate the monotone polygons into a vertex buffer. 1712 // Stage 6: Triangulate the monotone polygons into a vertex buffer.
1388 1713
1389 int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBo unds, 1714 int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBo unds,
1390 VertexAllocator* vertexAllocator, bool* isLinear) { 1715 VertexAllocator* vertexAllocator, bool antialias, const GrCo lor& color,
1716 bool canTweakAlphaForCoverage, bool* isLinear) {
1391 int contourCnt; 1717 int contourCnt;
1392 int sizeEstimate; 1718 int sizeEstimate;
1393 get_contour_count_and_size_estimate(path, tolerance, &contourCnt, &sizeEstim ate); 1719 get_contour_count_and_size_estimate(path, tolerance, &contourCnt, &sizeEstim ate);
1394 if (contourCnt <= 0) { 1720 if (contourCnt <= 0) {
1395 *isLinear = true; 1721 *isLinear = true;
1396 return 0; 1722 return 0;
1397 } 1723 }
1398 SkChunkAlloc alloc(sizeEstimate); 1724 SkChunkAlloc alloc(sizeEstimate);
1399 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, isLinear); 1725 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, antialias,
1726 isLinear);
1400 SkPath::FillType fillType = path.getFillType(); 1727 SkPath::FillType fillType = path.getFillType();
1401 int count = count_points(polys, fillType); 1728 int count = count_points(polys, fillType);
1402 if (0 == count) { 1729 if (0 == count) {
1403 return 0; 1730 return 0;
1404 } 1731 }
1405 1732
1406 SkPoint* verts = vertexAllocator->lock(count); 1733 void* verts = vertexAllocator->lock(count);
1407 if (!verts) { 1734 if (!verts) {
1408 SkDebugf("Could not allocate vertices\n"); 1735 SkDebugf("Could not allocate vertices\n");
1409 return 0; 1736 return 0;
1410 } 1737 }
1411 SkPoint* end = verts; 1738
1412 for (Poly* poly = polys; poly; poly = poly->fNext) { 1739 LOG("emitting %d verts\n", count);
1413 if (apply_fill_type(fillType, poly->fWinding)) { 1740 AAParams aaParams;
1414 end = poly->emit(end); 1741 aaParams.fTweakAlpha = canTweakAlphaForCoverage;
1415 } 1742 aaParams.fColor = color;
1416 } 1743
1417 int actualCount = static_cast<int>(end - verts); 1744 void* end = polys_to_triangles(polys, fillType, antialias ? &aaParams : null ptr, verts);
1418 LOG("actual count: %d\n", actualCount); 1745 int actualCount = static_cast<int>((static_cast<uint8_t*>(end) - static_cast <uint8_t*>(verts))
1746 / vertexAllocator->stride());
1419 SkASSERT(actualCount <= count); 1747 SkASSERT(actualCount <= count);
1420 vertexAllocator->unlock(actualCount); 1748 vertexAllocator->unlock(actualCount);
1421 return actualCount; 1749 return actualCount;
1422 } 1750 }
1423 1751
1424 int PathToVertices(const SkPath& path, SkScalar tolerance, const SkRect& clipBou nds, 1752 int PathToVertices(const SkPath& path, SkScalar tolerance, const SkRect& clipBou nds,
1425 GrTessellator::WindingVertex** verts) { 1753 GrTessellator::WindingVertex** verts) {
1426 int contourCnt; 1754 int contourCnt;
1427 int sizeEstimate; 1755 int sizeEstimate;
1428 get_contour_count_and_size_estimate(path, tolerance, &contourCnt, &sizeEstim ate); 1756 get_contour_count_and_size_estimate(path, tolerance, &contourCnt, &sizeEstim ate);
1429 if (contourCnt <= 0) { 1757 if (contourCnt <= 0) {
1430 return 0; 1758 return 0;
1431 } 1759 }
1432 SkChunkAlloc alloc(sizeEstimate); 1760 SkChunkAlloc alloc(sizeEstimate);
1433 bool isLinear; 1761 bool isLinear;
1434 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, &isLinear); 1762 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, false, &isLinear);
1435 SkPath::FillType fillType = path.getFillType(); 1763 SkPath::FillType fillType = path.getFillType();
1436 int count = count_points(polys, fillType); 1764 int count = count_points(polys, fillType);
1437 if (0 == count) { 1765 if (0 == count) {
1438 *verts = nullptr; 1766 *verts = nullptr;
1439 return 0; 1767 return 0;
1440 } 1768 }
1441 1769
1442 *verts = new GrTessellator::WindingVertex[count]; 1770 *verts = new GrTessellator::WindingVertex[count];
1443 GrTessellator::WindingVertex* vertsEnd = *verts; 1771 GrTessellator::WindingVertex* vertsEnd = *verts;
1444 SkPoint* points = new SkPoint[count]; 1772 SkPoint* points = new SkPoint[count];
1445 SkPoint* pointsEnd = points; 1773 SkPoint* pointsEnd = points;
1446 for (Poly* poly = polys; poly; poly = poly->fNext) { 1774 for (Poly* poly = polys; poly; poly = poly->fNext) {
1447 if (apply_fill_type(fillType, poly->fWinding)) { 1775 if (apply_fill_type(fillType, poly)) {
1448 SkPoint* start = pointsEnd; 1776 SkPoint* start = pointsEnd;
1449 pointsEnd = poly->emit(pointsEnd); 1777 pointsEnd = static_cast<SkPoint*>(poly->emit(nullptr, pointsEnd));
1450 while (start != pointsEnd) { 1778 while (start != pointsEnd) {
1451 vertsEnd->fPos = *start; 1779 vertsEnd->fPos = *start;
1452 vertsEnd->fWinding = poly->fWinding; 1780 vertsEnd->fWinding = poly->fWinding;
1453 ++start; 1781 ++start;
1454 ++vertsEnd; 1782 ++vertsEnd;
1455 } 1783 }
1456 } 1784 }
1457 } 1785 }
1458 int actualCount = static_cast<int>(vertsEnd - *verts); 1786 int actualCount = static_cast<int>(vertsEnd - *verts);
1459 SkASSERT(actualCount <= count); 1787 SkASSERT(actualCount <= count);
1460 SkASSERT(pointsEnd - points == actualCount); 1788 SkASSERT(pointsEnd - points == actualCount);
1461 delete[] points; 1789 delete[] points;
1462 return actualCount; 1790 return actualCount;
1463 } 1791 }
1464 1792
1465 } // namespace 1793 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698