Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GrTessellator.h"
      9 
     10 #include "GrDefaultGeoProcFactory.h"
     11 #include "GrPathUtils.h"
     12 
     13 #include "SkArenaAlloc.h"
     14 #include "SkGeometry.h"
     15 #include "SkPath.h"
     16 
     17 #include <stdio.h>
     18 
     19 /*
     20  * There are six stages to the basic algorithm:
     21  *
     22  * 1) Linearize the path contours into piecewise linear segments (path_to_contours()).
     23  * 2) Build a mesh of edges connecting the vertices (build_edges()).
     24  * 3) Sort the vertices in Y (and secondarily in X) (merge_sort()).
     25  * 4) Simplify the mesh by inserting new vertices at intersecting edges (simplify()).
     26  * 5) Tessellate the simplified mesh into monotone polygons (tessellate()).
     27  * 6) Triangulate the monotone polygons directly into a vertex buffer (polys_to_triangles()).
     28  *
     29  * For screenspace antialiasing, the algorithm is modified as follows:
     30  *
     31  * Run steps 1-5 above to produce polygons.
     32  * 5b) Apply fill rules to extract boundary contours from the polygons (extract_boundaries()).
     33  * 5c) Simplify boundaries to remove "pointy" vertices that cause inversions (simplify_boundary()).
     34  * 5d) Displace edges by half a pixel inward and outward along their normals. Intersect to find
     35  *     new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a new
     36  *     antialiased mesh from those vertices (stroke_boundary()).
     37  * Run steps 3-6 above on the new mesh, and produce antialiased triangles.
     38  *
     39  * The vertex sorting in step (3) is a merge sort, since it plays well with the linked list
     40  * of vertices (and the necessity of inserting new vertices on intersection).
     41  *
     42  * Stages (4) and (5) use an active edge list -- a list of all edges for which the
     43  * sweep line has crossed the top vertex, but not the bottom vertex.  It's sorted
     44  * left-to-right based on the point where both edges are active (when both top vertices
     45  * have been seen, so the "lower" top vertex of the two). If the top vertices are equal
     46  * (shared), it's sorted based on the last point where both edges are active, so the
     47  * "upper" bottom vertex.
     48  *
     49  * The most complex step is the simplification (4). It's based on the Bentley-Ottman
     50  * line-sweep algorithm, but due to floating point inaccuracy, the intersection points are
     51  * not exact and may violate the mesh topology or active edge list ordering. We
     52  * accommodate this by adjusting the topology of the mesh and AEL to match the intersection
     53  * points. This occurs in two ways:
     54  *
     55  * A) Intersections may cause a shortened edge to no longer be ordered with respect to its
     56  *    neighbouring edges at the top or bottom vertex. This is handled by merging the
     57  *    edges (merge_collinear_edges()).
     58  * B) Intersections may cause an edge to violate the left-to-right ordering of the
     59  *    active edge list. This is handled by detecting potential violations and rewinding
     60  *    the active edge list to the vertex before they occur (rewind() during merging,
     61  *    rewind_if_necessary() during splitting).
     62  *
     63  * The tessellation steps (5) and (6) are based on "Triangulating Simple Polygons and
     64  * Equivalent Problems" (Fournier and Montuno); also a line-sweep algorithm. Note that it
     65  * currently uses a linked list for the active edge list, rather than a 2-3 tree as the
     66  * paper describes. The 2-3 tree gives O(lg N) lookups, but insertion and removal also
     67  * become O(lg N). In all the test cases, it was found that the cost of frequent O(lg N)
     68  * insertions and removals was greater than the cost of infrequent O(N) lookups with the
     69  * linked list implementation. With the latter, all removals are O(1), and most insertions
     70  * are O(1), since we know the adjacent edge in the active edge list based on the topology.
     71  * Only type 2 vertices (see paper) require the O(N) lookups, and these are much less
     72  * frequent. There may be other data structures worth investigating, however.
     73  *
     74  * Note that the orientation of the line sweep algorithms is determined by the aspect ratio of the
     75  * path bounds. When the path is taller than it is wide, we sort vertices based on increasing Y
     76  * coordinate, and secondarily by increasing X coordinate. When the path is wider than it is tall,
     77  * we sort by increasing X coordinate, but secondarily by *decreasing* Y coordinate. This is so
     78  * that the "left" and "right" orientation in the code remains correct (edges to the left are
     79  * increasing in Y; edges to the right are decreasing in Y). That is, the setting rotates 90
     80  * degrees counterclockwise, rather that transposing.
     81  */
     82 
     83 #define LOGGING_ENABLED 0
     84 
     85 #if LOGGING_ENABLED
     86 #define LOG printf
     87 #else
     88 #define LOG(...)
     89 #endif
     90 
     91 namespace {
     92 
     93 const int kArenaChunkSize = 16 * 1024;
     94 
     95 struct Vertex;
     96 struct Edge;
     97 struct Poly;
     98 
     99 template <class T, T* T::*Prev, T* T::*Next>
    100 void list_insert(T* t, T* prev, T* next, T** head, T** tail) {
    101     t->*Prev = prev;
    102     t->*Next = next;
    103     if (prev) {
    104         prev->*Next = t;
    105     } else if (head) {
    106         *head = t;
    107     }
    108     if (next) {
    109         next->*Prev = t;
    110     } else if (tail) {
    111         *tail = t;
    112     }
    113 }
    114 
    115 template <class T, T* T::*Prev, T* T::*Next>
    116 void list_remove(T* t, T** head, T** tail) {
    117     if (t->*Prev) {
    118         t->*Prev->*Next = t->*Next;
    119     } else if (head) {
    120         *head = t->*Next;
    121     }
    122     if (t->*Next) {
    123         t->*Next->*Prev = t->*Prev;
    124     } else if (tail) {
    125         *tail = t->*Prev;
    126     }
    127     t->*Prev = t->*Next = nullptr;
    128 }
    129 
    130 /**
    131  * Vertices are used in three ways: first, the path contours are converted into a
    132  * circularly-linked list of Vertices for each contour. After edge construction, the same Vertices
    133  * are re-ordered by the merge sort according to the sweep_lt comparator (usually, increasing
    134  * in Y) using the same fPrev/fNext pointers that were used for the contours, to avoid
    135  * reallocation. Finally, MonotonePolys are built containing a circularly-linked list of
    136  * Vertices. (Currently, those Vertices are newly-allocated for the MonotonePolys, since
    137  * an individual Vertex from the path mesh may belong to multiple
    138  * MonotonePolys, so the original Vertices cannot be re-used.
    139  */
    140 
    141 struct Vertex {
    142   Vertex(const SkPoint& point, uint8_t alpha)
    143     : fPoint(point), fPrev(nullptr), fNext(nullptr)
    144     , fFirstEdgeAbove(nullptr), fLastEdgeAbove(nullptr)
    145     , fFirstEdgeBelow(nullptr), fLastEdgeBelow(nullptr)
    146     , fLeftEnclosingEdge(nullptr), fRightEnclosingEdge(nullptr)
    147     , fPartner(nullptr)
    148     , fAlpha(alpha)
    149 #if LOGGING_ENABLED
    150     , fID (-1.0f)
    151 #endif
    152     {}
    153     SkPoint fPoint;               // Vertex position
    154     Vertex* fPrev;                // Linked list of contours, then Y-sorted vertices.
    155     Vertex* fNext;                // "
    156     Edge*   fFirstEdgeAbove;      // Linked list of edges above this vertex.
    157     Edge*   fLastEdgeAbove;       // "
    158     Edge*   fFirstEdgeBelow;      // Linked list of edges below this vertex.
    159     Edge*   fLastEdgeBelow;       // "
    160     Edge*   fLeftEnclosingEdge;   // Nearest edge in the AEL left of this vertex.
    161     Edge*   fRightEnclosingEdge;  // Nearest edge in the AEL right of this vertex.
    162     Vertex* fPartner;             // Corresponding inner or outer vertex (for AA).
    163     uint8_t fAlpha;
    164 #if LOGGING_ENABLED
    165     float   fID;                  // Identifier used for logging.
    166 #endif
    167 };
    168 
    169 /***************************************************************************************/
    170 
    171 struct AAParams {
    172     bool fTweakAlpha;
    173     GrColor fColor;
    174 };
    175 
    176 typedef bool (*CompareFunc)(const SkPoint& a, const SkPoint& b);
    177 
    178 bool sweep_lt_horiz(const SkPoint& a, const SkPoint& b) {
    179     return a.fX < b.fX || (a.fX == b.fX && a.fY > b.fY);
    180 }
    181 
    182 bool sweep_lt_vert(const SkPoint& a, const SkPoint& b) {
    183     return a.fY < b.fY || (a.fY == b.fY && a.fX < b.fX);
    184 }
    185 
    186 struct Comparator {
    187     enum class Direction { kVertical, kHorizontal };
    188     Comparator(Direction direction) : fDirection(direction) {}
    189     bool sweep_lt(const SkPoint& a, const SkPoint& b) const {
    190         return fDirection == Direction::kHorizontal ? sweep_lt_horiz(a, b) : sweep_lt_vert(a, b);
    191     }
    192     Direction fDirection;
    193 };
    194 
    195 inline void* emit_vertex(Vertex* v, const AAParams* aaParams, void* data) {
    196     if (!aaParams) {
    197         SkPoint* d = static_cast<SkPoint*>(data);
    198         *d++ = v->fPoint;
    199         return d;
    200     }
    201     if (aaParams->fTweakAlpha) {
    202         auto d = static_cast<GrDefaultGeoProcFactory::PositionColorAttr*>(data);
    203         d->fPosition = v->fPoint;
    204         d->fColor = SkAlphaMulQ(aaParams->fColor, SkAlpha255To256(v->fAlpha));
    205         d++;
    206         return d;
    207     }
    208     auto d = static_cast<GrDefaultGeoProcFactory::PositionColorCoverageAttr*>(data);
    209     d->fPosition = v->fPoint;
    210     d->fColor = aaParams->fColor;
    211     d->fCoverage = GrNormalizeByteToFloat(v->fAlpha);
    212     d++;
    213     return d;
    214 }
    215 
    216 void* emit_triangle(Vertex* v0, Vertex* v1, Vertex* v2, const AAParams* aaParams, void* data) {
    217     LOG("emit_triangle (%g, %g) %d\n", v0->fPoint.fX, v0->fPoint.fY, v0->fAlpha);
    218     LOG("              (%g, %g) %d\n", v1->fPoint.fX, v1->fPoint.fY, v1->fAlpha);
    219     LOG("              (%g, %g) %d\n", v2->fPoint.fX, v2->fPoint.fY, v2->fAlpha);
    220 #if TESSELLATOR_WIREFRAME
    221     data = emit_vertex(v0, aaParams, data);
    222     data = emit_vertex(v1, aaParams, data);
    223     data = emit_vertex(v1, aaParams, data);
    224     data = emit_vertex(v2, aaParams, data);
    225     data = emit_vertex(v2, aaParams, data);
    226     data = emit_vertex(v0, aaParams, data);
    227 #else
    228     data = emit_vertex(v0, aaParams, data);
    229     data = emit_vertex(v1, aaParams, data);
    230     data = emit_vertex(v2, aaParams, data);
    231 #endif
    232     return data;
    233 }
    234 
    235 struct VertexList {
    236     VertexList() : fHead(nullptr), fTail(nullptr) {}
    237     VertexList(Vertex* head, Vertex* tail) : fHead(head), fTail(tail) {}
    238     Vertex* fHead;
    239     Vertex* fTail;
    240     void insert(Vertex* v, Vertex* prev, Vertex* next) {
    241         list_insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, prev, next, &fHead, &fTail);
    242     }
    243     void append(Vertex* v) {
    244         insert(v, fTail, nullptr);
    245     }
    246     void append(const VertexList& list) {
    247         if (!list.fHead) {
    248             return;
    249         }
    250         if (fTail) {
    251             fTail->fNext = list.fHead;
    252             list.fHead->fPrev = fTail;
    253         } else {
    254             fHead = list.fHead;
    255         }
    256         fTail = list.fTail;
    257     }
    258     void prepend(Vertex* v) {
    259         insert(v, nullptr, fHead);
    260     }
    261     void remove(Vertex* v) {
    262         list_remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, &fHead, &fTail);
    263     }
    264     void close() {
    265         if (fHead && fTail) {
    266             fTail->fNext = fHead;
    267             fHead->fPrev = fTail;
    268         }
    269     }
    270 };
    271 
    272 // Round to nearest quarter-pixel. This is used for screenspace tessellation.
    273 
    274 inline void round(SkPoint* p) {
    275     p->fX = SkScalarRoundToScalar(p->fX * SkFloatToScalar(4.0f)) * SkFloatToScalar(0.25f);
    276     p->fY = SkScalarRoundToScalar(p->fY * SkFloatToScalar(4.0f)) * SkFloatToScalar(0.25f);
    277 }
    278 
    279 // A line equation in implicit form. fA * x + fB * y + fC = 0, for all points (x, y) on the line.
    280 struct Line {
    281     Line(Vertex* p, Vertex* q) : Line(p->fPoint, q->fPoint) {}
    282     Line(const SkPoint& p, const SkPoint& q)
    283         : fA(static_cast<double>(q.fY) - p.fY)      // a = dY
    284         , fB(static_cast<double>(p.fX) - q.fX)      // b = -dX
    285         , fC(static_cast<double>(p.fY) * q.fX -     // c = cross(q, p)
    286              static_cast<double>(p.fX) * q.fY) {}
    287     double dist(const SkPoint& p) const {
    288         return fA * p.fX + fB * p.fY + fC;
    289     }
    290     double magSq() const {
    291         return fA * fA + fB * fB;
    292     }
    293 
    294     // Compute the intersection of two (infinite) Lines.
    295     bool intersect(const Line& other, SkPoint* point) {
    296         double denom = fA * other.fB - fB * other.fA;
    297         if (denom == 0.0) {
    298             return false;
    299         }
    300         double scale = 1.0f / denom;
    301         point->fX = SkDoubleToScalar((fB * other.fC - other.fB * fC) * scale);
    302         point->fY = SkDoubleToScalar((other.fA * fC - fA * other.fC) * scale);
    303         round(point);
    304         return true;
    305     }
    306     double fA, fB, fC;
    307 };
    308 
    309 /**
    310  * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of "edges above" and
    311  * "edge below" a vertex as well as for the active edge list is handled by isLeftOf()/isRightOf().
    312  * Note that an Edge will give occasionally dist() != 0 for its own endpoints (because floating
    313  * point). For speed, that case is only tested by the callers that require it (e.g.,
    314  * rewind_if_necessary()). Edges also handle checking for intersection with other edges.
    315  * Currently, this converts the edges to the parametric form, in order to avoid doing a division
    316  * until an intersection has been confirmed. This is slightly slower in the "found" case, but
    317  * a lot faster in the "not found" case.
    318  *
    319  * The coefficients of the line equation stored in double precision to avoid catastrphic
    320  * cancellation in the isLeftOf() and isRightOf() checks. Using doubles ensures that the result is
    321  * correct in float, since it's a polynomial of degree 2. The intersect() function, being
    322  * degree 5, is still subject to catastrophic cancellation. We deal with that by assuming its
    323  * output may be incorrect, and adjusting the mesh topology to match (see comment at the top of
    324  * this file).
    325  */
    326 
    327 struct Edge {
    328     enum class Type { kInner, kOuter, kConnector };
    329     Edge(Vertex* top, Vertex* bottom, int winding, Type type)
    330         : fWinding(winding)
    331         , fTop(top)
    332         , fBottom(bottom)
    333         , fType(type)
    334         , fLeft(nullptr)
    335         , fRight(nullptr)
    336         , fPrevEdgeAbove(nullptr)
    337         , fNextEdgeAbove(nullptr)
    338         , fPrevEdgeBelow(nullptr)
    339         , fNextEdgeBelow(nullptr)
    340         , fLeftPoly(nullptr)
    341         , fRightPoly(nullptr)
    342         , fLeftPolyPrev(nullptr)
    343         , fLeftPolyNext(nullptr)
    344         , fRightPolyPrev(nullptr)
    345         , fRightPolyNext(nullptr)
    346         , fUsedInLeftPoly(false)
    347         , fUsedInRightPoly(false)
    348         , fLine(top, bottom) {
    349         }
    350     int      fWinding;          // 1 == edge goes downward; -1 = edge goes upward.
    351     Vertex*  fTop;              // The top vertex in vertex-sort-order (sweep_lt).
    352     Vertex*  fBottom;           // The bottom vertex in vertex-sort-order.
    353     Type     fType;
    354     Edge*    fLeft;             // The linked list of edges in the active edge list.
    355     Edge*    fRight;            // "
    356     Edge*    fPrevEdgeAbove;    // The linked list of edges in the bottom Vertex's "edges above".
    357     Edge*    fNextEdgeAbove;    // "
    358     Edge*    fPrevEdgeBelow;    // The linked list of edges in the top Vertex's "edges below".
    359     Edge*    fNextEdgeBelow;    // "
    360     Poly*    fLeftPoly;         // The Poly to the left of this edge, if any.
    361     Poly*    fRightPoly;        // The Poly to the right of this edge, if any.
    362     Edge*    fLeftPolyPrev;
    363     Edge*    fLeftPolyNext;
    364     Edge*    fRightPolyPrev;
    365     Edge*    fRightPolyNext;
    366     bool     fUsedInLeftPoly;
    367     bool     fUsedInRightPoly;
    368     Line     fLine;
    369     double dist(const SkPoint& p) const {
    370         return fLine.dist(p);
    371     }
    372     bool isRightOf(Vertex* v) const {
    373         return fLine.dist(v->fPoint) < 0.0;
    374     }
    375     bool isLeftOf(Vertex* v) const {
    376         return fLine.dist(v->fPoint) > 0.0;
    377     }
    378     void recompute() {
    379         fLine = Line(fTop, fBottom);
    380     }
    381     bool intersect(const Edge& other, SkPoint* p, uint8_t* alpha = nullptr) {
    382         LOG("intersecting %g -> %g with %g -> %g\n",
    383                fTop->fID, fBottom->fID,
    384                other.fTop->fID, other.fBottom->fID);
    385         if (fTop == other.fTop || fBottom == other.fBottom) {
    386             return false;
    387         }
    388         double denom = fLine.fA * other.fLine.fB - fLine.fB * other.fLine.fA;
    389         if (denom == 0.0) {
    390             return false;
    391         }
    392         double dx = static_cast<double>(other.fTop->fPoint.fX) - fTop->fPoint.fX;
    393         double dy = static_cast<double>(other.fTop->fPoint.fY) - fTop->fPoint.fY;
    394         double sNumer = dy * other.fLine.fB + dx * other.fLine.fA;
    395         double tNumer = dy * fLine.fB + dx * fLine.fA;
    396         // If (sNumer / denom) or (tNumer / denom) is not in [0..1], exit early.
    397         // This saves us doing the divide below unless absolutely necessary.
    398         if (denom > 0.0 ? (sNumer < 0.0 || sNumer > denom || tNumer < 0.0 || tNumer > denom)
    399                         : (sNumer > 0.0 || sNumer < denom || tNumer > 0.0 || tNumer < denom)) {
    400             return false;
    401         }
    402         double s = sNumer / denom;
    403         SkASSERT(s >= 0.0 && s <= 1.0);
    404         p->fX = SkDoubleToScalar(fTop->fPoint.fX - s * fLine.fB);
    405         p->fY = SkDoubleToScalar(fTop->fPoint.fY + s * fLine.fA);
    406         if (alpha) {
    407             if (fType == Type::kConnector) {
    408                 *alpha = (1.0 - s) * fTop->fAlpha + s * fBottom->fAlpha;
    409             } else if (other.fType == Type::kConnector) {
    410                 double t = tNumer / denom;
    411                 *alpha = (1.0 - t) * other.fTop->fAlpha + t * other.fBottom->fAlpha;
    412             } else if (fType == Type::kOuter && other.fType == Type::kOuter) {
    413                 *alpha = 0;
    414             } else {
    415                 *alpha = 255;
    416             }
    417         }
    418         return true;
    419     }
    420 };
    421 
    422 struct EdgeList {
    423     EdgeList() : fHead(nullptr), fTail(nullptr) {}
    424     Edge* fHead;
    425     Edge* fTail;
    426     void insert(Edge* edge, Edge* prev, Edge* next) {
    427         list_insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &fHead, &fTail);
    428     }
    429     void append(Edge* e) {
    430         insert(e, fTail, nullptr);
    431     }
    432     void remove(Edge* edge) {
    433         list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &fHead, &fTail);
    434     }
    435     void removeAll() {
    436         while (fHead) {
    437             this->remove(fHead);
    438         }
    439     }
    440     void close() {
    441         if (fHead && fTail) {
    442             fTail->fRight = fHead;
    443             fHead->fLeft = fTail;
    444         }
    445     }
    446     bool contains(Edge* edge) const {
    447         return edge->fLeft || edge->fRight || fHead == edge;
    448     }
    449 };
    450 
    451 /***************************************************************************************/
    452 
    453 struct Poly {
    454     Poly(Vertex* v, int winding)
    455         : fFirstVertex(v)
    456         , fWinding(winding)
    457         , fHead(nullptr)
    458         , fTail(nullptr)
    459         , fNext(nullptr)
    460         , fPartner(nullptr)
    461         , fCount(0)
    462     {
    463 #if LOGGING_ENABLED
    464         static int gID = 0;
    465         fID = gID++;
    466         LOG("*** created Poly %d\n", fID);
    467 #endif
    468     }
    469     typedef enum { kLeft_Side, kRight_Side } Side;
    470     struct MonotonePoly {
    471         MonotonePoly(Edge* edge, Side side)
    472             : fSide(side)
    473             , fFirstEdge(nullptr)
    474             , fLastEdge(nullptr)
    475             , fPrev(nullptr)
    476             , fNext(nullptr) {
    477             this->addEdge(edge);
    478         }
    479         Side          fSide;
    480         Edge*         fFirstEdge;
    481         Edge*         fLastEdge;
    482         MonotonePoly* fPrev;
    483         MonotonePoly* fNext;
    484         void addEdge(Edge* edge) {
    485             if (fSide == kRight_Side) {
    486                 SkASSERT(!edge->fUsedInRightPoly);
    487                 list_insert<Edge, &Edge::fRightPolyPrev, &Edge::fRightPolyNext>(
    488                     edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge);
    489                 edge->fUsedInRightPoly = true;
    490             } else {
    491                 SkASSERT(!edge->fUsedInLeftPoly);
    492                 list_insert<Edge, &Edge::fLeftPolyPrev, &Edge::fLeftPolyNext>(
    493                     edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge);
    494                 edge->fUsedInLeftPoly = true;
    495             }
    496         }
    497 
    498         void* emit(const AAParams* aaParams, void* data) {
    499             Edge* e = fFirstEdge;
    500             VertexList vertices;
    501             vertices.append(e->fTop);
    502             int count = 1;
    503             while (e != nullptr) {
    504                 if (kRight_Side == fSide) {
    505                     vertices.append(e->fBottom);
    506                     e = e->fRightPolyNext;
    507                 } else {
    508                     vertices.prepend(e->fBottom);
    509                     e = e->fLeftPolyNext;
    510                 }
    511                 count++;
    512             }
    513             Vertex* first = vertices.fHead;
    514             Vertex* v = first->fNext;
    515             while (v != vertices.fTail) {
    516                 SkASSERT(v && v->fPrev && v->fNext);
    517                 Vertex* prev = v->fPrev;
    518                 Vertex* curr = v;
    519                 Vertex* next = v->fNext;
    520                 if (count == 3) {
    521                     return emit_triangle(prev, curr, next, aaParams, data);
    522                 }
    523                 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint.fX;
    524                 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint.fY;
    525                 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint.fX;
    526                 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint.fY;
    527                 if (ax * by - ay * bx >= 0.0) {
    528                     data = emit_triangle(prev, curr, next, aaParams, data);
    529                     v->fPrev->fNext = v->fNext;
    530                     v->fNext->fPrev = v->fPrev;
    531                     count--;
    532                     if (v->fPrev == first) {
    533                         v = v->fNext;
    534                     } else {
    535                         v = v->fPrev;
    536                     }
    537                 } else {
    538                     v = v->fNext;
    539                 }
    540             }
    541             return data;
    542         }
    543     };
    544     Poly* addEdge(Edge* e, Side side, SkArenaAlloc& alloc) {
    545         LOG("addEdge (%g -> %g) to poly %d, %s side\n",
    546                e->fTop->fID, e->fBottom->fID, fID, side == kLeft_Side ? "left" : "right");
    547         Poly* partner = fPartner;
    548         Poly* poly = this;
    549         if (side == kRight_Side) {
    550             if (e->fUsedInRightPoly) {
    551                 return this;
    552             }
    553         } else {
    554             if (e->fUsedInLeftPoly) {
    555                 return this;
    556             }
    557         }
    558         if (partner) {
    559             fPartner = partner->fPartner = nullptr;
    560         }
    561         if (!fTail) {
    562             fHead = fTail = alloc.make<MonotonePoly>(e, side);
    563             fCount += 2;
    564         } else if (e->fBottom == fTail->fLastEdge->fBottom) {
    565             return poly;
    566         } else if (side == fTail->fSide) {
    567             fTail->addEdge(e);
    568             fCount++;
    569         } else {
    570             e = alloc.make<Edge>(fTail->fLastEdge->fBottom, e->fBottom, 1, Edge::Type::kInner);
    571             fTail->addEdge(e);
    572             fCount++;
    573             if (partner) {
    574                 partner->addEdge(e, side, alloc);
    575                 poly = partner;
    576             } else {
    577                 MonotonePoly* m = alloc.make<MonotonePoly>(e, side);
    578                 m->fPrev = fTail;
    579                 fTail->fNext = m;
    580                 fTail = m;
    581             }
    582         }
    583         return poly;
    584     }
    585     void* emit(const AAParams* aaParams, void *data) {
    586         if (fCount < 3) {
    587             return data;
    588         }
    589         LOG("emit() %d, size %d\n", fID, fCount);
    590         for (MonotonePoly* m = fHead; m != nullptr; m = m->fNext) {
    591             data = m->emit(aaParams, data);
    592         }
    593         return data;
    594     }
    595     Vertex* lastVertex() const { return fTail ? fTail->fLastEdge->fBottom : fFirstVertex; }
    596     Vertex* fFirstVertex;
    597     int fWinding;
    598     MonotonePoly* fHead;
    599     MonotonePoly* fTail;
    600     Poly* fNext;
    601     Poly* fPartner;
    602     int fCount;
    603 #if LOGGING_ENABLED
    604     int fID;
    605 #endif
    606 };
    607 
    608 /***************************************************************************************/
    609 
    610 bool coincident(const SkPoint& a, const SkPoint& b) {
    611     return a == b;
    612 }
    613 
    614 Poly* new_poly(Poly** head, Vertex* v, int winding, SkArenaAlloc& alloc) {
    615     Poly* poly = alloc.make<Poly>(v, winding);
    616     poly->fNext = *head;
    617     *head = poly;
    618     return poly;
    619 }
    620 
    621 void append_point_to_contour(const SkPoint& p, VertexList* contour, SkArenaAlloc& alloc) {
    622     Vertex* v = alloc.make<Vertex>(p, 255);
    623 #if LOGGING_ENABLED
    624     static float gID = 0.0f;
    625     v->fID = gID++;
    626 #endif
    627     contour->append(v);
    628 }
    629 
    630 SkScalar quad_error_at(const SkPoint pts[3], SkScalar t, SkScalar u) {
    631     SkQuadCoeff quad(pts);
    632     SkPoint p0 = to_point(quad.eval(t - 0.5f * u));
    633     SkPoint mid = to_point(quad.eval(t));
    634     SkPoint p1 = to_point(quad.eval(t + 0.5f * u));
    635     if (!p0.isFinite() || !mid.isFinite() || !p1.isFinite()) {
    636         return 0;
    637     }
    638     return mid.distanceToLineSegmentBetweenSqd(p0, p1);
    639 }
    640 
    641 void append_quadratic_to_contour(const SkPoint pts[3], SkScalar toleranceSqd, VertexList* contour,
    642                                  SkArenaAlloc& alloc) {
    643     SkQuadCoeff quad(pts);
    644     Sk2s aa = quad.fA * quad.fA;
    645     SkScalar denom = 2.0f * (aa[0] + aa[1]);
    646     Sk2s ab = quad.fA * quad.fB;
    647     SkScalar t = denom ? (-ab[0] - ab[1]) / denom : 0.0f;
    648     int nPoints = 1;
    649     SkScalar u;
    650     // Test possible subdivision values only at the point of maximum curvature.
    651     // If it passes the flatness metric there, it'll pass everywhere.
    652     for (;;) {
    653         u = 1.0f / nPoints;
    654         if (quad_error_at(pts, t, u) < toleranceSqd) {
    655             break;
    656         }
    657         nPoints++;
    658     }
    659     for (int j = 1; j <= nPoints; j++) {
    660         append_point_to_contour(to_point(quad.eval(j * u)), contour, alloc);
    661     }
    662 }
    663 
    664 void generate_cubic_points(const SkPoint& p0,
    665                            const SkPoint& p1,
    666                            const SkPoint& p2,
    667                            const SkPoint& p3,
    668                            SkScalar tolSqd,
    669                            VertexList* contour,
    670                            int pointsLeft,
    671                            SkArenaAlloc& alloc) {
    672     SkScalar d1 = p1.distanceToLineSegmentBetweenSqd(p0, p3);
    673     SkScalar d2 = p2.distanceToLineSegmentBetweenSqd(p0, p3);
    674     if (pointsLeft < 2 || (d1 < tolSqd && d2 < tolSqd) ||
    675         !SkScalarIsFinite(d1) || !SkScalarIsFinite(d2)) {
    676         append_point_to_contour(p3, contour, alloc);
    677         return;
    678     }
    679     const SkPoint q[] = {
    680         { SkScalarAve(p0.fX, p1.fX), SkScalarAve(p0.fY, p1.fY) },
    681         { SkScalarAve(p1.fX, p2.fX), SkScalarAve(p1.fY, p2.fY) },
    682         { SkScalarAve(p2.fX, p3.fX), SkScalarAve(p2.fY, p3.fY) }
    683     };
    684     const SkPoint r[] = {
    685         { SkScalarAve(q[0].fX, q[1].fX), SkScalarAve(q[0].fY, q[1].fY) },
    686         { SkScalarAve(q[1].fX, q[2].fX), SkScalarAve(q[1].fY, q[2].fY) }
    687     };
    688     const SkPoint s = { SkScalarAve(r[0].fX, r[1].fX), SkScalarAve(r[0].fY, r[1].fY) };
    689     pointsLeft >>= 1;
    690     generate_cubic_points(p0, q[0], r[0], s, tolSqd, contour, pointsLeft, alloc);
    691     generate_cubic_points(s, r[1], q[2], p3, tolSqd, contour, pointsLeft, alloc);
    692 }
    693 
    694 // Stage 1: convert the input path to a set of linear contours (linked list of Vertices).
    695 
    696 void path_to_contours(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
    697                       VertexList* contours, SkArenaAlloc& alloc, bool *isLinear) {
    698     SkScalar toleranceSqd = tolerance * tolerance;
    699 
    700     SkPoint pts[4];
    701     *isLinear = true;
    702     VertexList* contour = contours;
    703     SkPath::Iter iter(path, false);
    704     if (path.isInverseFillType()) {
    705         SkPoint quad[4];
    706         clipBounds.toQuad(quad);
    707         for (int i = 3; i >= 0; i--) {
    708             append_point_to_contour(quad[i], contours, alloc);
    709         }
    710         contour++;
    711     }
    712     SkAutoConicToQuads converter;
    713     SkPath::Verb verb;
    714     while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
    715         switch (verb) {
    716             case SkPath::kConic_Verb: {
    717                 SkScalar weight = iter.conicWeight();
    718                 const SkPoint* quadPts = converter.computeQuads(pts, weight, toleranceSqd);
    719                 for (int i = 0; i < converter.countQuads(); ++i) {
    720                     append_quadratic_to_contour(quadPts, toleranceSqd, contour, alloc);
    721                     quadPts += 2;
    722                 }
    723                 *isLinear = false;
    724                 break;
    725             }
    726             case SkPath::kMove_Verb:
    727                 if (contour->fHead) {
    728                     contour++;
    729                 }
    730                 append_point_to_contour(pts[0], contour, alloc);
    731                 break;
    732             case SkPath::kLine_Verb: {
    733                 append_point_to_contour(pts[1], contour, alloc);
    734                 break;
    735             }
    736             case SkPath::kQuad_Verb: {
    737                 append_quadratic_to_contour(pts, toleranceSqd, contour, alloc);
    738                 *isLinear = false;
    739                 break;
    740             }
    741             case SkPath::kCubic_Verb: {
    742                 int pointsLeft = GrPathUtils::cubicPointCount(pts, tolerance);
    743                 generate_cubic_points(pts[0], pts[1], pts[2], pts[3], toleranceSqd, contour,
    744                                       pointsLeft, alloc);
    745                 *isLinear = false;
    746                 break;
    747             }
    748             case SkPath::kClose_Verb:
    749             case SkPath::kDone_Verb:
    750                 break;
    751         }
    752     }
    753 }
    754 
    755 inline bool apply_fill_type(SkPath::FillType fillType, int winding) {
    756     switch (fillType) {
    757         case SkPath::kWinding_FillType:
    758             return winding != 0;
    759         case SkPath::kEvenOdd_FillType:
    760             return (winding & 1) != 0;
    761         case SkPath::kInverseWinding_FillType:
    762             return winding == 1;
    763         case SkPath::kInverseEvenOdd_FillType:
    764             return (winding & 1) == 1;
    765         default:
    766             SkASSERT(false);
    767             return false;
    768     }
    769 }
    770 
    771 inline bool apply_fill_type(SkPath::FillType fillType, Poly* poly) {
    772     return poly && apply_fill_type(fillType, poly->fWinding);
    773 }
    774 
    775 Edge* new_edge(Vertex* prev, Vertex* next, Edge::Type type, Comparator& c, SkArenaAlloc& alloc) {
    776     int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1;
    777     Vertex* top = winding < 0 ? next : prev;
    778     Vertex* bottom = winding < 0 ? prev : next;
    779     return alloc.make<Edge>(top, bottom, winding, type);
    780 }
    781 
    782 void remove_edge(Edge* edge, EdgeList* edges) {
    783     LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID);
    784     SkASSERT(edges->contains(edge));
    785     edges->remove(edge);
    786 }
    787 
    788 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) {
    789     LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID);
    790     SkASSERT(!edges->contains(edge));
    791     Edge* next = prev ? prev->fRight : edges->fHead;
    792     edges->insert(edge, prev, next);
    793 }
    794 
    795 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right) {
    796     if (v->fFirstEdgeAbove && v->fLastEdgeAbove) {
    797         *left = v->fFirstEdgeAbove->fLeft;
    798         *right = v->fLastEdgeAbove->fRight;
    799         return;
    800     }
    801     Edge* next = nullptr;
    802     Edge* prev;
    803     for (prev = edges->fTail; prev != nullptr; prev = prev->fLeft) {
    804         if (prev->isLeftOf(v)) {
    805             break;
    806         }
    807         next = prev;
    808     }
    809     *left = prev;
    810     *right = next;
    811 }
    812 
    813 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) {
    814     if (edge->fTop->fPoint == edge->fBottom->fPoint ||
    815         c.sweep_lt(edge->fBottom->fPoint, edge->fTop->fPoint)) {
    816         return;
    817     }
    818     LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBottom->fID, v->fID);
    819     Edge* prev = nullptr;
    820     Edge* next;
    821     for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) {
    822         if (next->isRightOf(edge->fTop)) {
    823             break;
    824         }
    825         prev = next;
    826     }
    827     list_insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>(
    828         edge, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove);
    829 }
    830 
    831 void insert_edge_below(Edge* edge, Vertex* v, Comparator& c) {
    832     if (edge->fTop->fPoint == edge->fBottom->fPoint ||
    833         c.sweep_lt(edge->fBottom->fPoint, edge->fTop->fPoint)) {
    834         return;
    835     }
    836     LOG("insert edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBottom->fID, v->fID);
    837     Edge* prev = nullptr;
    838     Edge* next;
    839     for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) {
    840         if (next->isRightOf(edge->fBottom)) {
    841             break;
    842         }
    843         prev = next;
    844     }
    845     list_insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>(
    846         edge, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow);
    847 }
    848 
    849 void remove_edge_above(Edge* edge) {
    850     LOG("removing edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBottom->fID,
    851         edge->fBottom->fID);
    852     list_remove<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>(
    853         edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove);
    854 }
    855 
    856 void remove_edge_below(Edge* edge) {
    857     LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBottom->fID,
    858         edge->fTop->fID);
    859     list_remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>(
    860         edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow);
    861 }
    862 
    863 void disconnect(Edge* edge)
    864 {
    865     remove_edge_above(edge);
    866     remove_edge_below(edge);
    867 }
    868 
    869 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Vertex** current, Comparator& c);
    870 
    871 void rewind(EdgeList* activeEdges, Vertex** current, Vertex* dst, Comparator& c) {
    872     if (!current || *current == dst || c.sweep_lt((*current)->fPoint, dst->fPoint)) {
    873         return;
    874     }
    875     Vertex* v = *current;
    876     LOG("rewinding active edges from vertex %g to vertex %g\n", v->fID, dst->fID);
    877     while (v != dst) {
    878         v = v->fPrev;
    879         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
    880             remove_edge(e, activeEdges);
    881         }
    882         Edge* leftEdge = v->fLeftEnclosingEdge;
    883         for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
    884             insert_edge(e, leftEdge, activeEdges);
    885             leftEdge = e;
    886         }
    887     }
    888     *current = v;
    889 }
    890 
    891 void rewind_if_necessary(Edge* edge, EdgeList* activeEdges, Vertex** current, Comparator& c) {
    892     if (!activeEdges || !current) {
    893         return;
    894     }
    895     Vertex* top = edge->fTop;
    896     Vertex* bottom = edge->fBottom;
    897     if (edge->fLeft) {
    898         Vertex* leftTop = edge->fLeft->fTop;
    899         Vertex* leftBottom = edge->fLeft->fBottom;
    900         if (c.sweep_lt(leftTop->fPoint, top->fPoint) && !edge->fLeft->isLeftOf(top)) {
    901             rewind(activeEdges, current, leftTop, c);
    902         } else if (c.sweep_lt(top->fPoint, leftTop->fPoint) && !edge->isRightOf(leftTop)) {
    903             rewind(activeEdges, current, top, c);
    904         } else if (c.sweep_lt(bottom->fPoint, leftBottom->fPoint) &&
    905                    !edge->fLeft->isLeftOf(bottom)) {
    906             rewind(activeEdges, current, leftTop, c);
    907         } else if (c.sweep_lt(leftBottom->fPoint, bottom->fPoint) && !edge->isRightOf(leftBottom)) {
    908             rewind(activeEdges, current, top, c);
    909         }
    910     }
    911     if (edge->fRight) {
    912         Vertex* rightTop = edge->fRight->fTop;
    913         Vertex* rightBottom = edge->fRight->fBottom;
    914         if (c.sweep_lt(rightTop->fPoint, top->fPoint) && !edge->fRight->isRightOf(top)) {
    915             rewind(activeEdges, current, rightTop, c);
    916         } else if (c.sweep_lt(top->fPoint, rightTop->fPoint) && !edge->isLeftOf(rightTop)) {
    917             rewind(activeEdges, current, top, c);
    918         } else if (c.sweep_lt(bottom->fPoint, rightBottom->fPoint) &&
    919                    !edge->fRight->isRightOf(bottom)) {
    920             rewind(activeEdges, current, rightTop, c);
    921         } else if (c.sweep_lt(rightBottom->fPoint, bottom->fPoint) &&
    922                    !edge->isLeftOf(rightBottom)) {
    923             rewind(activeEdges, current, top, c);
    924         }
    925     }
    926 }
    927 
    928 void set_top(Edge* edge, Vertex* v, EdgeList* activeEdges, Vertex** current, Comparator& c) {
    929     remove_edge_below(edge);
    930     edge->fTop = v;
    931     edge->recompute();
    932     insert_edge_below(edge, v, c);
    933     rewind_if_necessary(edge, activeEdges, current, c);
    934     merge_collinear_edges(edge, activeEdges, current, c);
    935 }
    936 
    937 void set_bottom(Edge* edge, Vertex* v, EdgeList* activeEdges, Vertex** current, Comparator& c) {
    938     remove_edge_above(edge);
    939     edge->fBottom = v;
    940     edge->recompute();
    941     insert_edge_above(edge, v, c);
    942     rewind_if_necessary(edge, activeEdges, current, c);
    943     merge_collinear_edges(edge, activeEdges, current, c);
    944 }
    945 
    946 void merge_edges_above(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current,
    947                        Comparator& c) {
    948     if (coincident(edge->fTop->fPoint, other->fTop->fPoint)) {
    949         LOG("merging coincident above edges (%g, %g) -> (%g, %g)\n",
    950             edge->fTop->fPoint.fX, edge->fTop->fPoint.fY,
    951             edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY);
    952         rewind(activeEdges, current, edge->fTop, c);
    953         other->fWinding += edge->fWinding;
    954         disconnect(edge);
    955     } else if (c.sweep_lt(edge->fTop->fPoint, other->fTop->fPoint)) {
    956         rewind(activeEdges, current, edge->fTop, c);
    957         other->fWinding += edge->fWinding;
    958         set_bottom(edge, other->fTop, activeEdges, current, c);
    959     } else {
    960         rewind(activeEdges, current, other->fTop, c);
    961         edge->fWinding += other->fWinding;
    962         set_bottom(other, edge->fTop, activeEdges, current, c);
    963     }
    964 }
    965 
    966 void merge_edges_below(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current,
    967                        Comparator& c) {
    968     if (coincident(edge->fBottom->fPoint, other->fBottom->fPoint)) {
    969         LOG("merging coincident below edges (%g, %g) -> (%g, %g)\n",
    970             edge->fTop->fPoint.fX, edge->fTop->fPoint.fY,
    971             edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY);
    972         rewind(activeEdges, current, edge->fTop, c);
    973         other->fWinding += edge->fWinding;
    974         disconnect(edge);
    975     } else if (c.sweep_lt(edge->fBottom->fPoint, other->fBottom->fPoint)) {
    976         rewind(activeEdges, current, other->fTop, c);
    977         edge->fWinding += other->fWinding;
    978         set_top(other, edge->fBottom, activeEdges, current, c);
    979     } else {
    980         rewind(activeEdges, current, edge->fTop, c);
    981         other->fWinding += edge->fWinding;
    982         set_top(edge, other->fBottom, activeEdges, current, c);
    983     }
    984 }
    985 
    986 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Vertex** current, Comparator& c) {
    987     for (;;) {
    988         if (edge->fPrevEdgeAbove && (edge->fTop == edge->fPrevEdgeAbove->fTop ||
    989                                      !edge->fPrevEdgeAbove->isLeftOf(edge->fTop))) {
    990             merge_edges_above(edge, edge->fPrevEdgeAbove, activeEdges, current, c);
    991         } else if (edge->fNextEdgeAbove && (edge->fTop == edge->fNextEdgeAbove->fTop ||
    992                                             !edge->isLeftOf(edge->fNextEdgeAbove->fTop))) {
    993             merge_edges_above(edge, edge->fNextEdgeAbove, activeEdges, current, c);
    994         } else if (edge->fPrevEdgeBelow && (edge->fBottom == edge->fPrevEdgeBelow->fBottom ||
    995                                      !edge->fPrevEdgeBelow->isLeftOf(edge->fBottom))) {
    996             merge_edges_below(edge, edge->fPrevEdgeBelow, activeEdges, current, c);
    997         } else if (edge->fNextEdgeBelow && (edge->fBottom == edge->fNextEdgeBelow->fBottom ||
    998                                             !edge->isLeftOf(edge->fNextEdgeBelow->fBottom))) {
    999             merge_edges_below(edge, edge->fNextEdgeBelow, activeEdges, current, c);
   1000         } else {
   1001             break;
   1002         }
   1003     }
   1004     SkASSERT(!edge->fPrevEdgeAbove || edge->fPrevEdgeAbove->isLeftOf(edge->fTop));
   1005     SkASSERT(!edge->fPrevEdgeBelow || edge->fPrevEdgeBelow->isLeftOf(edge->fBottom));
   1006     SkASSERT(!edge->fNextEdgeAbove || edge->fNextEdgeAbove->isRightOf(edge->fTop));
   1007     SkASSERT(!edge->fNextEdgeBelow || edge->fNextEdgeBelow->isRightOf(edge->fBottom));
   1008 }
   1009 
   1010 void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Vertex** current, Comparator& c,
   1011                 SkArenaAlloc& alloc) {
   1012     if (v == edge->fTop || v == edge->fBottom) {
   1013         return;
   1014     }
   1015     LOG("splitting edge (%g -> %g) at vertex %g (%g, %g)\n",
   1016         edge->fTop->fID, edge->fBottom->fID,
   1017         v->fID, v->fPoint.fX, v->fPoint.fY);
   1018     Vertex* top;
   1019     Vertex* bottom;
   1020     if (c.sweep_lt(v->fPoint, edge->fTop->fPoint)) {
   1021         top = v;
   1022         bottom = edge->fTop;
   1023         set_top(edge, v, activeEdges, current, c);
   1024     } else if (c.sweep_lt(edge->fBottom->fPoint, v->fPoint)) {
   1025         top = edge->fBottom;
   1026         bottom = v;
   1027         set_bottom(edge, v, activeEdges, current, c);
   1028     } else {
   1029         top = v;
   1030         bottom = edge->fBottom;
   1031         set_bottom(edge, v, activeEdges, current, c);
   1032     }
   1033     Edge* newEdge = alloc.make<Edge>(top, bottom, edge->fWinding, edge->fType);
   1034     insert_edge_below(newEdge, top, c);
   1035     insert_edge_above(newEdge, bottom, c);
   1036     merge_collinear_edges(newEdge, activeEdges, current, c);
   1037 }
   1038 
   1039 Edge* connect(Vertex* prev, Vertex* next, Edge::Type type, Comparator& c, SkArenaAlloc& alloc,
   1040               int winding_scale = 1) {
   1041     Edge* edge = new_edge(prev, next, type, c, alloc);
   1042     insert_edge_below(edge, edge->fTop, c);
   1043     insert_edge_above(edge, edge->fBottom, c);
   1044     edge->fWinding *= winding_scale;
   1045     merge_collinear_edges(edge, nullptr, nullptr, c);
   1046     return edge;
   1047 }
   1048 
   1049 void merge_vertices(Vertex* src, Vertex* dst, VertexList* mesh, Comparator& c,
   1050                     SkArenaAlloc& alloc) {
   1051     LOG("found coincident verts at %g, %g; merging %g into %g\n", src->fPoint.fX, src->fPoint.fY,
   1052         src->fID, dst->fID);
   1053     dst->fAlpha = SkTMax(src->fAlpha, dst->fAlpha);
   1054     if (src->fPartner) {
   1055         src->fPartner->fPartner = dst;
   1056     }
   1057     for (Edge* edge = src->fFirstEdgeAbove; edge;) {
   1058         Edge* next = edge->fNextEdgeAbove;
   1059         set_bottom(edge, dst, nullptr, nullptr, c);
   1060         edge = next;
   1061     }
   1062     for (Edge* edge = src->fFirstEdgeBelow; edge;) {
   1063         Edge* next = edge->fNextEdgeBelow;
   1064         set_top(edge, dst, nullptr, nullptr, c);
   1065         edge = next;
   1066     }
   1067     mesh->remove(src);
   1068 }
   1069 
   1070 uint8_t max_edge_alpha(Edge* a, Edge* b) {
   1071     if (a->fType == Edge::Type::kInner || b->fType == Edge::Type::kInner) {
   1072         return 255;
   1073     } else if (a->fType == Edge::Type::kOuter && b->fType == Edge::Type::kOuter) {
   1074         return 0;
   1075     } else {
   1076         return SkTMax(SkTMax(a->fTop->fAlpha, a->fBottom->fAlpha),
   1077                       SkTMax(b->fTop->fAlpha, b->fBottom->fAlpha));
   1078     }
   1079 }
   1080 
   1081 bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current,
   1082                             VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
   1083     if (!edge || !other) {
   1084         return false;
   1085     }
   1086     SkPoint p;
   1087     uint8_t alpha;
   1088     if (edge->intersect(*other, &p, &alpha) && p.isFinite()) {
   1089         Vertex* v;
   1090         LOG("found intersection, pt is %g, %g\n", p.fX, p.fY);
   1091         Vertex* top = *current;
   1092         // If the intersection point is above the current vertex, rewind to the vertex above the
   1093         // intersection.
   1094         while (top && c.sweep_lt(p, top->fPoint)) {
   1095             top = top->fPrev;
   1096         }
   1097         if (p == edge->fTop->fPoint) {
   1098             v = edge->fTop;
   1099         } else if (p == edge->fBottom->fPoint) {
   1100             v = edge->fBottom;
   1101         } else if (p == other->fTop->fPoint) {
   1102             v = other->fTop;
   1103         } else if (p == other->fBottom->fPoint) {
   1104             v = other->fBottom;
   1105         } else {
   1106             Vertex* prevV = top;
   1107             Vertex* nextV = top ? top->fNext : mesh->fHead;
   1108             while (nextV && c.sweep_lt(nextV->fPoint, p)) {
   1109                 prevV = nextV;
   1110                 nextV = nextV->fNext;
   1111             }
   1112             if (prevV && coincident(prevV->fPoint, p)) {
   1113                 v = prevV;
   1114             } else if (nextV && coincident(nextV->fPoint, p)) {
   1115                 v = nextV;
   1116             } else {
   1117                 v = alloc.make<Vertex>(p, alpha);
   1118 #if LOGGING_ENABLED
   1119                 if (!prevV) {
   1120                     v->fID = mesh->fHead->fID - 1.0f;
   1121                 } else if (!nextV) {
   1122                     v->fID = mesh->fTail->fID + 1.0f;
   1123                 } else {
   1124                     v->fID = (prevV->fID + nextV->fID) * 0.5f;
   1125                 }
   1126 #endif
   1127                 mesh->insert(v, prevV, nextV);
   1128             }
   1129         }
   1130         rewind(activeEdges, current, top ? top : v, c);
   1131         split_edge(edge, v, activeEdges, current, c, alloc);
   1132         split_edge(other, v, activeEdges, current, c, alloc);
   1133         v->fAlpha = SkTMax(v->fAlpha, alpha);
   1134         return true;
   1135     }
   1136     return false;
   1137 }
   1138 
   1139 void sanitize_contours(VertexList* contours, int contourCnt, bool approximate) {
   1140     for (VertexList* contour = contours; contourCnt > 0; --contourCnt, ++contour) {
   1141         SkASSERT(contour->fHead);
   1142         Vertex* prev = contour->fTail;
   1143         if (approximate) {
   1144             round(&prev->fPoint);
   1145         }
   1146         for (Vertex* v = contour->fHead; v;) {
   1147             if (approximate) {
   1148                 round(&v->fPoint);
   1149             }
   1150             Vertex* next = v->fNext;
   1151             if (coincident(prev->fPoint, v->fPoint)) {
   1152                 LOG("vertex %g,%g coincident; removing\n", v->fPoint.fX, v->fPoint.fY);
   1153                 contour->remove(v);
   1154             }
   1155             prev = v;
   1156             v = next;
   1157         }
   1158     }
   1159 }
   1160 
   1161 void merge_coincident_vertices(VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
   1162     if (!mesh->fHead) {
   1163         return;
   1164     }
   1165     for (Vertex* v = mesh->fHead->fNext; v != nullptr; v = v->fNext) {
   1166         if (c.sweep_lt(v->fPoint, v->fPrev->fPoint)) {
   1167             v->fPoint = v->fPrev->fPoint;
   1168         }
   1169         if (coincident(v->fPrev->fPoint, v->fPoint)) {
   1170             merge_vertices(v->fPrev, v, mesh, c, alloc);
   1171         }
   1172     }
   1173 }
   1174 
   1175 // Stage 2: convert the contours to a mesh of edges connecting the vertices.
   1176 
   1177 void build_edges(VertexList* contours, int contourCnt, VertexList* mesh, Comparator& c,
   1178                  SkArenaAlloc& alloc) {
   1179     for (VertexList* contour = contours; contourCnt > 0; --contourCnt, ++contour) {
   1180         Vertex* prev = contour->fTail;
   1181         for (Vertex* v = contour->fHead; v;) {
   1182             Vertex* next = v->fNext;
   1183             connect(prev, v, Edge::Type::kInner, c, alloc);
   1184             mesh->append(v);
   1185             prev = v;
   1186             v = next;
   1187         }
   1188     }
   1189 }
   1190 
   1191 void connect_partners(VertexList* outerVertices, Comparator& c, SkArenaAlloc& alloc) {
   1192     for (Vertex* outer = outerVertices->fHead; outer; outer = outer->fNext) {
   1193         if (Vertex* inner = outer->fPartner) {
   1194             // Connector edges get zero winding, since they're only structural (i.e., to ensure
   1195             // no 0-0-0 alpha triangles are produced), and shouldn't affect the poly winding number.
   1196             connect(outer, inner, Edge::Type::kConnector, c, alloc, 0);
   1197             inner->fPartner = outer->fPartner = nullptr;
   1198         }
   1199     }
   1200 }
   1201 
   1202 template <CompareFunc sweep_lt>
   1203 void sorted_merge(VertexList* front, VertexList* back, VertexList* result) {
   1204     Vertex* a = front->fHead;
   1205     Vertex* b = back->fHead;
   1206     while (a && b) {
   1207         if (sweep_lt(a->fPoint, b->fPoint)) {
   1208             front->remove(a);
   1209             result->append(a);
   1210             a = front->fHead;
   1211         } else {
   1212             back->remove(b);
   1213             result->append(b);
   1214             b = back->fHead;
   1215         }
   1216     }
   1217     result->append(*front);
   1218     result->append(*back);
   1219 }
   1220 
   1221 void sorted_merge(VertexList* front, VertexList* back, VertexList* result, Comparator& c) {
   1222     if (c.fDirection == Comparator::Direction::kHorizontal) {
   1223         sorted_merge<sweep_lt_horiz>(front, back, result);
   1224     } else {
   1225         sorted_merge<sweep_lt_vert>(front, back, result);
   1226     }
   1227 #if LOGGING_ENABLED
   1228     float id = 0.0f;
   1229     for (Vertex* v = result->fHead; v; v = v->fNext) {
   1230         v->fID = id++;
   1231     }
   1232 #endif
   1233 }
   1234 
   1235 // Stage 3: sort the vertices by increasing sweep direction.
   1236 
   1237 template <CompareFunc sweep_lt>
   1238 void merge_sort(VertexList* vertices) {
   1239     Vertex* slow = vertices->fHead;
   1240     if (!slow) {
   1241         return;
   1242     }
   1243     Vertex* fast = slow->fNext;
   1244     if (!fast) {
   1245         return;
   1246     }
   1247     do {
   1248         fast = fast->fNext;
   1249         if (fast) {
   1250             fast = fast->fNext;
   1251             slow = slow->fNext;
   1252         }
   1253     } while (fast);
   1254     VertexList front(vertices->fHead, slow);
   1255     VertexList back(slow->fNext, vertices->fTail);
   1256     front.fTail->fNext = back.fHead->fPrev = nullptr;
   1257 
   1258     merge_sort<sweep_lt>(&front);
   1259     merge_sort<sweep_lt>(&back);
   1260 
   1261     vertices->fHead = vertices->fTail = nullptr;
   1262     sorted_merge<sweep_lt>(&front, &back, vertices);
   1263 }
   1264 
   1265 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges.
   1266 
   1267 void simplify(VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
   1268     LOG("simplifying complex polygons\n");
   1269     EdgeList activeEdges;
   1270     for (Vertex* v = mesh->fHead; v != nullptr; v = v->fNext) {
   1271         if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) {
   1272             continue;
   1273         }
   1274         Edge* leftEnclosingEdge;
   1275         Edge* rightEnclosingEdge;
   1276         bool restartChecks;
   1277         do {
   1278             LOG("\nvertex %g: (%g,%g), alpha %d\n", v->fID, v->fPoint.fX, v->fPoint.fY, v->fAlpha);
   1279             restartChecks = false;
   1280             find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge);
   1281             if (rightEnclosingEdge && !rightEnclosingEdge->isRightOf(v)) {
   1282                 split_edge(rightEnclosingEdge, v, &activeEdges, &v, c, alloc);
   1283                 restartChecks = true;
   1284                 continue;
   1285             }
   1286             SkASSERT(!rightEnclosingEdge || rightEnclosingEdge->isRightOf(v));
   1287             v->fLeftEnclosingEdge = leftEnclosingEdge;
   1288             v->fRightEnclosingEdge = rightEnclosingEdge;
   1289             if (v->fFirstEdgeBelow) {
   1290                 for (Edge* edge = v->fFirstEdgeBelow; edge; edge = edge->fNextEdgeBelow) {
   1291                     if (check_for_intersection(edge, leftEnclosingEdge, &activeEdges, &v, mesh, c,
   1292                                                alloc)) {
   1293                         restartChecks = true;
   1294                         break;
   1295                     }
   1296                     if (check_for_intersection(edge, rightEnclosingEdge, &activeEdges, &v, mesh, c,
   1297                                                alloc)) {
   1298                         restartChecks = true;
   1299                         break;
   1300                     }
   1301                 }
   1302             } else {
   1303                 if (check_for_intersection(leftEnclosingEdge, rightEnclosingEdge,
   1304                                            &activeEdges, &v, mesh, c, alloc)) {
   1305                     restartChecks = true;
   1306                 }
   1307 
   1308             }
   1309         } while (restartChecks);
   1310         if (v->fAlpha == 0) {
   1311             if ((leftEnclosingEdge && leftEnclosingEdge->fWinding < 0) &&
   1312                 (rightEnclosingEdge && rightEnclosingEdge->fWinding > 0)) {
   1313                 v->fAlpha = max_edge_alpha(leftEnclosingEdge, rightEnclosingEdge);
   1314             }
   1315         }
   1316         for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
   1317             remove_edge(e, &activeEdges);
   1318         }
   1319         Edge* leftEdge = leftEnclosingEdge;
   1320         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
   1321             insert_edge(e, leftEdge, &activeEdges);
   1322             leftEdge = e;
   1323         }
   1324     }
   1325 }
   1326 
   1327 // This is a stripped-down version of simplify() (the Bentley-Ottmann algorithm) that
   1328 // early-returns true on the first found intersection, false if none.
   1329 bool is_complex(const VertexList& vertices) {
   1330     LOG("testing polygon complexity\n");
   1331     EdgeList activeEdges;
   1332     for (Vertex* v = vertices.fHead; v != nullptr; v = v->fNext) {
   1333         if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) {
   1334             continue;
   1335         }
   1336         Edge* leftEnclosingEdge;
   1337         Edge* rightEnclosingEdge;
   1338         find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge);
   1339         SkPoint dummy;
   1340         if (v->fFirstEdgeBelow) {
   1341             for (Edge* edge = v->fFirstEdgeBelow; edge; edge = edge->fNextEdgeBelow) {
   1342                 if (edge && leftEnclosingEdge && edge->intersect(*leftEnclosingEdge, &dummy)) {
   1343                     activeEdges.removeAll();
   1344                     return true;
   1345                 }
   1346                 if (edge && rightEnclosingEdge && edge->intersect(*rightEnclosingEdge, &dummy)) {
   1347                     activeEdges.removeAll();
   1348                     return true;
   1349                 }
   1350             }
   1351         } else if (leftEnclosingEdge && rightEnclosingEdge &&
   1352                    leftEnclosingEdge->intersect(*rightEnclosingEdge, &dummy)) {
   1353             activeEdges.removeAll();
   1354             return true;
   1355         }
   1356         for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
   1357             remove_edge(e, &activeEdges);
   1358         }
   1359         Edge* leftEdge = leftEnclosingEdge;
   1360         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
   1361             insert_edge(e, leftEdge, &activeEdges);
   1362             leftEdge = e;
   1363         }
   1364     }
   1365     activeEdges.removeAll();
   1366     return false;
   1367 }
   1368 
   1369 // Stage 5: Tessellate the simplified mesh into monotone polygons.
   1370 
   1371 Poly* tessellate(const VertexList& vertices, SkArenaAlloc& alloc) {
   1372     LOG("tessellating simple polygons\n");
   1373     EdgeList activeEdges;
   1374     Poly* polys = nullptr;
   1375     for (Vertex* v = vertices.fHead; v != nullptr; v = v->fNext) {
   1376         if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) {
   1377             continue;
   1378         }
   1379 #if LOGGING_ENABLED
   1380         LOG("\nvertex %g: (%g,%g), alpha %d\n", v->fID, v->fPoint.fX, v->fPoint.fY, v->fAlpha);
   1381 #endif
   1382         Edge* leftEnclosingEdge;
   1383         Edge* rightEnclosingEdge;
   1384         find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge);
   1385         Poly* leftPoly;
   1386         Poly* rightPoly;
   1387         if (v->fFirstEdgeAbove) {
   1388             leftPoly = v->fFirstEdgeAbove->fLeftPoly;
   1389             rightPoly = v->fLastEdgeAbove->fRightPoly;
   1390         } else {
   1391             leftPoly = leftEnclosingEdge ? leftEnclosingEdge->fRightPoly : nullptr;
   1392             rightPoly = rightEnclosingEdge ? rightEnclosingEdge->fLeftPoly : nullptr;
   1393         }
   1394 #if LOGGING_ENABLED
   1395         LOG("edges above:\n");
   1396         for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
   1397             LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID,
   1398                 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRightPoly->fID : -1);
   1399         }
   1400         LOG("edges below:\n");
   1401         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
   1402             LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID,
   1403                 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRightPoly->fID : -1);
   1404         }
   1405 #endif
   1406         if (v->fFirstEdgeAbove) {
   1407             if (leftPoly) {
   1408                 leftPoly = leftPoly->addEdge(v->fFirstEdgeAbove, Poly::kRight_Side, alloc);
   1409             }
   1410             if (rightPoly) {
   1411                 rightPoly = rightPoly->addEdge(v->fLastEdgeAbove, Poly::kLeft_Side, alloc);
   1412             }
   1413             for (Edge* e = v->fFirstEdgeAbove; e != v->fLastEdgeAbove; e = e->fNextEdgeAbove) {
   1414                 Edge* rightEdge = e->fNextEdgeAbove;
   1415                 remove_edge(e, &activeEdges);
   1416                 if (e->fRightPoly) {
   1417                     e->fRightPoly->addEdge(e, Poly::kLeft_Side, alloc);
   1418                 }
   1419                 if (rightEdge->fLeftPoly && rightEdge->fLeftPoly != e->fRightPoly) {
   1420                     rightEdge->fLeftPoly->addEdge(e, Poly::kRight_Side, alloc);
   1421                 }
   1422             }
   1423             remove_edge(v->fLastEdgeAbove, &activeEdges);
   1424             if (!v->fFirstEdgeBelow) {
   1425                 if (leftPoly && rightPoly && leftPoly != rightPoly) {
   1426                     SkASSERT(leftPoly->fPartner == nullptr && rightPoly->fPartner == nullptr);
   1427                     rightPoly->fPartner = leftPoly;
   1428                     leftPoly->fPartner = rightPoly;
   1429                 }
   1430             }
   1431         }
   1432         if (v->fFirstEdgeBelow) {
   1433             if (!v->fFirstEdgeAbove) {
   1434                 if (leftPoly && rightPoly) {
   1435                     if (leftPoly == rightPoly) {
   1436                         if (leftPoly->fTail && leftPoly->fTail->fSide == Poly::kLeft_Side) {
   1437                             leftPoly = new_poly(&polys, leftPoly->lastVertex(),
   1438                                                  leftPoly->fWinding, alloc);
   1439                             leftEnclosingEdge->fRightPoly = leftPoly;
   1440                         } else {
   1441                             rightPoly = new_poly(&polys, rightPoly->lastVertex(),
   1442                                                  rightPoly->fWinding, alloc);
   1443                             rightEnclosingEdge->fLeftPoly = rightPoly;
   1444                         }
   1445                     }
   1446                     Edge* join = alloc.make<Edge>(leftPoly->lastVertex(), v, 1, Edge::Type::kInner);
   1447                     leftPoly = leftPoly->addEdge(join, Poly::kRight_Side, alloc);
   1448                     rightPoly = rightPoly->addEdge(join, Poly::kLeft_Side, alloc);
   1449                 }
   1450             }
   1451             Edge* leftEdge = v->fFirstEdgeBelow;
   1452             leftEdge->fLeftPoly = leftPoly;
   1453             insert_edge(leftEdge, leftEnclosingEdge, &activeEdges);
   1454             for (Edge* rightEdge = leftEdge->fNextEdgeBelow; rightEdge;
   1455                  rightEdge = rightEdge->fNextEdgeBelow) {
   1456                 insert_edge(rightEdge, leftEdge, &activeEdges);
   1457                 int winding = leftEdge->fLeftPoly ? leftEdge->fLeftPoly->fWinding : 0;
   1458                 winding += leftEdge->fWinding;
   1459                 if (winding != 0) {
   1460                     Poly* poly = new_poly(&polys, v, winding, alloc);
   1461                     leftEdge->fRightPoly = rightEdge->fLeftPoly = poly;
   1462                 }
   1463                 leftEdge = rightEdge;
   1464             }
   1465             v->fLastEdgeBelow->fRightPoly = rightPoly;
   1466         }
   1467 #if LOGGING_ENABLED
   1468         LOG("\nactive edges:\n");
   1469         for (Edge* e = activeEdges.fHead; e != nullptr; e = e->fRight) {
   1470             LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID,
   1471                 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRightPoly->fID : -1);
   1472         }
   1473 #endif
   1474     }
   1475     return polys;
   1476 }
   1477 
   1478 void remove_non_boundary_edges(const VertexList& mesh, SkPath::FillType fillType,
   1479                                SkArenaAlloc& alloc) {
   1480     LOG("removing non-boundary edges\n");
   1481     EdgeList activeEdges;
   1482     for (Vertex* v = mesh.fHead; v != nullptr; v = v->fNext) {
   1483         if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) {
   1484             continue;
   1485         }
   1486         Edge* leftEnclosingEdge;
   1487         Edge* rightEnclosingEdge;
   1488         find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge);
   1489         bool prevFilled = leftEnclosingEdge &&
   1490                           apply_fill_type(fillType, leftEnclosingEdge->fWinding);
   1491         for (Edge* e = v->fFirstEdgeAbove; e;) {
   1492             Edge* next = e->fNextEdgeAbove;
   1493             remove_edge(e, &activeEdges);
   1494             bool filled = apply_fill_type(fillType, e->fWinding);
   1495             if (filled == prevFilled) {
   1496                 disconnect(e);
   1497             }
   1498             prevFilled = filled;
   1499             e = next;
   1500         }
   1501         Edge* prev = leftEnclosingEdge;
   1502         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
   1503             if (prev) {
   1504                 e->fWinding += prev->fWinding;
   1505             }
   1506             insert_edge(e, prev, &activeEdges);
   1507             prev = e;
   1508         }
   1509     }
   1510 }
   1511 
   1512 // Note: this is the normal to the edge, but not necessarily unit length.
   1513 void get_edge_normal(const Edge* e, SkVector* normal) {
   1514     normal->set(SkDoubleToScalar(e->fLine.fA) * e->fWinding,
   1515                 SkDoubleToScalar(e->fLine.fB) * e->fWinding);
   1516 }
   1517 
   1518 // Stage 5c: detect and remove "pointy" vertices whose edge normals point in opposite directions
   1519 // and whose adjacent vertices are less than a quarter pixel from an edge. These are guaranteed to
   1520 // invert on stroking.
   1521 
   1522 void simplify_boundary(EdgeList* boundary, Comparator& c, SkArenaAlloc& alloc) {
   1523     Edge* prevEdge = boundary->fTail;
   1524     SkVector prevNormal;
   1525     get_edge_normal(prevEdge, &prevNormal);
   1526     for (Edge* e = boundary->fHead; e != nullptr;) {
   1527         Vertex* prev = prevEdge->fWinding == 1 ? prevEdge->fTop : prevEdge->fBottom;
   1528         Vertex* next = e->fWinding == 1 ? e->fBottom : e->fTop;
   1529         double dist = e->dist(prev->fPoint);
   1530         SkVector normal;
   1531         get_edge_normal(e, &normal);
   1532         double denom = 0.0625f * e->fLine.magSq();
   1533         if (prevNormal.dot(normal) < 0.0 && (dist * dist) <= denom) {
   1534             Edge* join = new_edge(prev, next, Edge::Type::kInner, c, alloc);
   1535             insert_edge(join, e, boundary);
   1536             remove_edge(prevEdge, boundary);
   1537             remove_edge(e, boundary);
   1538             if (join->fLeft && join->fRight) {
   1539                 prevEdge = join->fLeft;
   1540                 e = join;
   1541             } else {
   1542                 prevEdge = boundary->fTail;
   1543                 e = boundary->fHead; // join->fLeft ? join->fLeft : join;
   1544             }
   1545             get_edge_normal(prevEdge, &prevNormal);
   1546         } else {
   1547             prevEdge = e;
   1548             prevNormal = normal;
   1549             e = e->fRight;
   1550         }
   1551     }
   1552 }
   1553 
   1554 void fix_inversions(Vertex* prev, Vertex* next, Edge* prevBisector, Edge* nextBisector,
   1555                     Edge* prevEdge, Comparator& c) {
   1556     if (!prev || !next) {
   1557         return;
   1558     }
   1559     int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1;
   1560     SkPoint p;
   1561     uint8_t alpha;
   1562     if (winding != prevEdge->fWinding && prevBisector->intersect(*nextBisector, &p, &alpha)) {
   1563         prev->fPoint = next->fPoint = p;
   1564         prev->fAlpha = next->fAlpha = alpha;
   1565     }
   1566 }
   1567 
   1568 // Stage 5d: Displace edges by half a pixel inward and outward along their normals. Intersect to
   1569 // find new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a
   1570 // new antialiased mesh from those vertices.
   1571 
   1572 void stroke_boundary(EdgeList* boundary, VertexList* innerMesh, VertexList* outerMesh,
   1573                      Comparator& c, SkArenaAlloc& alloc) {
   1574     // A boundary with fewer than 3 edges is degenerate.
   1575     if (!boundary->fHead || !boundary->fHead->fRight || !boundary->fHead->fRight->fRight) {
   1576         return;
   1577     }
   1578     Edge* prevEdge = boundary->fTail;
   1579     float radius = 0.5f;
   1580     double offset = radius * sqrt(prevEdge->fLine.magSq()) * prevEdge->fWinding;
   1581     Line prevInner(prevEdge->fLine);
   1582     prevInner.fC -= offset;
   1583     Line prevOuter(prevEdge->fLine);
   1584     prevOuter.fC += offset;
   1585     VertexList innerVertices;
   1586     VertexList outerVertices;
   1587     Edge* prevBisector = nullptr;
   1588     for (Edge* e = boundary->fHead; e != nullptr; e = e->fRight) {
   1589         double offset = radius * sqrt(e->fLine.magSq()) * e->fWinding;
   1590         Line inner(e->fLine);
   1591         inner.fC -= offset;
   1592         Line outer(e->fLine);
   1593         outer.fC += offset;
   1594         SkPoint innerPoint, outerPoint;
   1595         if (prevInner.intersect(inner, &innerPoint) &&
   1596             prevOuter.intersect(outer, &outerPoint)) {
   1597             Vertex* innerVertex = alloc.make<Vertex>(innerPoint, 255);
   1598             Vertex* outerVertex = alloc.make<Vertex>(outerPoint, 0);
   1599             Edge* bisector = new_edge(outerVertex, innerVertex, Edge::Type::kConnector, c, alloc);
   1600             fix_inversions(innerVertices.fTail, innerVertex, prevBisector, bisector, prevEdge, c);
   1601             fix_inversions(outerVertices.fTail, outerVertex, prevBisector, bisector, prevEdge, c);
   1602             innerVertex->fPartner = outerVertex;
   1603             outerVertex->fPartner = innerVertex;
   1604             innerVertices.append(innerVertex);
   1605             outerVertices.append(outerVertex);
   1606             prevBisector = bisector;
   1607         }
   1608         prevInner = inner;
   1609         prevOuter = outer;
   1610         prevEdge = e;
   1611     }
   1612 
   1613     Vertex* innerVertex = innerVertices.fHead;
   1614     Vertex* outerVertex = outerVertices.fHead;
   1615     if (!innerVertex || !outerVertex) {
   1616         return;
   1617     }
   1618     Edge* bisector = new_edge(outerVertices.fHead, innerVertices.fHead, Edge::Type::kConnector, c,
   1619                               alloc);
   1620     fix_inversions(innerVertices.fTail, innerVertices.fHead, prevBisector, bisector, prevEdge, c);
   1621     fix_inversions(outerVertices.fTail, outerVertices.fHead, prevBisector, bisector, prevEdge, c);
   1622     Vertex* prevInnerVertex = innerVertices.fTail;
   1623     Vertex* prevOuterVertex = outerVertices.fTail;
   1624     while (innerVertex && outerVertex) {
   1625         // Connect vertices into a quad mesh. Outer edges get default (1) winding.
   1626         // Inner edges get -2 winding. This ensures that the interior is always filled
   1627         // (-1 winding number for normal cases, 3 for thin features where the interior inverts).
   1628         connect(prevOuterVertex, outerVertex, Edge::Type::kOuter, c, alloc);
   1629         connect(prevInnerVertex, innerVertex, Edge::Type::kInner, c, alloc, -2);
   1630         prevInnerVertex = innerVertex;
   1631         prevOuterVertex = outerVertex;
   1632         innerVertex = innerVertex->fNext;
   1633         outerVertex = outerVertex->fNext;
   1634     }
   1635     innerMesh->append(innerVertices);
   1636     outerMesh->append(outerVertices);
   1637 }
   1638 
   1639 void extract_boundary(EdgeList* boundary, Edge* e, SkPath::FillType fillType, SkArenaAlloc& alloc) {
   1640     bool down = apply_fill_type(fillType, e->fWinding);
   1641     while (e) {
   1642         e->fWinding = down ? 1 : -1;
   1643         Edge* next;
   1644         boundary->append(e);
   1645         if (down) {
   1646             // Find outgoing edge, in clockwise order.
   1647             if ((next = e->fNextEdgeAbove)) {
   1648                 down = false;
   1649             } else if ((next = e->fBottom->fLastEdgeBelow)) {
   1650                 down = true;
   1651             } else if ((next = e->fPrevEdgeAbove)) {
   1652                 down = false;
   1653             }
   1654         } else {
   1655             // Find outgoing edge, in counter-clockwise order.
   1656             if ((next = e->fPrevEdgeBelow)) {
   1657                 down = true;
   1658             } else if ((next = e->fTop->fFirstEdgeAbove)) {
   1659                 down = false;
   1660             } else if ((next = e->fNextEdgeBelow)) {
   1661                 down = true;
   1662             }
   1663         }
   1664         disconnect(e);
   1665         e = next;
   1666     }
   1667 }
   1668 
   1669 // Stage 5b: Extract boundaries from mesh, simplify and stroke them into a new mesh.
   1670 
   1671 void extract_boundaries(const VertexList& inMesh, VertexList* innerVertices,
   1672                         VertexList* outerVertices, SkPath::FillType fillType,
   1673                         Comparator& c, SkArenaAlloc& alloc) {
   1674     remove_non_boundary_edges(inMesh, fillType, alloc);
   1675     for (Vertex* v = inMesh.fHead; v; v = v->fNext) {
   1676         while (v->fFirstEdgeBelow) {
   1677             EdgeList boundary;
   1678             extract_boundary(&boundary, v->fFirstEdgeBelow, fillType, alloc);
   1679             simplify_boundary(&boundary, c, alloc);
   1680             stroke_boundary(&boundary, innerVertices, outerVertices, c, alloc);
   1681         }
   1682     }
   1683 }
   1684 
   1685 // This is a driver function that calls stages 2-5 in turn.
   1686 
   1687 void contours_to_mesh(VertexList* contours, int contourCnt, bool antialias,
   1688                       VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
   1689 #if LOGGING_ENABLED
   1690     for (int i = 0; i < contourCnt; ++i) {
   1691         Vertex* v = contours[i].fHead;
   1692         SkASSERT(v);
   1693         LOG("path.moveTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY);
   1694         for (v = v->fNext; v; v = v->fNext) {
   1695             LOG("path.lineTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY);
   1696         }
   1697     }
   1698 #endif
   1699     sanitize_contours(contours, contourCnt, antialias);
   1700     build_edges(contours, contourCnt, mesh, c, alloc);
   1701 }
   1702 
   1703 void sort_mesh(VertexList* vertices, Comparator& c, SkArenaAlloc& alloc) {
   1704     if (!vertices || !vertices->fHead) {
   1705         return;
   1706     }
   1707 
   1708     // Sort vertices in Y (secondarily in X).
   1709     if (c.fDirection == Comparator::Direction::kHorizontal) {
   1710         merge_sort<sweep_lt_horiz>(vertices);
   1711     } else {
   1712         merge_sort<sweep_lt_vert>(vertices);
   1713     }
   1714 #if LOGGING_ENABLED
   1715     for (Vertex* v = vertices->fHead; v != nullptr; v = v->fNext) {
   1716         static float gID = 0.0f;
   1717         v->fID = gID++;
   1718     }
   1719 #endif
   1720 }
   1721 
   1722 Poly* contours_to_polys(VertexList* contours, int contourCnt, SkPath::FillType fillType,
   1723                         const SkRect& pathBounds, bool antialias, VertexList* outerMesh,
   1724                         SkArenaAlloc& alloc) {
   1725     Comparator c(pathBounds.width() > pathBounds.height() ? Comparator::Direction::kHorizontal
   1726                                                           : Comparator::Direction::kVertical);
   1727     VertexList mesh;
   1728     contours_to_mesh(contours, contourCnt, antialias, &mesh, c, alloc);
   1729     sort_mesh(&mesh, c, alloc);
   1730     merge_coincident_vertices(&mesh, c, alloc);
   1731     simplify(&mesh, c, alloc);
   1732     if (antialias) {
   1733         VertexList innerMesh;
   1734         extract_boundaries(mesh, &innerMesh, outerMesh, fillType, c, alloc);
   1735         sort_mesh(&innerMesh, c, alloc);
   1736         sort_mesh(outerMesh, c, alloc);
   1737         if (is_complex(innerMesh) || is_complex(*outerMesh)) {
   1738             LOG("found complex mesh; taking slow path\n");
   1739             VertexList aaMesh;
   1740             connect_partners(outerMesh, c, alloc);
   1741             sorted_merge(&innerMesh, outerMesh, &aaMesh, c);
   1742             merge_coincident_vertices(&aaMesh, c, alloc);
   1743             simplify(&aaMesh, c, alloc);
   1744             outerMesh->fHead = outerMesh->fTail = nullptr;
   1745             return tessellate(aaMesh, alloc);
   1746         } else {
   1747             LOG("no complex polygons; taking fast path\n");
   1748             merge_coincident_vertices(&innerMesh, c, alloc);
   1749             return tessellate(innerMesh, alloc);
   1750         }
   1751     } else {
   1752         return tessellate(mesh, alloc);
   1753     }
   1754 }
   1755 
   1756 // Stage 6: Triangulate the monotone polygons into a vertex buffer.
   1757 void* polys_to_triangles(Poly* polys, SkPath::FillType fillType, const AAParams* aaParams,
   1758                          void* data) {
   1759     for (Poly* poly = polys; poly; poly = poly->fNext) {
   1760         if (apply_fill_type(fillType, poly)) {
   1761             data = poly->emit(aaParams, data);
   1762         }
   1763     }
   1764     return data;
   1765 }
   1766 
   1767 Poly* path_to_polys(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
   1768                     int contourCnt, SkArenaAlloc& alloc, bool antialias, bool* isLinear,
   1769                     VertexList* outerMesh) {
   1770     SkPath::FillType fillType = path.getFillType();
   1771     if (SkPath::IsInverseFillType(fillType)) {
   1772         contourCnt++;
   1773     }
   1774     std::unique_ptr<VertexList[]> contours(new VertexList[contourCnt]);
   1775 
   1776     path_to_contours(path, tolerance, clipBounds, contours.get(), alloc, isLinear);
   1777     return contours_to_polys(contours.get(), contourCnt, path.getFillType(), path.getBounds(),
   1778                              antialias, outerMesh, alloc);
   1779 }
   1780 
   1781 int get_contour_count(const SkPath& path, SkScalar tolerance) {
   1782     int contourCnt;
   1783     int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, tolerance);
   1784     if (maxPts <= 0) {
   1785         return 0;
   1786     }
   1787     if (maxPts > ((int)SK_MaxU16 + 1)) {
   1788         SkDebugf("Path not rendered, too many verts (%d)\n", maxPts);
   1789         return 0;
   1790     }
   1791     return contourCnt;
   1792 }
   1793 
   1794 int count_points(Poly* polys, SkPath::FillType fillType) {
   1795     int count = 0;
   1796     for (Poly* poly = polys; poly; poly = poly->fNext) {
   1797         if (apply_fill_type(fillType, poly) && poly->fCount >= 3) {
   1798             count += (poly->fCount - 2) * (TESSELLATOR_WIREFRAME ? 6 : 3);
   1799         }
   1800     }
   1801     return count;
   1802 }
   1803 
   1804 int count_outer_mesh_points(const VertexList& outerMesh) {
   1805     int count = 0;
   1806     for (Vertex* v = outerMesh.fHead; v; v = v->fNext) {
   1807         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
   1808             count += TESSELLATOR_WIREFRAME ? 12 : 6;
   1809         }
   1810     }
   1811     return count;
   1812 }
   1813 
   1814 void* outer_mesh_to_triangles(const VertexList& outerMesh, const AAParams* aaParams, void* data) {
   1815     for (Vertex* v = outerMesh.fHead; v; v = v->fNext) {
   1816         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
   1817             Vertex* v0 = e->fTop;
   1818             Vertex* v1 = e->fBottom;
   1819             Vertex* v2 = e->fBottom->fPartner;
   1820             Vertex* v3 = e->fTop->fPartner;
   1821             data = emit_triangle(v0, v1, v2, aaParams, data);
   1822             data = emit_triangle(v0, v2, v3, aaParams, data);
   1823         }
   1824     }
   1825     return data;
   1826 }
   1827 
   1828 } // namespace
   1829 
   1830 namespace GrTessellator {
   1831 
   1832 // Stage 6: Triangulate the monotone polygons into a vertex buffer.
   1833 
   1834 int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
   1835                     VertexAllocator* vertexAllocator, bool antialias, const GrColor& color,
   1836                     bool canTweakAlphaForCoverage, bool* isLinear) {
   1837     int contourCnt = get_contour_count(path, tolerance);
   1838     if (contourCnt <= 0) {
   1839         *isLinear = true;
   1840         return 0;
   1841     }
   1842     SkArenaAlloc alloc(kArenaChunkSize);
   1843     VertexList outerMesh;
   1844     Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, antialias,
   1845                                 isLinear, &outerMesh);
   1846     SkPath::FillType fillType = antialias ? SkPath::kWinding_FillType : path.getFillType();
   1847     int count = count_points(polys, fillType);
   1848     if (antialias) {
   1849         count += count_outer_mesh_points(outerMesh);
   1850     }
   1851     if (0 == count) {
   1852         return 0;
   1853     }
   1854 
   1855     void* verts = vertexAllocator->lock(count);
   1856     if (!verts) {
   1857         SkDebugf("Could not allocate vertices\n");
   1858         return 0;
   1859     }
   1860 
   1861     LOG("emitting %d verts\n", count);
   1862     AAParams aaParams;
   1863     aaParams.fTweakAlpha = canTweakAlphaForCoverage;
   1864     aaParams.fColor = color;
   1865 
   1866     void* end = polys_to_triangles(polys, fillType, antialias ? &aaParams : nullptr, verts);
   1867     end = outer_mesh_to_triangles(outerMesh, &aaParams, end);
   1868     int actualCount = static_cast<int>((static_cast<uint8_t*>(end) - static_cast<uint8_t*>(verts))
   1869                                        / vertexAllocator->stride());
   1870     SkASSERT(actualCount <= count);
   1871     vertexAllocator->unlock(actualCount);
   1872     return actualCount;
   1873 }
   1874 
   1875 int PathToVertices(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
   1876                    GrTessellator::WindingVertex** verts) {
   1877     int contourCnt = get_contour_count(path, tolerance);
   1878     if (contourCnt <= 0) {
   1879         return 0;
   1880     }
   1881     SkArenaAlloc alloc(kArenaChunkSize);
   1882     bool isLinear;
   1883     Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, false, &isLinear,
   1884                                 nullptr);
   1885     SkPath::FillType fillType = path.getFillType();
   1886     int count = count_points(polys, fillType);
   1887     if (0 == count) {
   1888         *verts = nullptr;
   1889         return 0;
   1890     }
   1891 
   1892     *verts = new GrTessellator::WindingVertex[count];
   1893     GrTessellator::WindingVertex* vertsEnd = *verts;
   1894     SkPoint* points = new SkPoint[count];
   1895     SkPoint* pointsEnd = points;
   1896     for (Poly* poly = polys; poly; poly = poly->fNext) {
   1897         if (apply_fill_type(fillType, poly)) {
   1898             SkPoint* start = pointsEnd;
   1899             pointsEnd = static_cast<SkPoint*>(poly->emit(nullptr, pointsEnd));
   1900             while (start != pointsEnd) {
   1901                 vertsEnd->fPos = *start;
   1902                 vertsEnd->fWinding = poly->fWinding;
   1903                 ++start;
   1904                 ++vertsEnd;
   1905             }
   1906         }
   1907     }
   1908     int actualCount = static_cast<int>(vertsEnd - *verts);
   1909     SkASSERT(actualCount <= count);
   1910     SkASSERT(pointsEnd - points == actualCount);
   1911     delete[] points;
   1912     return actualCount;
   1913 }
   1914 
   1915 } // namespace
   1916