GrTriangulator cleanups

Replace "pathToTriangles" with "pathToPolys, polysToTriangles". This
will allow the tessellator to do pathToPolys in onPrePrepare and
polysToTriangles in onPrepare.

Don't make countPoints and polysToTriangles virtual. This is a step
toward moving the outer mesh of GrAATriangulator back out of the
class, which seems to match the style better.

Bug: skia:10419
Change-Id: Id6d22dcc2da0af84b9cb46fb36ead4c2e30d5c32
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/355176
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrAATriangulator.cpp b/src/gpu/GrAATriangulator.cpp
index 402f58b..9a49d19 100644
--- a/src/gpu/GrAATriangulator.cpp
+++ b/src/gpu/GrAATriangulator.cpp
@@ -7,6 +7,7 @@
 
 #include "src/gpu/GrAATriangulator.h"
 
+#include "src/gpu/GrEagerVertexAllocator.h"
 #include <queue>
 #include <vector>
 #include <unordered_map>
@@ -651,19 +652,28 @@
     }
 }
 
-int64_t GrAATriangulator::countPoints(Poly* polys) const {
-    int64_t count = this->countPointsImpl(polys, SkPathFillType::kWinding);
+int GrAATriangulator::polysToAATriangles(Poly* polys, GrEagerVertexAllocator* vertexAllocator) {
+    int64_t count64 = CountPoints(polys, SkPathFillType::kWinding);
     // Count the points from the outer mesh.
     for (Vertex* v = fOuterMesh.fHead; v; v = v->fNext) {
         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
-            count += TRIANGULATOR_WIREFRAME ? 12 : 6;
+            count64 += TRIANGULATOR_WIREFRAME ? 12 : 6;
         }
     }
-    return count;
-}
+    if (0 == count64 || count64 > SK_MaxS32) {
+        return 0;
+    }
+    int count = count64;
 
-void* GrAATriangulator::polysToTriangles(Poly* polys, void* data) {
-    data = this->polysToTrianglesImpl(polys, data, SkPathFillType::kWinding);
+    size_t vertexStride = sizeof(SkPoint) + sizeof(float);
+    void* verts = vertexAllocator->lock(vertexStride, count);
+    if (!verts) {
+        SkDebugf("Could not allocate vertices\n");
+        return 0;
+    }
+
+    TESS_LOG("emitting %d verts\n", count);
+    void* end = this->polysToTriangles(polys, verts, SkPathFillType::kWinding);
     // Emit the triangles from the outer mesh.
     for (Vertex* v = fOuterMesh.fHead; v; v = v->fNext) {
         for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
@@ -671,9 +681,14 @@
             Vertex* v1 = e->fBottom;
             Vertex* v2 = e->fBottom->fPartner;
             Vertex* v3 = e->fTop->fPartner;
-            data = this->emitTriangle(v0, v1, v2, 0/*winding*/, data);
-            data = this->emitTriangle(v0, v2, v3, 0/*winding*/, data);
+            end = this->emitTriangle(v0, v1, v2, 0/*winding*/, end);
+            end = this->emitTriangle(v0, v2, v3, 0/*winding*/, end);
         }
     }
-    return data;
+
+    int actualCount = static_cast<int>((static_cast<uint8_t*>(end) - static_cast<uint8_t*>(verts))
+                                       / vertexStride);
+    SkASSERT(actualCount <= count);
+    vertexAllocator->unlock(actualCount);
+    return actualCount;
 }
diff --git a/src/gpu/GrAATriangulator.h b/src/gpu/GrAATriangulator.h
index 7718557..4d240d0 100644
--- a/src/gpu/GrAATriangulator.h
+++ b/src/gpu/GrAATriangulator.h
@@ -11,14 +11,15 @@
 #include "src/gpu/GrTriangulator.h"
 
 // Triangulates the given path in device space with a mesh of alpha ramps for antialiasing.
-class GrAATriangulator : public GrTriangulator {
+class GrAATriangulator : private GrTriangulator {
 public:
-    static int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
-                               GrEagerVertexAllocator* vertexAllocator) {
+    static int PathToAATriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
+                                 GrEagerVertexAllocator* vertexAllocator) {
         GrAATriangulator aaTriangulator(path);
         aaTriangulator.fRoundVerticesToQuarterPixel = true;
         aaTriangulator.fEmitCoverage = true;
-        return  aaTriangulator.pathToTriangles(tolerance, clipBounds, vertexAllocator);
+        Poly* polys = aaTriangulator.pathToPolys(tolerance, clipBounds);
+        return aaTriangulator.polysToAATriangles(polys, vertexAllocator);
     }
 
     // Structs used by GrAATriangulator internals.
@@ -62,8 +63,7 @@
 
     // Run steps 3-6 above on the new mesh, and produce antialiased triangles.
     Poly* tessellate(const VertexList& mesh, const Comparator&) override;
-    int64_t countPoints(Poly* polys) const override;
-    void* polysToTriangles(Poly* polys, void* data) override;
+    int polysToAATriangles(Poly*, GrEagerVertexAllocator*);
 
     // Additional helpers and driver functions.
     void makeEvent(SSEdge*, EventList* events);
diff --git a/src/gpu/GrTriangulator.cpp b/src/gpu/GrTriangulator.cpp
index f08379b..6a016f4 100644
--- a/src/gpu/GrTriangulator.cpp
+++ b/src/gpu/GrTriangulator.cpp
@@ -1391,8 +1391,7 @@
 }
 
 // Stage 6: Triangulate the monotone polygons into a vertex buffer.
-void* GrTriangulator::polysToTrianglesImpl(Poly* polys, void* data,
-                                           SkPathFillType overrideFillType) {
+void* GrTriangulator::polysToTriangles(Poly* polys, void* data, SkPathFillType overrideFillType) {
     for (Poly* poly = polys; poly; poly = poly->fNext) {
         if (apply_fill_type(overrideFillType, poly)) {
             data = this->emitPoly(poly, data);
@@ -1401,16 +1400,6 @@
     return data;
 }
 
-Poly* GrTriangulator::pathToPolys(float tolerance, const SkRect& clipBounds, int contourCnt) {
-    if (SkPathFillType_IsInverse(fPath.getFillType())) {
-        contourCnt++;
-    }
-    std::unique_ptr<VertexList[]> contours(new VertexList[contourCnt]);
-
-    this->pathToContours(tolerance, clipBounds, contours.get());
-    return this->contoursToPolys(contours.get(), contourCnt);
-}
-
 static int get_contour_count(const SkPath& path, SkScalar tolerance) {
     // We could theoretically be more aggressive about not counting empty contours, but we need to
     // actually match the exact number of contour linked lists the tessellator will create later on.
@@ -1445,7 +1434,23 @@
     return contourCnt;
 }
 
-int64_t GrTriangulator::countPointsImpl(Poly* polys, SkPathFillType overrideFillType) const {
+Poly* GrTriangulator::pathToPolys(float tolerance, const SkRect& clipBounds) {
+    int contourCnt = get_contour_count(fPath, tolerance);
+    if (contourCnt <= 0) {
+        fIsLinear = true;
+        return nullptr;
+    }
+
+    if (SkPathFillType_IsInverse(fPath.getFillType())) {
+        contourCnt++;
+    }
+    std::unique_ptr<VertexList[]> contours(new VertexList[contourCnt]);
+
+    this->pathToContours(tolerance, clipBounds, contours.get());
+    return this->contoursToPolys(contours.get(), contourCnt);
+}
+
+int64_t GrTriangulator::CountPoints(Poly* polys, SkPathFillType overrideFillType) {
     int64_t count = 0;
     for (Poly* poly = polys; poly; poly = poly->fNext) {
         if (apply_fill_type(overrideFillType, poly) && poly->fCount >= 3) {
@@ -1457,15 +1462,8 @@
 
 // Stage 6: Triangulate the monotone polygons into a vertex buffer.
 
-int GrTriangulator::pathToTriangles(float tolerance, const SkRect& clipBounds,
-                                    GrEagerVertexAllocator* vertexAllocator) {
-    int contourCnt = get_contour_count(fPath, tolerance);
-    if (contourCnt <= 0) {
-        fIsLinear = true;
-        return 0;
-    }
-    Poly* polys = this->pathToPolys(tolerance, clipBounds, contourCnt);
-    int64_t count64 = this->countPoints(polys);
+int GrTriangulator::polysToTriangles(Poly* polys, GrEagerVertexAllocator* vertexAllocator) {
+    int64_t count64 = CountPoints(polys, fPath.getFillType());
     if (0 == count64 || count64 > SK_MaxS32) {
         return 0;
     }
@@ -1482,7 +1480,7 @@
     }
 
     TESS_LOG("emitting %d verts\n", count);
-    void* end = this->polysToTriangles(polys, verts);
+    void* end = this->polysToTriangles(polys, verts, fPath.getFillType());
 
     int actualCount = static_cast<int>((static_cast<uint8_t*>(end) - static_cast<uint8_t*>(verts))
                                        / vertexStride);
@@ -1493,14 +1491,9 @@
 
 int GrTriangulator::PathToVertices(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
                                    WindingVertex** verts) {
-    int contourCnt = get_contour_count(path, tolerance);
-    if (contourCnt <= 0) {
-        *verts = nullptr;
-        return 0;
-    }
     GrTriangulator triangulator(path);
-    Poly* polys = triangulator.pathToPolys(tolerance, clipBounds, contourCnt);
-    int64_t count64 = triangulator.countPoints(polys);
+    Poly* polys = triangulator.pathToPolys(tolerance, clipBounds);
+    int64_t count64 = CountPoints(polys, path.getFillType());
     if (0 == count64 || count64 > SK_MaxS32) {
         *verts = nullptr;
         return 0;
diff --git a/src/gpu/GrTriangulator.h b/src/gpu/GrTriangulator.h
index d4f4a9f..5475c60 100644
--- a/src/gpu/GrTriangulator.h
+++ b/src/gpu/GrTriangulator.h
@@ -28,7 +28,8 @@
     static int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
                                GrEagerVertexAllocator* vertexAllocator, bool* isLinear) {
         GrTriangulator triangulator(path);
-        int count = triangulator.pathToTriangles(tolerance, clipBounds, vertexAllocator);
+        Poly* polys = triangulator.pathToPolys(tolerance, clipBounds);
+        int count = triangulator.polysToTriangles(polys, vertexAllocator);
         *isLinear = triangulator.fIsLinear;
         return count;
     }
@@ -75,7 +76,8 @@
         GrTriangulator triangulator(path);
         triangulator.fCullCollinearVertices = false;
         triangulator.fBreadcrumbTriangles = breadcrumbTriangles;
-        int count = triangulator.pathToTriangles(0, SkRect::MakeEmpty(), vertexAllocator);
+        Poly* polys = triangulator.pathToPolys(0, SkRect::MakeEmpty());
+        int count = triangulator.polysToTriangles(polys, vertexAllocator);
         *isLinear = triangulator.fIsLinear;
         return count;
     }
@@ -86,7 +88,8 @@
         GrTriangulator triangulator(path);
         triangulator.fCullCollinearVertices = false;
         triangulator.fDisallowSelfIntersection = true;
-        int count = triangulator.pathToTriangles(0, SkRect::MakeEmpty(), vertexAllocator);
+        Poly* polys = triangulator.pathToPolys(0, SkRect::MakeEmpty());
+        int count = triangulator.polysToTriangles(polys, vertexAllocator);
         *isLinear = triangulator.fIsLinear;
         return count;
     }
@@ -150,12 +153,7 @@
     virtual Poly* tessellate(const VertexList& vertices, const Comparator&);
 
     // 6) Triangulate the monotone polygons directly into a vertex buffer:
-    virtual int64_t countPoints(Poly* polys) const {
-        return this->countPointsImpl(polys, fPath.getFillType());
-    }
-    virtual void* polysToTriangles(Poly* polys, void* data) {
-        return this->polysToTrianglesImpl(polys, data, fPath.getFillType());
-    }
+    void* polysToTriangles(Poly* polys, void* data, SkPathFillType overrideFillType);
 
     // The vertex sorting in step (3) is a merge sort, since it plays well with the linked list
     // of vertices (and the necessity of inserting new vertices on intersection).
@@ -237,10 +235,9 @@
     bool mergeCoincidentVertices(VertexList* mesh, const Comparator&);
     void buildEdges(VertexList* contours, int contourCnt, VertexList* mesh, const Comparator&);
     Poly* contoursToPolys(VertexList* contours, int contourCnt);
-    Poly* pathToPolys(float tolerance, const SkRect& clipBounds, int contourCnt);
-    int64_t countPointsImpl(Poly* polys, SkPathFillType overrideFillType) const;
-    void* polysToTrianglesImpl(Poly* polys, void* data, SkPathFillType overrideFillType);
-    int pathToTriangles(float tolerance, const SkRect& clipBounds, GrEagerVertexAllocator*);
+    Poly* pathToPolys(float tolerance, const SkRect& clipBounds);
+    static int64_t CountPoints(Poly* polys, SkPathFillType overrideFillType);
+    int polysToTriangles(Poly*, GrEagerVertexAllocator*);
 
     constexpr static int kArenaChunkSize = 16 * 1024;
     SkArenaAlloc fAlloc{kArenaChunkSize};
diff --git a/src/gpu/ops/GrTriangulatingPathRenderer.cpp b/src/gpu/ops/GrTriangulatingPathRenderer.cpp
index 9f9667f..2a4e86f 100644
--- a/src/gpu/ops/GrTriangulatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTriangulatingPathRenderer.cpp
@@ -440,7 +440,7 @@
         sk_sp<const GrBuffer> vertexBuffer;
         int firstVertex;
         GrEagerDynamicVertexAllocator allocator(target, &vertexBuffer, &firstVertex);
-        int vertexCount = GrAATriangulator::PathToTriangles(path, tol, clipBounds, &allocator);
+        int vertexCount = GrAATriangulator::PathToAATriangles(path, tol, clipBounds, &allocator);
         if (vertexCount == 0) {
             return;
         }