| OLD | NEW |
| 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 "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 | 87 |
| 88 #define ALLOC_NEW(Type, args, alloc) new (alloc.allocThrow(sizeof(Type))) Type a
rgs | 88 #define ALLOC_NEW(Type, args, alloc) new (alloc.allocThrow(sizeof(Type))) Type a
rgs |
| 89 | 89 |
| 90 namespace { | 90 namespace { |
| 91 | 91 |
| 92 struct Vertex; | 92 struct Vertex; |
| 93 struct Edge; | 93 struct Edge; |
| 94 struct Poly; | 94 struct Poly; |
| 95 | 95 |
| 96 template <class T, T* T::*Prev, T* T::*Next> | 96 template <class T, T* T::*Prev, T* T::*Next> |
| 97 void insert(T* t, T* prev, T* next, T** head, T** tail) { | 97 void list_insert(T* t, T* prev, T* next, T** head, T** tail) { |
| 98 t->*Prev = prev; | 98 t->*Prev = prev; |
| 99 t->*Next = next; | 99 t->*Next = next; |
| 100 if (prev) { | 100 if (prev) { |
| 101 prev->*Next = t; | 101 prev->*Next = t; |
| 102 } else if (head) { | 102 } else if (head) { |
| 103 *head = t; | 103 *head = t; |
| 104 } | 104 } |
| 105 if (next) { | 105 if (next) { |
| 106 next->*Prev = t; | 106 next->*Prev = t; |
| 107 } else if (tail) { | 107 } else if (tail) { |
| 108 *tail = t; | 108 *tail = t; |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 template <class T, T* T::*Prev, T* T::*Next> | 112 template <class T, T* T::*Prev, T* T::*Next> |
| 113 void remove(T* t, T** head, T** tail) { | 113 void list_remove(T* t, T** head, T** tail) { |
| 114 if (t->*Prev) { | 114 if (t->*Prev) { |
| 115 t->*Prev->*Next = t->*Next; | 115 t->*Prev->*Next = t->*Next; |
| 116 } else if (head) { | 116 } else if (head) { |
| 117 *head = t->*Next; | 117 *head = t->*Next; |
| 118 } | 118 } |
| 119 if (t->*Next) { | 119 if (t->*Next) { |
| 120 t->*Next->*Prev = t->*Prev; | 120 t->*Next->*Prev = t->*Prev; |
| 121 } else if (tail) { | 121 } else if (tail) { |
| 122 *tail = t->*Prev; | 122 *tail = t->*Prev; |
| 123 } | 123 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 #endif | 203 #endif |
| 204 return data; | 204 return data; |
| 205 } | 205 } |
| 206 | 206 |
| 207 struct EdgeList { | 207 struct EdgeList { |
| 208 EdgeList() : fHead(nullptr), fTail(nullptr) {} | 208 EdgeList() : fHead(nullptr), fTail(nullptr) {} |
| 209 Edge* fHead; | 209 Edge* fHead; |
| 210 Edge* fTail; | 210 Edge* fTail; |
| 211 }; | 211 }; |
| 212 | 212 |
| 213 struct VertexList { |
| 214 VertexList() : fHead(nullptr), fTail(nullptr) {} |
| 215 Vertex* fHead; |
| 216 Vertex* fTail; |
| 217 void insert(Vertex* v, Vertex* prev, Vertex* next) { |
| 218 list_insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, prev, next, &fHea
d, &fTail); |
| 219 } |
| 220 void append(Vertex* v) { |
| 221 insert(v, fTail, nullptr); |
| 222 } |
| 223 void prepend(Vertex* v) { |
| 224 insert(v, nullptr, fHead); |
| 225 } |
| 226 }; |
| 227 |
| 213 /** | 228 /** |
| 214 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of
"edges above" and | 229 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of
"edges above" and |
| 215 * "edge below" a vertex as well as for the active edge list is handled by isLef
tOf()/isRightOf(). | 230 * "edge below" a vertex as well as for the active edge list is handled by isLef
tOf()/isRightOf(). |
| 216 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b
ecause floating | 231 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b
ecause floating |
| 217 * point). For speed, that case is only tested by the callers which require it (
e.g., | 232 * point). For speed, that case is only tested by the callers which require it (
e.g., |
| 218 * cleanup_active_edges()). Edges also handle checking for intersection with oth
er edges. | 233 * cleanup_active_edges()). Edges also handle checking for intersection with oth
er edges. |
| 219 * Currently, this converts the edges to the parametric form, in order to avoid
doing a division | 234 * Currently, this converts the edges to the parametric form, in order to avoid
doing a division |
| 220 * until an intersection has been confirmed. This is slightly slower in the "fou
nd" case, but | 235 * until an intersection has been confirmed. This is slightly slower in the "fou
nd" case, but |
| 221 * a lot faster in the "not found" case. | 236 * a lot faster in the "not found" case. |
| 222 * | 237 * |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 #if LOGGING_ENABLED | 334 #if LOGGING_ENABLED |
| 320 static int gID = 0; | 335 static int gID = 0; |
| 321 fID = gID++; | 336 fID = gID++; |
| 322 LOG("*** created Poly %d\n", fID); | 337 LOG("*** created Poly %d\n", fID); |
| 323 #endif | 338 #endif |
| 324 } | 339 } |
| 325 typedef enum { kNeither_Side, kLeft_Side, kRight_Side } Side; | 340 typedef enum { kNeither_Side, kLeft_Side, kRight_Side } Side; |
| 326 struct MonotonePoly { | 341 struct MonotonePoly { |
| 327 MonotonePoly() | 342 MonotonePoly() |
| 328 : fSide(kNeither_Side) | 343 : fSide(kNeither_Side) |
| 329 , fHead(nullptr) | |
| 330 , fTail(nullptr) | |
| 331 , fPrev(nullptr) | 344 , fPrev(nullptr) |
| 332 , fNext(nullptr) {} | 345 , fNext(nullptr) {} |
| 333 Side fSide; | 346 Side fSide; |
| 334 Vertex* fHead; | 347 VertexList fVertices; |
| 335 Vertex* fTail; | |
| 336 MonotonePoly* fPrev; | 348 MonotonePoly* fPrev; |
| 337 MonotonePoly* fNext; | 349 MonotonePoly* fNext; |
| 338 bool addVertex(Vertex* v, Side side, SkChunkAlloc& alloc) { | 350 bool addVertex(Vertex* v, Side side, SkChunkAlloc& alloc) { |
| 339 Vertex* newV = ALLOC_NEW(Vertex, (v->fPoint), alloc); | 351 Vertex* newV = ALLOC_NEW(Vertex, (v->fPoint), alloc); |
| 340 bool done = false; | 352 bool done = false; |
| 341 if (fSide == kNeither_Side) { | 353 if (fSide == kNeither_Side) { |
| 342 fSide = side; | 354 fSide = side; |
| 343 } else { | 355 } else { |
| 344 done = side != fSide; | 356 done = side != fSide; |
| 345 } | 357 } |
| 346 if (fHead == nullptr) { | 358 if (fSide == kRight_Side) { |
| 347 fHead = fTail = newV; | 359 fVertices.append(newV); |
| 348 } else if (fSide == kRight_Side) { | |
| 349 newV->fPrev = fTail; | |
| 350 fTail->fNext = newV; | |
| 351 fTail = newV; | |
| 352 } else { | 360 } else { |
| 353 newV->fNext = fHead; | 361 fVertices.prepend(newV); |
| 354 fHead->fPrev = newV; | |
| 355 fHead = newV; | |
| 356 } | 362 } |
| 357 return done; | 363 return done; |
| 358 } | 364 } |
| 359 | 365 |
| 360 SkPoint* emit(SkPoint* data) { | 366 SkPoint* emit(SkPoint* data) { |
| 361 Vertex* first = fHead; | 367 Vertex* first = fVertices.fHead; |
| 362 Vertex* v = first->fNext; | 368 Vertex* v = first->fNext; |
| 363 while (v != fTail) { | 369 while (v != fVertices.fTail) { |
| 364 SkASSERT(v && v->fPrev && v->fNext); | 370 SkASSERT(v && v->fPrev && v->fNext); |
| 365 Vertex* prev = v->fPrev; | 371 Vertex* prev = v->fPrev; |
| 366 Vertex* curr = v; | 372 Vertex* curr = v; |
| 367 Vertex* next = v->fNext; | 373 Vertex* next = v->fNext; |
| 368 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint.
fX; | 374 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint.
fX; |
| 369 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint.
fY; | 375 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint.
fY; |
| 370 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint.
fX; | 376 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint.
fX; |
| 371 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint.
fY; | 377 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint.
fY; |
| 372 if (ax * by - ay * bx >= 0.0) { | 378 if (ax * by - ay * bx >= 0.0) { |
| 373 data = emit_triangle(prev, curr, next, data); | 379 data = emit_triangle(prev, curr, next, data); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 402 fTail->fNext = fActive; | 408 fTail->fNext = fActive; |
| 403 fTail = fActive; | 409 fTail = fActive; |
| 404 } else { | 410 } else { |
| 405 fHead = fTail = fActive; | 411 fHead = fTail = fActive; |
| 406 } | 412 } |
| 407 if (partner) { | 413 if (partner) { |
| 408 partner->addVertex(v, side, alloc); | 414 partner->addVertex(v, side, alloc); |
| 409 poly = partner; | 415 poly = partner; |
| 410 } else { | 416 } else { |
| 411 Vertex* prev = fActive->fSide == Poly::kLeft_Side ? | 417 Vertex* prev = fActive->fSide == Poly::kLeft_Side ? |
| 412 fActive->fHead->fNext : fActive->fTail->fPrev; | 418 fActive->fVertices.fHead->fNext : fActive->fVerti
ces.fTail->fPrev; |
| 413 fActive = ALLOC_NEW(MonotonePoly, , alloc); | 419 fActive = ALLOC_NEW(MonotonePoly, , alloc); |
| 414 fActive->addVertex(prev, Poly::kNeither_Side, alloc); | 420 fActive->addVertex(prev, Poly::kNeither_Side, alloc); |
| 415 fActive->addVertex(v, side, alloc); | 421 fActive->addVertex(v, side, alloc); |
| 416 } | 422 } |
| 417 } | 423 } |
| 418 fCount++; | 424 fCount++; |
| 419 return poly; | 425 return poly; |
| 420 } | 426 } |
| 421 void end(Vertex* v, SkChunkAlloc& alloc) { | 427 void end(Vertex* v, SkChunkAlloc& alloc) { |
| 422 LOG("end() %d at %g, %g\n", fID, v->fPoint.fX, v->fPoint.fY); | 428 LOG("end() %d at %g, %g\n", fID, v->fPoint.fX, v->fPoint.fY); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c) { | 644 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c) { |
| 639 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; | 645 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; |
| 640 Vertex* top = winding < 0 ? next : prev; | 646 Vertex* top = winding < 0 ? next : prev; |
| 641 Vertex* bottom = winding < 0 ? prev : next; | 647 Vertex* bottom = winding < 0 ? prev : next; |
| 642 return ALLOC_NEW(Edge, (top, bottom, winding), alloc); | 648 return ALLOC_NEW(Edge, (top, bottom, winding), alloc); |
| 643 } | 649 } |
| 644 | 650 |
| 645 void remove_edge(Edge* edge, EdgeList* edges) { | 651 void remove_edge(Edge* edge, EdgeList* edges) { |
| 646 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); | 652 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); |
| 647 SkASSERT(edge->isActive(edges)); | 653 SkASSERT(edge->isActive(edges)); |
| 648 remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &edges->fHead, &edges->fTail
); | 654 list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &edges->fHead, &edges->
fTail); |
| 649 } | 655 } |
| 650 | 656 |
| 651 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) { | 657 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) { |
| 652 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); | 658 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); |
| 653 SkASSERT(!edge->isActive(edges)); | 659 SkASSERT(!edge->isActive(edges)); |
| 654 Edge* next = prev ? prev->fRight : edges->fHead; | 660 Edge* next = prev ? prev->fRight : edges->fHead; |
| 655 insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &edges->fHead, &
edges->fTail); | 661 list_insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &edges->fHe
ad, &edges->fTail); |
| 656 } | 662 } |
| 657 | 663 |
| 658 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right)
{ | 664 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right)
{ |
| 659 if (v->fFirstEdgeAbove) { | 665 if (v->fFirstEdgeAbove) { |
| 660 *left = v->fFirstEdgeAbove->fLeft; | 666 *left = v->fFirstEdgeAbove->fLeft; |
| 661 *right = v->fLastEdgeAbove->fRight; | 667 *right = v->fLastEdgeAbove->fRight; |
| 662 return; | 668 return; |
| 663 } | 669 } |
| 664 Edge* next = nullptr; | 670 Edge* next = nullptr; |
| 665 Edge* prev; | 671 Edge* prev; |
| 666 for (prev = edges->fTail; prev != nullptr; prev = prev->fLeft) { | 672 for (prev = edges->fTail; prev != nullptr; prev = prev->fLeft) { |
| 667 if (prev->isLeftOf(v)) { | 673 if (prev->isLeftOf(v)) { |
| 668 break; | 674 break; |
| 669 } | 675 } |
| 670 next = prev; | 676 next = prev; |
| 671 } | 677 } |
| 672 *left = prev; | 678 *left = prev; |
| 673 *right = next; | 679 *right = next; |
| 674 return; | |
| 675 } | 680 } |
| 676 | 681 |
| 677 void find_enclosing_edges(Edge* edge, EdgeList* edges, Comparator& c, Edge** lef
t, Edge** right) { | 682 void find_enclosing_edges(Edge* edge, EdgeList* edges, Comparator& c, Edge** lef
t, Edge** right) { |
| 678 Edge* prev = nullptr; | 683 Edge* prev = nullptr; |
| 679 Edge* next; | 684 Edge* next; |
| 680 for (next = edges->fHead; next != nullptr; next = next->fRight) { | 685 for (next = edges->fHead; next != nullptr; next = next->fRight) { |
| 681 if ((c.sweep_gt(edge->fTop->fPoint, next->fTop->fPoint) && next->isRight
Of(edge->fTop)) || | 686 if ((c.sweep_gt(edge->fTop->fPoint, next->fTop->fPoint) && next->isRight
Of(edge->fTop)) || |
| 682 (c.sweep_gt(next->fTop->fPoint, edge->fTop->fPoint) && edge->isLeftO
f(next->fTop)) || | 687 (c.sweep_gt(next->fTop->fPoint, edge->fTop->fPoint) && edge->isLeftO
f(next->fTop)) || |
| 683 (c.sweep_lt(edge->fBottom->fPoint, next->fBottom->fPoint) && | 688 (c.sweep_lt(edge->fBottom->fPoint, next->fBottom->fPoint) && |
| 684 next->isRightOf(edge->fBottom)) || | 689 next->isRightOf(edge->fBottom)) || |
| 685 (c.sweep_lt(next->fBottom->fPoint, edge->fBottom->fPoint) && | 690 (c.sweep_lt(next->fBottom->fPoint, edge->fBottom->fPoint) && |
| 686 edge->isLeftOf(next->fBottom))) { | 691 edge->isLeftOf(next->fBottom))) { |
| 687 break; | 692 break; |
| 688 } | 693 } |
| 689 prev = next; | 694 prev = next; |
| 690 } | 695 } |
| 691 *left = prev; | 696 *left = prev; |
| 692 *right = next; | 697 *right = next; |
| 693 return; | |
| 694 } | 698 } |
| 695 | 699 |
| 696 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) { | 700 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) { |
| 697 if (edge->isActive(activeEdges)) { | 701 if (edge->isActive(activeEdges)) { |
| 698 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { | 702 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { |
| 699 remove_edge(edge, activeEdges); | 703 remove_edge(edge, activeEdges); |
| 700 } | 704 } |
| 701 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { | 705 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { |
| 702 Edge* left; | 706 Edge* left; |
| 703 Edge* right; | 707 Edge* right; |
| 704 find_enclosing_edges(edge, activeEdges, c, &left, &right); | 708 find_enclosing_edges(edge, activeEdges, c, &left, &right); |
| 705 insert_edge(edge, left, activeEdges); | 709 insert_edge(edge, left, activeEdges); |
| 706 } | 710 } |
| 707 } | 711 } |
| 708 | 712 |
| 709 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) { | 713 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) { |
| 710 if (edge->fTop->fPoint == edge->fBottom->fPoint || | 714 if (edge->fTop->fPoint == edge->fBottom->fPoint || |
| 711 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { | 715 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { |
| 712 return; | 716 return; |
| 713 } | 717 } |
| 714 LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); | 718 LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); |
| 715 Edge* prev = nullptr; | 719 Edge* prev = nullptr; |
| 716 Edge* next; | 720 Edge* next; |
| 717 for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) { | 721 for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) { |
| 718 if (next->isRightOf(edge->fTop)) { | 722 if (next->isRightOf(edge->fTop)) { |
| 719 break; | 723 break; |
| 720 } | 724 } |
| 721 prev = next; | 725 prev = next; |
| 722 } | 726 } |
| 723 insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( | 727 list_insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( |
| 724 edge, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove); | 728 edge, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove); |
| 725 } | 729 } |
| 726 | 730 |
| 727 void insert_edge_below(Edge* edge, Vertex* v, Comparator& c) { | 731 void insert_edge_below(Edge* edge, Vertex* v, Comparator& c) { |
| 728 if (edge->fTop->fPoint == edge->fBottom->fPoint || | 732 if (edge->fTop->fPoint == edge->fBottom->fPoint || |
| 729 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { | 733 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { |
| 730 return; | 734 return; |
| 731 } | 735 } |
| 732 LOG("insert edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); | 736 LOG("insert edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); |
| 733 Edge* prev = nullptr; | 737 Edge* prev = nullptr; |
| 734 Edge* next; | 738 Edge* next; |
| 735 for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) { | 739 for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) { |
| 736 if (next->isRightOf(edge->fBottom)) { | 740 if (next->isRightOf(edge->fBottom)) { |
| 737 break; | 741 break; |
| 738 } | 742 } |
| 739 prev = next; | 743 prev = next; |
| 740 } | 744 } |
| 741 insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( | 745 list_insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( |
| 742 edge, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow); | 746 edge, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow); |
| 743 } | 747 } |
| 744 | 748 |
| 745 void remove_edge_above(Edge* edge) { | 749 void remove_edge_above(Edge* edge) { |
| 746 LOG("removing edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, | 750 LOG("removing edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, |
| 747 edge->fBottom->fID); | 751 edge->fBottom->fID); |
| 748 remove<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( | 752 list_remove<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( |
| 749 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove); | 753 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove); |
| 750 } | 754 } |
| 751 | 755 |
| 752 void remove_edge_below(Edge* edge) { | 756 void remove_edge_below(Edge* edge) { |
| 753 LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, | 757 LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, |
| 754 edge->fTop->fID); | 758 edge->fTop->fID); |
| 755 remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( | 759 list_remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( |
| 756 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); | 760 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); |
| 757 } | 761 } |
| 758 | 762 |
| 759 void erase_edge_if_zero_winding(Edge* edge, EdgeList* edges) { | 763 void erase_edge_if_zero_winding(Edge* edge, EdgeList* edges) { |
| 760 if (edge->fWinding != 0) { | 764 if (edge->fWinding != 0) { |
| 761 return; | 765 return; |
| 762 } | 766 } |
| 763 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); | 767 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); |
| 764 remove_edge_above(edge); | 768 remove_edge_above(edge); |
| 765 remove_edge_below(edge); | 769 remove_edge_below(edge); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 for (Edge* edge = src->fFirstEdgeAbove; edge;) { | 910 for (Edge* edge = src->fFirstEdgeAbove; edge;) { |
| 907 Edge* next = edge->fNextEdgeAbove; | 911 Edge* next = edge->fNextEdgeAbove; |
| 908 set_bottom(edge, dst, nullptr, c); | 912 set_bottom(edge, dst, nullptr, c); |
| 909 edge = next; | 913 edge = next; |
| 910 } | 914 } |
| 911 for (Edge* edge = src->fFirstEdgeBelow; edge;) { | 915 for (Edge* edge = src->fFirstEdgeBelow; edge;) { |
| 912 Edge* next = edge->fNextEdgeBelow; | 916 Edge* next = edge->fNextEdgeBelow; |
| 913 set_top(edge, dst, nullptr, c); | 917 set_top(edge, dst, nullptr, c); |
| 914 edge = next; | 918 edge = next; |
| 915 } | 919 } |
| 916 remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, nullptr); | 920 list_remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, nullptr); |
| 917 } | 921 } |
| 918 | 922 |
| 919 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C
omparator& c, | 923 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C
omparator& c, |
| 920 SkChunkAlloc& alloc) { | 924 SkChunkAlloc& alloc) { |
| 921 SkPoint p; | 925 SkPoint p; |
| 922 if (!edge || !other) { | 926 if (!edge || !other) { |
| 923 return nullptr; | 927 return nullptr; |
| 924 } | 928 } |
| 925 if (edge->intersect(*other, &p)) { | 929 if (edge->intersect(*other, &p)) { |
| 926 Vertex* v; | 930 Vertex* v; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 Vertex* a; | 1081 Vertex* a; |
| 1078 Vertex* b; | 1082 Vertex* b; |
| 1079 front_back_split(*head, &a, &b); | 1083 front_back_split(*head, &a, &b); |
| 1080 | 1084 |
| 1081 merge_sort(&a, c); | 1085 merge_sort(&a, c); |
| 1082 merge_sort(&b, c); | 1086 merge_sort(&b, c); |
| 1083 | 1087 |
| 1084 *head = sorted_merge(a, b, c); | 1088 *head = sorted_merge(a, b, c); |
| 1085 } | 1089 } |
| 1086 | 1090 |
| 1087 inline void append_vertex(Vertex* v, Vertex** head, Vertex** tail) { | |
| 1088 insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, *tail, nullptr, head, tail
); | |
| 1089 } | |
| 1090 | |
| 1091 inline void append_vertex_list(Vertex* v, Vertex** head, Vertex** tail) { | |
| 1092 insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, *tail, v->fNext, head, tai
l); | |
| 1093 } | |
| 1094 | |
| 1095 Vertex* sorted_merge(Vertex* a, Vertex* b, Comparator& c) { | 1091 Vertex* sorted_merge(Vertex* a, Vertex* b, Comparator& c) { |
| 1096 Vertex* head = nullptr; | 1092 VertexList vertices; |
| 1097 Vertex* tail = nullptr; | |
| 1098 | 1093 |
| 1099 while (a && b) { | 1094 while (a && b) { |
| 1100 if (c.sweep_lt(a->fPoint, b->fPoint)) { | 1095 if (c.sweep_lt(a->fPoint, b->fPoint)) { |
| 1101 Vertex* next = a->fNext; | 1096 Vertex* next = a->fNext; |
| 1102 append_vertex(a, &head, &tail); | 1097 vertices.append(a); |
| 1103 a = next; | 1098 a = next; |
| 1104 } else { | 1099 } else { |
| 1105 Vertex* next = b->fNext; | 1100 Vertex* next = b->fNext; |
| 1106 append_vertex(b, &head, &tail); | 1101 vertices.append(b); |
| 1107 b = next; | 1102 b = next; |
| 1108 } | 1103 } |
| 1109 } | 1104 } |
| 1110 if (a) { | 1105 if (a) { |
| 1111 append_vertex_list(a, &head, &tail); | 1106 vertices.insert(a, vertices.fTail, a->fNext); |
| 1112 } | 1107 } |
| 1113 if (b) { | 1108 if (b) { |
| 1114 append_vertex_list(b, &head, &tail); | 1109 vertices.insert(b, vertices.fTail, b->fNext); |
| 1115 } | 1110 } |
| 1116 return head; | 1111 return vertices.fHead; |
| 1117 } | 1112 } |
| 1118 | 1113 |
| 1119 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. | 1114 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. |
| 1120 | 1115 |
| 1121 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) { | 1116 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) { |
| 1122 LOG("simplifying complex polygons\n"); | 1117 LOG("simplifying complex polygons\n"); |
| 1123 EdgeList activeEdges; | 1118 EdgeList activeEdges; |
| 1124 for (Vertex* v = vertices; v != nullptr; v = v->fNext) { | 1119 for (Vertex* v = vertices; v != nullptr; v = v->fNext) { |
| 1125 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { | 1120 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { |
| 1126 continue; | 1121 continue; |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 } | 1456 } |
| 1462 } | 1457 } |
| 1463 int actualCount = static_cast<int>(vertsEnd - *verts); | 1458 int actualCount = static_cast<int>(vertsEnd - *verts); |
| 1464 SkASSERT(actualCount <= count); | 1459 SkASSERT(actualCount <= count); |
| 1465 SkASSERT(pointsEnd - points == actualCount); | 1460 SkASSERT(pointsEnd - points == actualCount); |
| 1466 delete[] points; | 1461 delete[] points; |
| 1467 return actualCount; | 1462 return actualCount; |
| 1468 } | 1463 } |
| 1469 | 1464 |
| 1470 } // namespace | 1465 } // namespace |
| OLD | NEW |