GrQuadPerEdgeAA::Tessellator owns GrVertexWriter
Change-Id: I3c8bf48dda061aa9d318b9f81f22608fdd68fcbd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255786
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp
index 94142a6..e213283 100644
--- a/src/gpu/ops/GrFillRectOp.cpp
+++ b/src/gpu/ops/GrFillRectOp.cpp
@@ -216,17 +216,15 @@
return;
}
- // vertices pointer advances through vdata based on Tessellate's return value
- void* vertices = vdata;
- GrQuadPerEdgeAA::Tessellator tessellator(vertexSpec);
+ GrQuadPerEdgeAA::Tessellator tessellator(vertexSpec, (char*) vdata);
auto iter = fQuads.iterator();
while(iter.next()) {
// All entries should have local coords, or no entries should have local coords,
// matching !helper.isTrivial() (which is more conservative than helper.usesLocalCoords)
SkASSERT(iter.isLocalValid() != fHelper.isTrivial());
auto info = iter.metadata();
- vertices = tessellator.append(vertices, iter.deviceQuad(), iter.localQuad(),
- info.fColor, kEmptyDomain, info.fAAFlags);
+ tessellator.append(iter.deviceQuad(), iter.localQuad(),
+ info.fColor, kEmptyDomain, info.fAAFlags);
}
sk_sp<const GrBuffer> indexBuffer;
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index ac2961b..70a8607 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -8,7 +8,6 @@
#include "src/gpu/ops/GrQuadPerEdgeAA.h"
#include "include/private/SkVx.h"
-#include "src/gpu/GrVertexWriter.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/geometry/GrQuadUtils.h"
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
@@ -285,12 +284,16 @@
return write_quad_generic;
}
-Tessellator::Tessellator(const VertexSpec& spec)
+Tessellator::Tessellator(const VertexSpec& spec, char* vertices)
: fVertexSpec(spec)
+ , fVertexWriter{vertices}
, fWriteProc(Tessellator::GetWriteQuadProc(spec)) {}
-void* Tessellator::append(void* vertices, const GrQuad& deviceQuad, const GrQuad& localQuad,
- const SkPMColor4f& color, const SkRect& uvDomain, GrQuadAAFlags aaFlags) {
+void Tessellator::append(const GrQuad& deviceQuad, const GrQuad& localQuad,
+ const SkPMColor4f& color, const SkRect& uvDomain, GrQuadAAFlags aaFlags) {
+ // We allow Tessellator to be created with a null vertices pointer for convenience, but it is
+ // assumed it will never actually be used in those cases.
+ SkASSERT(fVertexWriter.fPtr);
SkASSERT(deviceQuad.quadType() <= fVertexSpec.deviceQuadType());
SkASSERT(!fVertexSpec.hasLocalCoords() || localQuad.quadType() <= fVertexSpec.localQuadType());
@@ -298,7 +301,6 @@
static const float kZeroCoverage[4] = {0.f, 0.f, 0.f, 0.f};
static const SkRect kIgnoredDomain = SkRect::MakeEmpty();
- GrVertexWriter vb{vertices};
if (fVertexSpec.usesCoverageAA()) {
SkASSERT(fVertexSpec.coverageMode() == CoverageMode::kWithColor ||
fVertexSpec.coverageMode() == CoverageMode::kWithPosition);
@@ -313,11 +315,11 @@
if (aaFlags == GrQuadAAFlags::kNone) {
// Have to write the coverage AA vertex structure, but there's no math to be done for a
// non-aa quad batched into a coverage AA op.
- fWriteProc(&vb, fVertexSpec, deviceQuad, localQuad, kFullCoverage, color,
+ fWriteProc(&fVertexWriter, fVertexSpec, deviceQuad, localQuad, kFullCoverage, color,
geomDomain, uvDomain);
// Since we pass the same corners in, the outer vertex structure will have 0 area and
// the coverage interpolation from 1 to 0 will not be visible.
- fWriteProc(&vb, fVertexSpec, deviceQuad, localQuad, kZeroCoverage, color,
+ fWriteProc(&fVertexWriter, fVertexSpec, deviceQuad, localQuad, kZeroCoverage, color,
geomDomain, uvDomain);
} else {
// Reset the tessellation helper to match the current geometry
@@ -340,23 +342,21 @@
// Write inner vertices first
float coverage[4];
fAAHelper.inset(edgeDistances, &aaDeviceQuad, &aaLocalQuad).store(coverage);
- fWriteProc(&vb, fVertexSpec, aaDeviceQuad, aaLocalQuad, coverage, color,
+ fWriteProc(&fVertexWriter, fVertexSpec, aaDeviceQuad, aaLocalQuad, coverage, color,
geomDomain, uvDomain);
// Then outer vertices, which use 0.f for their coverage
fAAHelper.outset(edgeDistances, &aaDeviceQuad, &aaLocalQuad);
- fWriteProc(&vb, fVertexSpec, aaDeviceQuad, aaLocalQuad, kZeroCoverage, color,
+ fWriteProc(&fVertexWriter, fVertexSpec, aaDeviceQuad, aaLocalQuad, kZeroCoverage, color,
geomDomain, uvDomain);
}
} else {
// No outsetting needed, just write a single quad with full coverage
SkASSERT(fVertexSpec.coverageMode() == CoverageMode::kNone &&
!fVertexSpec.requiresGeometryDomain());
- fWriteProc(&vb, fVertexSpec, deviceQuad, localQuad, kFullCoverage, color,
+ fWriteProc(&fVertexWriter, fVertexSpec, deviceQuad, localQuad, kFullCoverage, color,
kIgnoredDomain, uvDomain);
}
-
- return vb.fPtr;
}
sk_sp<const GrBuffer> GetIndexBuffer(GrMeshDrawOp::Target* target,
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.h b/src/gpu/ops/GrQuadPerEdgeAA.h
index 1ba92ca..2b99c68 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.h
+++ b/src/gpu/ops/GrQuadPerEdgeAA.h
@@ -14,6 +14,7 @@
#include "src/gpu/GrColor.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrSamplerState.h"
+#include "src/gpu/GrVertexWriter.h"
#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/geometry/GrQuadUtils.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
@@ -134,14 +135,16 @@
// MakeProcessor and/or MakeTexturedProcessor.
class Tessellator {
public:
- explicit Tessellator(const VertexSpec& spec);
+ explicit Tessellator(const VertexSpec& spec, char* vertices);
- // Calculates (as needed) inset and outset geometry for anti-aliasing, and writes all
- // necessary position and vertex attributes required by this Tessellator's VertexSpec.
- // After appending, this will return the pointer to the next vertex in the VBO.
- void* append(void* vertices, const GrQuad& deviceQuad, const GrQuad& localQuad,
+ // Calculates (as needed) inset and outset geometry for anti-aliasing, and appends all
+ // necessary position and vertex attributes required by this Tessellator's VertexSpec into
+ // the 'vertices' the Tessellator was called with.
+ void append(const GrQuad& deviceQuad, const GrQuad& localQuad,
const SkPMColor4f& color, const SkRect& uvDomain, GrQuadAAFlags aaFlags);
+ SkDEBUGCODE(char* vertices() const { return (char*) fVertexWriter.fPtr; })
+
private:
// VertexSpec defines many unique ways to write vertex attributes, which can be handled
// generically by branching per-quad based on the VertexSpec. However, there are several
@@ -155,6 +158,7 @@
GrQuadUtils::TessellationHelper fAAHelper;
VertexSpec fVertexSpec;
+ GrVertexWriter fVertexWriter;
WriteQuadProc fWriteProc;
};
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 2dd9d5f..0b687dd 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -584,36 +584,30 @@
sk_sp<const GrBuffer> indexBuffer) {
int totQuadsSeen = 0;
SkDEBUGCODE(int totVerticesSeen = 0;)
- char* dst = pVertexData;
- const size_t vertexSize = desc->fVertexSpec.vertexSize();
+ SkDEBUGCODE(const size_t vertexSize = desc->fVertexSpec.vertexSize());
- GrQuadPerEdgeAA::Tessellator tessellator(desc->fVertexSpec);
+ GrQuadPerEdgeAA::Tessellator tessellator(desc->fVertexSpec, pVertexData);
int meshIndex = 0;
for (const auto& op : ChainRange<TextureOp>(texOp)) {
auto iter = op.fQuads.iterator();
for (unsigned p = 0; p < op.fProxyCnt; ++p) {
GrTextureProxy* proxy = op.fViewCountPairs[p].fProxyView.asTextureProxy();
- int quadCnt = op.fViewCountPairs[p].fQuadCnt;
-
- const int meshVertexCnt = quadCnt * desc->fVertexSpec.verticesPerQuad();
-
+ const int quadCnt = op.fViewCountPairs[p].fQuadCnt;
+ SkDEBUGCODE(int meshVertexCnt = quadCnt * desc->fVertexSpec.verticesPerQuad());
SkASSERT(meshIndex < desc->fNumProxies);
- if (dst) {
- int i = 0;
- void* v = dst;
- while(i < quadCnt && iter.next()) {
+ if (pVertexData) {
+ for (int i = 0; i < quadCnt && iter.next(); ++i) {
SkASSERT(iter.isLocalValid());
const ColorDomainAndAA& info = iter.metadata();
- v = tessellator.append(v, iter.deviceQuad(), iter.localQuad(),
- info.fColor, info.fDomainRect, info.aaFlags());
- i++;
+ tessellator.append(iter.deviceQuad(), iter.localQuad(),
+ info.fColor, info.fDomainRect, info.aaFlags());
}
desc->setMeshProxy(meshIndex, proxy);
- SkASSERT(totVerticesSeen * vertexSize == (size_t)(dst - pVertexData));
- dst += vertexSize * meshVertexCnt;
+ SkASSERT((totVerticesSeen + meshVertexCnt) * vertexSize
+ == (size_t)(tessellator.vertices() - pVertexData));
}
if (meshes) {
@@ -631,10 +625,11 @@
// If quad counts per proxy were calculated correctly, the entire iterator
// should have been consumed.
- SkASSERT(!dst || !iter.next());
+ SkASSERT(!pVertexData || !iter.next());
}
- SkASSERT(!dst || (desc->totalSizeInBytes() == (size_t)(dst - pVertexData)));
+ SkASSERT(!pVertexData ||
+ (desc->totalSizeInBytes() == (size_t)(tessellator.vertices() - pVertexData)));
SkASSERT(meshIndex == desc->fNumProxies);
SkASSERT(totQuadsSeen == desc->fNumTotalQuads);
SkASSERT(totVerticesSeen == desc->totalNumVertices());