Add a per-triangle vertex advance to GrMiddleOutPolygonTriangulator
This will allow us to write the triangles with a 4-vertex stride and
combine them with cubic instances for indirect draw mode.
Change-Id: Ibe1b16ac093c2fd09a604f37e527c1c24369a64b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/289936
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h b/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h
index 258e175..482f2e3 100644
--- a/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h
+++ b/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h
@@ -40,10 +40,12 @@
// recursion, we manipulate an O(log N) stack to determine the correct middle-out triangulation.
class GrMiddleOutPolygonTriangulator {
public:
- GrMiddleOutPolygonTriangulator(SkPoint* vertexData, int maxVertices)
- : fTriangleData(reinterpret_cast<std::array<SkPoint, 3>*>(vertexData)) {
+ GrMiddleOutPolygonTriangulator(SkPoint* vertexData, int perTriangleVertexAdvance,
+ int maxPushVertexCalls)
+ : fVertexData(vertexData)
+ , fPerTriangleVertexAdvance(perTriangleVertexAdvance) {
// Determine the deepest our stack can ever go.
- int maxStackDepth = SkNextLog2(maxVertices) + 1;
+ int maxStackDepth = SkNextLog2(maxPushVertexCalls) + 1;
if (maxStackDepth > kStackPreallocCount) {
fVertexStack.reset(maxStackDepth);
}
@@ -75,17 +77,15 @@
// (This is a stack-based implementation of the recursive example method from the class
// comment.)
while (vertexIdxDelta == fTop->fVertexIdxDelta) {
- *fTriangleData++ = {fTop[-1].fPoint, fTop->fPoint, pt};
+ this->popTopTriangle(pt);
vertexIdxDelta *= 2;
- this->popTop();
}
- this->pushTop();
- *fTop = {vertexIdxDelta, pt};
+ this->pushVertex(vertexIdxDelta, pt);
}
int close() {
- if (fTop == &fVertexStack[0]) { // The stack only contains one point (the starting point).
- return fTotalClosedVertexCount;
+ if (fTop == fVertexStack) { // The stack only contains one point (the starting point).
+ return fTotalClosedTriangleCount;
}
// We will count vertices by walking the stack backwards.
int finalVertexCount = 1;
@@ -94,24 +94,23 @@
// vertexIdxDeltas match.
const SkPoint& p0 = fVertexStack[0].fPoint;
SkASSERT(fTop->fPoint != p0); // We should have detected and handled this case earlier.
- while (fTop > &fVertexStack[1]) {
- *fTriangleData++ = {fTop[-1].fPoint, fTop->fPoint, p0};
+ while (fTop - 1 > fVertexStack) {
finalVertexCount += fTop->fVertexIdxDelta;
- this->popTop();
+ this->popTopTriangle(p0);
}
+ SkASSERT(fTop == fVertexStack + 1);
finalVertexCount += fTop->fVertexIdxDelta;
- this->popTop();
- SkASSERT(fTop == &fVertexStack[0]);
SkASSERT(fVertexStack[0].fVertexIdxDelta == 0);
+ fTop = fVertexStack;
int numTriangles = finalVertexCount - 2;
SkASSERT(numTriangles >= 0);
- fTotalClosedVertexCount += numTriangles * 3;
- return fTotalClosedVertexCount;
+ fTotalClosedTriangleCount += numTriangles;
+ return fTotalClosedTriangleCount;
}
void closeAndMove(const SkPoint& startPt) {
this->close();
- SkASSERT(fTop == &fVertexStack[0]); // The stack should only contain a starting point now.
+ SkASSERT(fTop == fVertexStack); // The stack should only contain a starting point now.
fTop->fPoint = startPt; // Modify the starting point.
SkASSERT(fTop->fVertexIdxDelta == 0); // Ensure we are in the initial stack state.
}
@@ -129,23 +128,30 @@
SkPoint fPoint;
};
- void pushTop() {
+ void pushVertex(int vertexIdxDelta, const SkPoint& point) {
++fTop;
// We should never push deeper than fStackAllocCount.
- SkASSERT(fTop < &fVertexStack[fStackAllocCount]);
+ SkASSERT(fTop < fVertexStack + fStackAllocCount);
+ fTop->fVertexIdxDelta = vertexIdxDelta;
+ fTop->fPoint = point;
}
- void popTop() {
- SkASSERT(fTop > &fVertexStack[0]); // We should never pop the starting point.
+ void popTopTriangle(const SkPoint& lastPt) {
+ SkASSERT(fTop > fVertexStack); // We should never pop the starting point.
--fTop;
+ fVertexData[0] = fTop[0].fPoint;
+ fVertexData[1] = fTop[1].fPoint;
+ fVertexData[2] = lastPt;
+ fVertexData += fPerTriangleVertexAdvance;
}
constexpr static int kStackPreallocCount = 32;
SkAutoSTMalloc<kStackPreallocCount, StackVertex> fVertexStack;
SkDEBUGCODE(int fStackAllocCount;)
StackVertex* fTop;
- std::array<SkPoint, 3>* fTriangleData;
- int fTotalClosedVertexCount = 0;
+ SkPoint* fVertexData;
+ int fPerTriangleVertexAdvance;
+ int fTotalClosedTriangleCount = 0;
};
#endif
diff --git a/src/gpu/tessellate/GrTessellatePathOp.cpp b/src/gpu/tessellate/GrTessellatePathOp.cpp
index 7e0950a..cf79daa 100644
--- a/src/gpu/tessellate/GrTessellatePathOp.cpp
+++ b/src/gpu/tessellate/GrTessellatePathOp.cpp
@@ -122,7 +122,8 @@
return;
}
- GrMiddleOutPolygonTriangulator middleOut(vertexData, maxVertices);
+ constexpr static int kNumVerticesPerTriangle = 3;
+ GrMiddleOutPolygonTriangulator middleOut(vertexData, kNumVerticesPerTriangle, maxVertices);
int localCurveCount = 0;
for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) {
switch (verb) {
@@ -147,7 +148,7 @@
SkUNREACHABLE;
}
}
- fTriangleVertexCount = middleOut.close();
+ fTriangleVertexCount = middleOut.close() * kNumVerticesPerTriangle;
*numCountedCurves = localCurveCount;
vertexAlloc.unlock(fTriangleVertexCount);