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;
}