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>
This commit is contained in:
parent
fe13ca3e67
commit
189c98042f
@ -421,8 +421,8 @@ private:
|
||||
GrQuad quad = GrQuad::MakeFromSkQuad(fCorners, SkMatrix::I());
|
||||
|
||||
float vertices[56]; // 2 quads, with x, y, coverage, and geometry domain (7 floats x 8 vert)
|
||||
GrQuadPerEdgeAA::Tessellator tessellator(kSpec);
|
||||
tessellator.append(vertices, quad, GrQuad(SkRect::MakeEmpty()), {1.f, 1.f, 1.f, 1.f},
|
||||
GrQuadPerEdgeAA::Tessellator tessellator(kSpec, (char*) vertices);
|
||||
tessellator.append(quad, GrQuad(SkRect::MakeEmpty()), {1.f, 1.f, 1.f, 1.f},
|
||||
SkRect::MakeEmpty(), flags);
|
||||
|
||||
// The first quad in vertices is the inset, then the outset, but they
|
||||
|
@ -216,17 +216,15 @@ private:
|
||||
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;
|
||||
|
@ -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 @@ Tessellator::WriteQuadProc Tessellator::GetWriteQuadProc(const VertexSpec& spec)
|
||||
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 @@ void* Tessellator::append(void* vertices, const GrQuad& deviceQuad, const GrQuad
|
||||
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 @@ void* Tessellator::append(void* vertices, const GrQuad& deviceQuad, const GrQuad
|
||||
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 @@ void* Tessellator::append(void* vertices, const GrQuad& deviceQuad, const GrQuad
|
||||
// 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,
|
||||
|
@ -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 @@ namespace GrQuadPerEdgeAA {
|
||||
// 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 @@ namespace GrQuadPerEdgeAA {
|
||||
|
||||
GrQuadUtils::TessellationHelper fAAHelper;
|
||||
VertexSpec fVertexSpec;
|
||||
GrVertexWriter fVertexWriter;
|
||||
WriteQuadProc fWriteProc;
|
||||
};
|
||||
|
||||
|
@ -584,36 +584,30 @@ private:
|
||||
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 @@ private:
|
||||
|
||||
// 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());
|
||||
|
Loading…
Reference in New Issue
Block a user