Extract a GrAATriangulator class

Bug: skia:10419
Change-Id: I0394697fdc292cabeb81da508e1acdc74e2127ff
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350257
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrTriangulator.cpp b/src/gpu/GrTriangulator.cpp
index 3a21038..5d86e4c 100644
--- a/src/gpu/GrTriangulator.cpp
+++ b/src/gpu/GrTriangulator.cpp
@@ -23,14 +23,14 @@
 
 #if TRIANGULATOR_LOGGING
 #define TESS_LOG printf
+#define DUMP_MESH(M) dump_mesh(M)
 #else
 #define TESS_LOG(...)
+#define DUMP_MESH(M)
 #endif
 
 constexpr static float kCosMiterAngle = 0.97f; // Corresponds to an angle of ~14 degrees.
 
-struct Event;
-
 using EdgeType = GrTriangulator::EdgeType;
 using Vertex = GrTriangulator::Vertex;
 using VertexList = GrTriangulator::VertexList;
@@ -40,6 +40,10 @@
 using Poly = GrTriangulator::Poly;
 using MonotonePoly = GrTriangulator::MonotonePoly;
 using Comparator = GrTriangulator::Comparator;
+using SSEdge = GrAATriangulator::SSEdge;
+using EventList = GrAATriangulator::EventList;
+using Event = GrAATriangulator::Event;
+using EventComparator = GrAATriangulator::EventComparator;
 
 template <class T, T* T::*Prev, T* T::*Next>
 static void list_insert(T* t, T* prev, T* next, T** head, T** tail) {
@@ -186,8 +190,6 @@
     return true;
 }
 
-struct SSEdge;
-
 struct SSVertex {
     SSVertex(Vertex* v) : fVertex(v), fPrev(nullptr), fNext(nullptr) {}
     Vertex* fVertex;
@@ -195,7 +197,7 @@
     SSEdge* fNext;
 };
 
-struct SSEdge {
+struct GrAATriangulator::SSEdge {
     SSEdge(Edge* edge, SSVertex* prev, SSVertex* next)
       : fEdge(edge), fEvent(nullptr), fPrev(prev), fNext(next) {
     }
@@ -215,36 +217,14 @@
     list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &fHead, &fTail);
 }
 
-struct EventList;
-
-struct Event {
-    Event(SSEdge* edge, const SkPoint& point, uint8_t alpha)
-      : fEdge(edge), fPoint(point), fAlpha(alpha) {
-    }
-    SSEdge* fEdge;
-    SkPoint fPoint;
-    uint8_t fAlpha;
-    void apply(VertexList* mesh, const Comparator& c, EventList* events, SkArenaAlloc& alloc);
-};
-
-struct EventComparator {
-    enum class Op { kLessThan, kGreaterThan };
-    EventComparator(Op op) : fOp(op) {}
-    bool operator() (Event* const &e1, Event* const &e2) {
-        return fOp == Op::kLessThan ? e1->fAlpha < e2->fAlpha
-                                    : e1->fAlpha > e2->fAlpha;
-    }
-    Op fOp;
-};
-
 typedef  std::priority_queue<Event*, std::vector<Event*>, EventComparator> EventPQ;
 
-struct EventList : EventPQ {
+struct GrAATriangulator::EventList : EventPQ {
     EventList(EventComparator comparison) : EventPQ(comparison) {
     }
 };
 
-static void create_event(SSEdge* e, EventList* events, SkArenaAlloc& alloc) {
+void GrAATriangulator::makeEvent(SSEdge* e, EventList* events) {
     Vertex* prev = e->fPrev->fVertex;
     Vertex* next = e->fNext->fVertex;
     if (prev == next || !prev->fPartner || !next->fPartner) {
@@ -259,13 +239,13 @@
                  "will collapse to %g,%g alpha %d\n",
                   prev->fID, next->fID, e->fEdge->fTop->fID, e->fEdge->fBottom->fID, p.fX, p.fY,
                   alpha);
-        e->fEvent = alloc.make<Event>(e, p, alpha);
+        e->fEvent = fAlloc.make<Event>(e, p, alpha);
         events->push(e->fEvent);
     }
 }
 
-static void create_event(SSEdge* edge, Vertex* v, SSEdge* other, Vertex* dest, EventList* events,
-                         const Comparator& c, SkArenaAlloc& alloc) {
+void GrAATriangulator::makeEvent(SSEdge* edge, Vertex* v, SSEdge* other, Vertex* dest,
+                                 EventList* events, const Comparator& c) {
     if (!v->fPartner) {
         return;
     }
@@ -284,7 +264,7 @@
         TESS_LOG("found p edge event for %g, %g (original %g -> %g), "
                  "will collapse to %g,%g alpha %d\n",
                  dest->fID, v->fID, top->fID, bottom->fID, p.fX, p.fY, alpha);
-        edge->fEvent = alloc.make<Event>(edge, p, alpha);
+        edge->fEvent = fAlloc.make<Event>(edge, p, alpha);
         events->push(edge->fEvent);
     }
 }
@@ -415,8 +395,8 @@
     return a == b;
 }
 
-static Poly* new_poly(Poly** head, Vertex* v, int winding, SkArenaAlloc& alloc) {
-    Poly* poly = alloc.make<Poly>(v, winding);
+Poly* GrTriangulator::makePoly(Poly** head, Vertex* v, int winding) {
+    Poly* poly = fAlloc.make<Poly>(v, winding);
     poly->fNext = *head;
     *head = poly;
     return poly;
@@ -582,12 +562,11 @@
     return poly && apply_fill_type(fillType, poly->fWinding);
 }
 
-static Edge* new_edge(Vertex* prev, Vertex* next, EdgeType type, const Comparator& c,
-                      SkArenaAlloc& alloc) {
+Edge* GrTriangulator::makeEdge(Vertex* prev, Vertex* next, EdgeType type, const Comparator& c) {
     int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1;
     Vertex* top = winding < 0 ? next : prev;
     Vertex* bottom = winding < 0 ? prev : next;
-    return alloc.make<Edge>(top, bottom, winding, type);
+    return fAlloc.make<Edge>(top, bottom, winding, type);
 }
 
 static void remove_edge(Edge* edge, EdgeList* edges) {
@@ -910,15 +889,15 @@
     return false;
 }
 
-static Edge* connect(Vertex* prev, Vertex* next, EdgeType type, const Comparator& c,
-                     SkArenaAlloc& alloc, int winding_scale = 1) {
+Edge* GrTriangulator::makeConnectingEdge(Vertex* prev, Vertex* next, EdgeType type,
+                                         const Comparator& c, int windingScale) {
     if (!prev || !next || prev->fPoint == next->fPoint) {
         return nullptr;
     }
-    Edge* edge = new_edge(prev, next, type, c, alloc);
+    Edge* edge = this->makeEdge(prev, next, type, c);
     insert_edge_below(edge, edge->fTop, c);
     insert_edge_above(edge, edge->fBottom, c);
-    edge->fWinding *= winding_scale;
+    edge->fWinding *= windingScale;
     merge_collinear_edges(edge, nullptr, nullptr, c);
     return edge;
 }
@@ -940,8 +919,8 @@
     dst->fSynthetic = true;
 }
 
-static Vertex* create_sorted_vertex(const SkPoint& p, uint8_t alpha, VertexList* mesh,
-                                    Vertex* reference, const Comparator& c, SkArenaAlloc& alloc) {
+Vertex* GrTriangulator::makeSortedVertex(const SkPoint& p, uint8_t alpha, VertexList* mesh,
+                                         Vertex* reference, const Comparator& c) {
     Vertex* prevV = reference;
     while (prevV && c.sweep_lt(p, prevV->fPoint)) {
         prevV = prevV->fPrev;
@@ -957,7 +936,7 @@
     } else if (nextV && coincident(nextV->fPoint, p)) {
         v = nextV;
     } else {
-        v = alloc.make<Vertex>(p, alpha);
+        v = fAlloc.make<Vertex>(p, alpha);
 #if TRIANGULATOR_LOGGING
         if (!prevV) {
             v->fID = mesh->fHead->fID - 1.0f;
@@ -991,7 +970,7 @@
     }
 }
 
-static void compute_bisector(Edge* edge1, Edge* edge2, Vertex* v, SkArenaAlloc& alloc) {
+void GrTriangulator::computeBisector(Edge* edge1, Edge* edge2, Vertex* v) {
     Line line1 = edge1->fLine;
     Line line2 = edge2->fLine;
     line1.normalize();
@@ -1005,7 +984,7 @@
     SkPoint p;
     if (line1.intersect(line2, &p)) {
         uint8_t alpha = edge1->fType == EdgeType::kOuter ? 255 : 0;
-        v->fPartner = alloc.make<Vertex>(p, alpha);
+        v->fPartner = fAlloc.make<Vertex>(p, alpha);
         TESS_LOG("computed bisector (%g,%g) alpha %d for vertex %g\n", p.fX, p.fY, alpha, v->fID);
     }
 }
@@ -1041,10 +1020,10 @@
         } else if (p == right->fBottom->fPoint) {
             v = right->fBottom;
         } else {
-            v = create_sorted_vertex(p, alpha, mesh, top, c, fAlloc);
+            v = this->makeSortedVertex(p, alpha, mesh, top, c);
             if (left->fTop->fPartner) {
                 v->fSynthetic = true;
-                compute_bisector(left, right, v, fAlloc);
+                this->computeBisector(left, right, v);
             }
         }
         rewind(activeEdges, current, top ? top : v, c);
@@ -1114,7 +1093,7 @@
         Vertex* prev = contour->fTail;
         for (Vertex* v = contour->fHead; v;) {
             Vertex* next = v->fNext;
-            connect(prev, v, EdgeType::kInner, c, fAlloc);
+            this->makeConnectingEdge(prev, v, EdgeType::kInner, c);
             mesh->append(v);
             prev = v;
             v = next;
@@ -1122,14 +1101,14 @@
     }
 }
 
-static void connect_partners(VertexList* mesh, const Comparator& c, SkArenaAlloc& alloc) {
+void GrAATriangulator::connectPartners(VertexList* mesh, const Comparator& c) {
     for (Vertex* outer = mesh->fHead; outer; outer = outer->fNext) {
         if (Vertex* inner = outer->fPartner) {
             if ((inner->fPrev || inner->fNext) && (outer->fPrev || outer->fNext)) {
                 // Connector edges get zero winding, since they're only structural (i.e., to ensure
                 // no 0-0-0 alpha triangles are produced), and shouldn't affect the poly winding
                 // number.
-                connect(outer, inner, EdgeType::kConnector, c, alloc, 0);
+                this->makeConnectingEdge(outer, inner, EdgeType::kConnector, c, 0);
                 inner->fPartner = outer->fPartner = nullptr;
             }
         }
@@ -1200,8 +1179,8 @@
     sorted_merge<sweep_lt>(&front, &back, vertices);
 }
 
-static void dump_mesh(const VertexList& mesh) {
 #if TRIANGULATOR_LOGGING
+static void dump_mesh(const VertexList& mesh) {
     for (Vertex* v = mesh.fHead; v; v = v->fNext) {
         TESS_LOG("vertex %g (%g, %g) alpha %d", v->fID, v->fPoint.fX, v->fPoint.fY, v->fAlpha);
         if (Vertex* p = v->fPartner) {
@@ -1217,8 +1196,8 @@
             TESS_LOG("  edge %g -> %g, winding %d\n", e->fTop->fID, e->fBottom->fID, e->fWinding);
         }
     }
-#endif
 }
+#endif
 
 static void dump_skel(const SSEdgeList& ssEdges) {
 #if TRIANGULATOR_LOGGING
@@ -1342,7 +1321,7 @@
 
 // Stage 5: Tessellate the simplified mesh into monotone polygons.
 
-Poly* GrTriangulator::tessellate(const VertexList& vertices) {
+Poly* GrTriangulator::tessellate(const VertexList& vertices, VertexList*, const Comparator&) {
     TESS_LOG("\ntessellating simple polygons\n");
     int maxWindMagnitude = std::numeric_limits<int>::max();
     if (fSimpleInnerPolygons && !SkPathFillType_IsEvenOdd(fPath.getFillType())) {
@@ -1416,12 +1395,12 @@
                 if (leftPoly && rightPoly) {
                     if (leftPoly == rightPoly) {
                         if (leftPoly->fTail && leftPoly->fTail->fSide == kLeft_Side) {
-                            leftPoly = new_poly(&polys, leftPoly->lastVertex(),
-                                                 leftPoly->fWinding, fAlloc);
+                            leftPoly = this->makePoly(&polys, leftPoly->lastVertex(),
+                                                      leftPoly->fWinding);
                             leftEnclosingEdge->fRightPoly = leftPoly;
                         } else {
-                            rightPoly = new_poly(&polys, rightPoly->lastVertex(),
-                                                 rightPoly->fWinding, fAlloc);
+                            rightPoly = this->makePoly(&polys, rightPoly->lastVertex(),
+                                                       rightPoly->fWinding);
                             rightEnclosingEdge->fLeftPoly = rightPoly;
                         }
                     }
@@ -1443,7 +1422,7 @@
                     if (abs(winding) > maxWindMagnitude) {
                         return nullptr;  // We can't have weighted wind in kSimpleInnerPolygons mode
                     }
-                    Poly* poly = new_poly(&polys, v, winding, fAlloc);
+                    Poly* poly = this->makePoly(&polys, v, winding);
                     leftEdge->fRightPoly = rightEdge->fLeftPoly = poly;
                 }
                 leftEdge = rightEdge;
@@ -1463,8 +1442,7 @@
     return polys;
 }
 
-static void remove_non_boundary_edges(const VertexList& mesh, SkPathFillType fillType,
-                                      SkArenaAlloc& alloc) {
+void GrAATriangulator::removeNonBoundaryEdges(const VertexList& mesh) {
     TESS_LOG("removing non-boundary edges\n");
     EdgeList activeEdges;
     for (Vertex* v = mesh.fHead; v != nullptr; v = v->fNext) {
@@ -1475,11 +1453,11 @@
         Edge* rightEnclosingEdge;
         find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge);
         bool prevFilled = leftEnclosingEdge &&
-                          apply_fill_type(fillType, leftEnclosingEdge->fWinding);
+                          apply_fill_type(fPath.getFillType(), leftEnclosingEdge->fWinding);
         for (Edge* e = v->fFirstEdgeAbove; e;) {
             Edge* next = e->fNextEdgeAbove;
             remove_edge(e, &activeEdges);
-            bool filled = apply_fill_type(fillType, e->fWinding);
+            bool filled = apply_fill_type(fPath.getFillType(), e->fWinding);
             if (filled == prevFilled) {
                 disconnect(e);
             }
@@ -1507,7 +1485,7 @@
 // and whose adjacent vertices are less than a quarter pixel from an edge. These are guaranteed to
 // invert on stroking.
 
-static void simplify_boundary(EdgeList* boundary, const Comparator& c, SkArenaAlloc& alloc) {
+void GrAATriangulator::simplifyBoundary(EdgeList* boundary, const Comparator& c) {
     Edge* prevEdge = boundary->fTail;
     SkVector prevNormal;
     get_edge_normal(prevEdge, &prevNormal);
@@ -1529,7 +1507,7 @@
             }
         } else if (prevNormal.dot(normal) < 0.0 &&
             (distPrev * distPrev <= kQuarterPixelSq || distNext * distNext <= kQuarterPixelSq)) {
-            Edge* join = new_edge(prev, next, EdgeType::kInner, c, alloc);
+            Edge* join = this->makeEdge(prev, next, EdgeType::kInner, c);
             if (prev->fPoint != next->fPoint) {
                 join->fLine.normalize();
                 join->fLine = join->fLine * join->fWinding;
@@ -1553,13 +1531,13 @@
     }
 }
 
-static void ss_connect(Vertex* v, Vertex* dest, const Comparator& c, SkArenaAlloc& alloc) {
+void GrAATriangulator::connectSSEdge(Vertex* v, Vertex* dest, const Comparator& c) {
     if (v == dest) {
         return;
     }
     TESS_LOG("ss_connecting vertex %g to vertex %g\n", v->fID, dest->fID);
     if (v->fSynthetic) {
-        connect(v, dest, EdgeType::kConnector, c, alloc, 0);
+        this->makeConnectingEdge(v, dest, EdgeType::kConnector, c, 0);
     } else if (v->fPartner) {
         TESS_LOG("setting %g's partner to %g ", v->fPartner->fID, dest->fID);
         TESS_LOG("and %g's partner to null\n", v->fID);
@@ -1568,7 +1546,8 @@
     }
 }
 
-void Event::apply(VertexList* mesh, const Comparator& c, EventList* events, SkArenaAlloc& alloc) {
+void GrAATriangulator::Event::apply(VertexList* mesh, const Comparator& c, EventList* events,
+                                    GrAATriangulator* triangulator) {
     if (!fEdge) {
         return;
     }
@@ -1579,16 +1558,16 @@
     if (!prevEdge || !nextEdge || !prevEdge->fEdge || !nextEdge->fEdge) {
         return;
     }
-    Vertex* dest = create_sorted_vertex(fPoint, fAlpha, mesh, prev, c, alloc);
+    Vertex* dest = triangulator->makeSortedVertex(fPoint, fAlpha, mesh, prev, c);
     dest->fSynthetic = true;
-    SSVertex* ssv = alloc.make<SSVertex>(dest);
+    SSVertex* ssv = triangulator->fAlloc.make<SSVertex>(dest);
     TESS_LOG("collapsing %g, %g (original edge %g -> %g) to %g (%g, %g) alpha %d\n",
              prev->fID, next->fID, fEdge->fEdge->fTop->fID, fEdge->fEdge->fBottom->fID, dest->fID,
              fPoint.fX, fPoint.fY, fAlpha);
     fEdge->fEdge = nullptr;
 
-    ss_connect(prev, dest, c, alloc);
-    ss_connect(next, dest, c, alloc);
+    triangulator->connectSSEdge(prev, dest, c);
+    triangulator->connectSSEdge(next, dest, c);
 
     prevEdge->fNext = nextEdge->fPrev = ssv;
     ssv->fPrev = prevEdge;
@@ -1603,17 +1582,17 @@
         nextEdge->fEvent->fEdge = nullptr;
     }
     if (prevEdge->fPrev == nextEdge->fNext) {
-        ss_connect(prevEdge->fPrev->fVertex, dest, c, alloc);
+        triangulator->connectSSEdge(prevEdge->fPrev->fVertex, dest, c);
         prevEdge->fEdge = nextEdge->fEdge = nullptr;
     } else {
-        compute_bisector(prevEdge->fEdge, nextEdge->fEdge, dest, alloc);
+        triangulator->computeBisector(prevEdge->fEdge, nextEdge->fEdge, dest);
         SkASSERT(prevEdge != fEdge && nextEdge != fEdge);
         if (dest->fPartner) {
-            create_event(prevEdge, events, alloc);
-            create_event(nextEdge, events, alloc);
+            triangulator->makeEvent(prevEdge, events);
+            triangulator->makeEvent(nextEdge, events);
         } else {
-            create_event(prevEdge, prevEdge->fPrev->fVertex, nextEdge, dest, events, c, alloc);
-            create_event(nextEdge, nextEdge->fNext->fVertex, prevEdge, dest, events, c, alloc);
+            triangulator->makeEvent(prevEdge, prevEdge->fPrev->fVertex, nextEdge, dest, events, c);
+            triangulator->makeEvent(nextEdge, nextEdge->fNext->fVertex, prevEdge, dest, events, c);
         }
     }
 }
@@ -1630,8 +1609,8 @@
 
 // This is a stripped-down version of tessellate() which computes edges which
 // join two filled regions, which represent overlap regions, and collapses them.
-static bool collapse_overlap_regions(VertexList* mesh, const Comparator& c, SkArenaAlloc& alloc,
-                                     EventComparator comp) {
+bool GrAATriangulator::collapseOverlapRegions(VertexList* mesh, const Comparator& c,
+                                              EventComparator comp) {
     TESS_LOG("\nfinding overlap regions\n");
     EdgeList activeEdges;
     EventList events(comp);
@@ -1666,17 +1645,17 @@
                 Vertex* nextVertex = e->fWinding < 0 ? e->fTop : e->fBottom;
                 SSVertex* ssPrev = ssVertices[prevVertex];
                 if (!ssPrev) {
-                    ssPrev = ssVertices[prevVertex] = alloc.make<SSVertex>(prevVertex);
+                    ssPrev = ssVertices[prevVertex] = fAlloc.make<SSVertex>(prevVertex);
                 }
                 SSVertex* ssNext = ssVertices[nextVertex];
                 if (!ssNext) {
-                    ssNext = ssVertices[nextVertex] = alloc.make<SSVertex>(nextVertex);
+                    ssNext = ssVertices[nextVertex] = fAlloc.make<SSVertex>(nextVertex);
                 }
-                SSEdge* ssEdge = alloc.make<SSEdge>(e, ssPrev, ssNext);
+                SSEdge* ssEdge = fAlloc.make<SSEdge>(e, ssPrev, ssNext);
                 ssEdges.push_back(ssEdge);
 //                SkASSERT(!ssPrev->fNext && !ssNext->fPrev);
                 ssPrev->fNext = ssNext->fPrev = ssEdge;
-                create_event(ssEdge, &events, alloc);
+                this->makeEvent(ssEdge, &events);
                 if (!isOuterBoundary) {
                     disconnect(e);
                 }
@@ -1700,13 +1679,13 @@
     while (events.size() > 0) {
         Event* event = events.top();
         events.pop();
-        event->apply(mesh, c, &events, alloc);
+        event->apply(mesh, c, &events, this);
     }
     TESS_LOG("skeleton after:\n");
     dump_skel(ssEdges);
     for (SSEdge* edge : ssEdges) {
         if (Edge* e = edge->fEdge) {
-            connect(edge->fPrev->fVertex, edge->fNext->fVertex, e->fType, c, alloc, 0);
+            this->makeConnectingEdge(edge->fPrev->fVertex, edge->fNext->fVertex, e->fType, c, 0);
         }
     }
     return complex;
@@ -1724,8 +1703,8 @@
 // find new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a
 // new antialiased mesh from those vertices.
 
-static void stroke_boundary(EdgeList* boundary, VertexList* innerMesh, VertexList* outerMesh,
-                            const Comparator& c, SkArenaAlloc& alloc) {
+void GrAATriangulator::strokeBoundary(EdgeList* boundary, VertexList* innerMesh,
+                                      VertexList* outerMesh, const Comparator& c) {
     TESS_LOG("\nstroking boundary\n");
     // A boundary with fewer than 3 edges is degenerate.
     if (!boundary->fHead || !boundary->fHead->fRight || !boundary->fHead->fRight->fRight) {
@@ -1816,10 +1795,10 @@
                          innerPoint1.fX, innerPoint1.fY, innerPoint2.fX, innerPoint2.fY);
                 TESS_LOG("outer (%g, %g), (%g, %g)\n",
                          outerPoint1.fX, outerPoint1.fY, outerPoint2.fX, outerPoint2.fY);
-                Vertex* innerVertex1 = alloc.make<Vertex>(innerPoint1, 255);
-                Vertex* innerVertex2 = alloc.make<Vertex>(innerPoint2, 255);
-                Vertex* outerVertex1 = alloc.make<Vertex>(outerPoint1, 0);
-                Vertex* outerVertex2 = alloc.make<Vertex>(outerPoint2, 0);
+                Vertex* innerVertex1 = fAlloc.make<Vertex>(innerPoint1, 255);
+                Vertex* innerVertex2 = fAlloc.make<Vertex>(innerPoint2, 255);
+                Vertex* outerVertex1 = fAlloc.make<Vertex>(outerPoint1, 0);
+                Vertex* outerVertex2 = fAlloc.make<Vertex>(outerPoint2, 0);
                 innerVertex1->fPartner = outerVertex1;
                 innerVertex2->fPartner = outerVertex2;
                 outerVertex1->fPartner = innerVertex1;
@@ -1837,8 +1816,8 @@
             } else {
                 TESS_LOG("inner (%g, %g), ", innerPoint.fX, innerPoint.fY);
                 TESS_LOG("outer (%g, %g)\n", outerPoint.fX, outerPoint.fY);
-                Vertex* innerVertex = alloc.make<Vertex>(innerPoint, 255);
-                Vertex* outerVertex = alloc.make<Vertex>(outerPoint, 0);
+                Vertex* innerVertex = fAlloc.make<Vertex>(innerPoint, 255);
+                Vertex* outerVertex = fAlloc.make<Vertex>(outerPoint, 0);
                 innerVertex->fPartner = outerVertex;
                 outerVertex->fPartner = innerVertex;
                 if (!inversion(innerVertices.fTail, innerVertex, prevEdge, c)) {
@@ -1867,25 +1846,26 @@
     // is always filled (1 + -2 = -1 for normal cases, 1 + 2 = 3 for thin features where the
     // interior inverts).
     // For total inversion cases, the shape has now reversed handedness, so invert the winding
-    // so it will be detected during collapse_overlap_regions().
+    // so it will be detected during collapseOverlapRegions().
     int innerWinding = innerInversion ? 2 : -2;
     int outerWinding = outerInversion ? -1 : 1;
     for (Vertex* v = innerVertices.fHead; v && v->fNext; v = v->fNext) {
-        connect(v, v->fNext, EdgeType::kInner, c, alloc, innerWinding);
+        this->makeConnectingEdge(v, v->fNext, EdgeType::kInner, c, innerWinding);
     }
-    connect(innerVertices.fTail, innerVertices.fHead, EdgeType::kInner, c, alloc, innerWinding);
+    this->makeConnectingEdge(innerVertices.fTail, innerVertices.fHead, EdgeType::kInner, c,
+                             innerWinding);
     for (Vertex* v = outerVertices.fHead; v && v->fNext; v = v->fNext) {
-        connect(v, v->fNext, EdgeType::kOuter, c, alloc, outerWinding);
+        this->makeConnectingEdge(v, v->fNext, EdgeType::kOuter, c, outerWinding);
     }
-    connect(outerVertices.fTail, outerVertices.fHead, EdgeType::kOuter, c, alloc, outerWinding);
+    this->makeConnectingEdge(outerVertices.fTail, outerVertices.fHead, EdgeType::kOuter, c,
+                             outerWinding);
     innerMesh->append(innerVertices);
     outerMesh->append(outerVertices);
 }
 
-static void extract_boundary(EdgeList* boundary, Edge* e, SkPathFillType fillType,
-                             SkArenaAlloc& alloc) {
+void GrAATriangulator::extractBoundary(EdgeList* boundary, Edge* e) {
     TESS_LOG("\nextracting boundary\n");
-    bool down = apply_fill_type(fillType, e->fWinding);
+    bool down = apply_fill_type(fPath.getFillType(), e->fWinding);
     Vertex* start = down ? e->fTop : e->fBottom;
     do {
         e->fWinding = down ? 1 : -1;
@@ -1919,16 +1899,15 @@
 
 // Stage 5b: Extract boundaries from mesh, simplify and stroke them into a new mesh.
 
-static void extract_boundaries(const VertexList& inMesh, VertexList* innerVertices,
-                               VertexList* outerVertices, SkPathFillType fillType,
-                               const Comparator& c, SkArenaAlloc& alloc) {
-    remove_non_boundary_edges(inMesh, fillType, alloc);
+void GrAATriangulator::extractBoundaries(const VertexList& inMesh, VertexList* innerVertices,
+                                         VertexList* outerVertices, const Comparator& c) {
+    this->removeNonBoundaryEdges(inMesh);
     for (Vertex* v = inMesh.fHead; v; v = v->fNext) {
         while (v->fFirstEdgeBelow) {
             EdgeList boundary;
-            extract_boundary(&boundary, v->fFirstEdgeBelow, fillType, alloc);
-            simplify_boundary(&boundary, c, alloc);
-            stroke_boundary(&boundary, innerVertices, outerVertices, c, alloc);
+            this->extractBoundary(&boundary, v->fFirstEdgeBelow);
+            this->simplifyBoundary(&boundary, c);
+            this->strokeBoundary(&boundary, innerVertices, outerVertices, c);
         }
     }
 }
@@ -1982,51 +1961,52 @@
         return nullptr;
     }
     TESS_LOG("\nsimplified mesh:\n");
-    dump_mesh(mesh);
-    if (fEmitCoverage) {
-        VertexList innerMesh;
-        extract_boundaries(mesh, &innerMesh, outerMesh, fPath.getFillType(), c, fAlloc);
-        SortMesh(&innerMesh, c);
-        SortMesh(outerMesh, c);
-        this->mergeCoincidentVertices(&innerMesh, c);
-        bool was_complex = this->mergeCoincidentVertices(outerMesh, c);
-        auto result = this->simplify(&innerMesh, c);
+    DUMP_MESH(mesh);
+    return this->tessellate(mesh, outerMesh, c);
+}
+
+Poly* GrAATriangulator::tessellate(const VertexList& mesh, VertexList* outerMesh,
+                                   const Comparator& c) {
+    VertexList innerMesh;
+    this->extractBoundaries(mesh, &innerMesh, outerMesh, c);
+    SortMesh(&innerMesh, c);
+    SortMesh(outerMesh, c);
+    this->mergeCoincidentVertices(&innerMesh, c);
+    bool was_complex = this->mergeCoincidentVertices(outerMesh, c);
+    auto result = this->simplify(&innerMesh, c);
+    SkASSERT(SimplifyResult::kAbort != result);
+    was_complex = (SimplifyResult::kFoundSelfIntersection == result) || was_complex;
+    result = this->simplify(outerMesh, c);
+    SkASSERT(SimplifyResult::kAbort != result);
+    was_complex = (SimplifyResult::kFoundSelfIntersection == result) || was_complex;
+    TESS_LOG("\ninner mesh before:\n");
+    DUMP_MESH(innerMesh);
+    TESS_LOG("\nouter mesh before:\n");
+    DUMP_MESH(*outerMesh);
+    EventComparator eventLT(EventComparator::Op::kLessThan);
+    EventComparator eventGT(EventComparator::Op::kGreaterThan);
+    was_complex = this->collapseOverlapRegions(&innerMesh, c, eventLT) || was_complex;
+    was_complex = this->collapseOverlapRegions(outerMesh, c, eventGT) || was_complex;
+    if (was_complex) {
+        TESS_LOG("found complex mesh; taking slow path\n");
+        VertexList aaMesh;
+        TESS_LOG("\ninner mesh after:\n");
+        DUMP_MESH(innerMesh);
+        TESS_LOG("\nouter mesh after:\n");
+        DUMP_MESH(*outerMesh);
+        this->connectPartners(outerMesh, c);
+        this->connectPartners(&innerMesh, c);
+        sorted_merge(&innerMesh, outerMesh, &aaMesh, c);
+        this->mergeCoincidentVertices(&aaMesh, c);
+        result = this->simplify(&aaMesh, c);
         SkASSERT(SimplifyResult::kAbort != result);
-        was_complex = (SimplifyResult::kFoundSelfIntersection == result) || was_complex;
-        result = this->simplify(outerMesh, c);
-        SkASSERT(SimplifyResult::kAbort != result);
-        was_complex = (SimplifyResult::kFoundSelfIntersection == result) || was_complex;
-        TESS_LOG("\ninner mesh before:\n");
-        dump_mesh(innerMesh);
-        TESS_LOG("\nouter mesh before:\n");
-        dump_mesh(*outerMesh);
-        EventComparator eventLT(EventComparator::Op::kLessThan);
-        EventComparator eventGT(EventComparator::Op::kGreaterThan);
-        was_complex = collapse_overlap_regions(&innerMesh, c, fAlloc, eventLT) || was_complex;
-        was_complex = collapse_overlap_regions(outerMesh, c, fAlloc, eventGT) || was_complex;
-        if (was_complex) {
-            TESS_LOG("found complex mesh; taking slow path\n");
-            VertexList aaMesh;
-            TESS_LOG("\ninner mesh after:\n");
-            dump_mesh(innerMesh);
-            TESS_LOG("\nouter mesh after:\n");
-            dump_mesh(*outerMesh);
-            connect_partners(outerMesh, c, fAlloc);
-            connect_partners(&innerMesh, c, fAlloc);
-            sorted_merge(&innerMesh, outerMesh, &aaMesh, c);
-            this->mergeCoincidentVertices(&aaMesh, c);
-            result = this->simplify(&aaMesh, c);
-            SkASSERT(SimplifyResult::kAbort != result);
-            TESS_LOG("combined and simplified mesh:\n");
-            dump_mesh(aaMesh);
-            outerMesh->fHead = outerMesh->fTail = nullptr;
-            return this->tessellate(aaMesh);
-        } else {
-            TESS_LOG("no complex polygons; taking fast path\n");
-            return this->tessellate(innerMesh);
-        }
+        TESS_LOG("combined and simplified mesh:\n");
+        DUMP_MESH(aaMesh);
+        outerMesh->fHead = outerMesh->fTail = nullptr;
+        return this->GrTriangulator::tessellate(aaMesh, outerMesh, c);
     } else {
-        return this->tessellate(mesh);
+        TESS_LOG("no complex polygons; taking fast path\n");
+        return this->GrTriangulator::tessellate(innerMesh, outerMesh, c);
     }
 }