Start disentangling tessellation from pipeline creation in GrTextureOp
The idea/dream here is to be able to (optionally) tessellate in onPrePrepareDraws and then just copy the prePrepared data into the vertex buffer.
Change -Id: I899eebce36dc9516bfc4b0fce5e657458167c772
Change-Id: I899eebce36dc9516bfc4b0fce5e657458167c772
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/248804
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index ad060dd..27bd00e 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -477,32 +477,10 @@
return coverage;
}
-enum class CoverageMode {
- kNone,
- kWithPosition,
- kWithColor
-};
-
-static CoverageMode get_mode_for_spec(const GrQuadPerEdgeAA::VertexSpec& spec) {
- if (spec.usesCoverageAA()) {
- if (spec.compatibleWithCoverageAsAlpha() && spec.hasVertexColors() &&
- !spec.requiresGeometryDomain()) {
- // Using a geometric domain acts as a second source of coverage and folding the original
- // coverage into color makes it impossible to apply the color's alpha to the geometric
- // domain's coverage when the original shape is clipped.
- return CoverageMode::kWithColor;
- } else {
- return CoverageMode::kWithPosition;
- }
- } else {
- return CoverageMode::kNone;
- }
-}
-
// Writes four vertices in triangle strip order, including the additional data for local
// coordinates, geometry + texture domains, color, and coverage as needed to satisfy the vertex spec
static void write_quad(GrVertexWriter* vb, const GrQuadPerEdgeAA::VertexSpec& spec,
- CoverageMode mode, const V4f& coverage, SkPMColor4f color4f,
+ GrQuadPerEdgeAA::CoverageMode mode, const V4f& coverage, SkPMColor4f color4f,
const SkRect& geomDomain, const SkRect& texDomain, const Vertices& quad) {
static constexpr auto If = GrVertexWriter::If<float>;
@@ -511,13 +489,14 @@
// perspective and coverage mode.
vb->write(quad.fX[i], quad.fY[i],
If(spec.deviceQuadType() == GrQuad::Type::kPerspective, quad.fW[i]),
- If(mode == CoverageMode::kWithPosition, coverage[i]));
+ If(mode == GrQuadPerEdgeAA::CoverageMode::kWithPosition, coverage[i]));
// save color
if (spec.hasVertexColors()) {
bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kHalf;
vb->write(GrVertexColor(
- color4f * (mode == CoverageMode::kWithColor ? coverage[i] : 1.f), wide));
+ color4f * (mode == GrQuadPerEdgeAA::CoverageMode::kWithColor ? coverage[i] : 1.f),
+ wide));
}
// save local position
@@ -584,7 +563,7 @@
SkASSERT(deviceQuad.quadType() <= spec.deviceQuadType());
SkASSERT(!spec.hasLocalCoords() || localQuad.quadType() <= spec.localQuadType());
- CoverageMode mode = get_mode_for_spec(spec);
+ GrQuadPerEdgeAA::CoverageMode mode = spec.coverageMode();
// Load position data into V4fs (always x, y, and load w to avoid branching down the road)
Vertices outer;
@@ -685,6 +664,63 @@
return fHasLocalCoords ? (this->localQuadType() == GrQuad::Type::kPerspective ? 3 : 2) : 0;
}
+CoverageMode VertexSpec::coverageMode() const {
+ if (this->usesCoverageAA()) {
+ if (this->compatibleWithCoverageAsAlpha() && this->hasVertexColors() &&
+ !this->requiresGeometryDomain()) {
+ // Using a geometric domain acts as a second source of coverage and folding
+ // the original coverage into color makes it impossible to apply the color's
+ // alpha to the geometric domain's coverage when the original shape is clipped.
+ return CoverageMode::kWithColor;
+ } else {
+ return CoverageMode::kWithPosition;
+ }
+ } else {
+ return CoverageMode::kNone;
+ }
+}
+
+// This needs to stay in sync w/ QuadPerEdgeAAGeometryProcessor::initializeAttrs
+size_t VertexSpec::vertexSize() const {
+ bool needsPerspective = (this->deviceDimensionality() == 3);
+ CoverageMode coverageMode = this->coverageMode();
+
+ size_t count = 0;
+
+ if (coverageMode == CoverageMode::kWithPosition) {
+ if (needsPerspective) {
+ count += GrVertexAttribTypeSize(kFloat4_GrVertexAttribType);
+ } else {
+ count += GrVertexAttribTypeSize(kFloat2_GrVertexAttribType) +
+ GrVertexAttribTypeSize(kFloat_GrVertexAttribType);
+ }
+ } else {
+ if (needsPerspective) {
+ count += GrVertexAttribTypeSize(kFloat3_GrVertexAttribType);
+ } else {
+ count += GrVertexAttribTypeSize(kFloat2_GrVertexAttribType);
+ }
+ }
+
+ if (this->requiresGeometryDomain()) {
+ count += GrVertexAttribTypeSize(kFloat4_GrVertexAttribType);
+ }
+
+ count += this->localDimensionality() * GrVertexAttribTypeSize(kFloat_GrVertexAttribType);
+
+ if (ColorType::kByte == this->colorType()) {
+ count += GrVertexAttribTypeSize(kUByte4_norm_GrVertexAttribType);
+ } else if (ColorType::kHalf == this->colorType()) {
+ count += GrVertexAttribTypeSize(kHalf4_GrVertexAttribType);
+ }
+
+ if (this->hasDomain()) {
+ count += GrVertexAttribTypeSize(kFloat4_GrVertexAttribType);
+ }
+
+ return count;
+}
+
////////////////// Geometry Processor Implementation
class QuadPerEdgeAAGeometryProcessor : public GrGeometryProcessor {
@@ -918,9 +954,10 @@
this->setTextureSamplerCnt(1);
}
+ // This needs to stay in sync w/ VertexSpec::vertexSize
void initializeAttrs(const VertexSpec& spec) {
fNeedsPerspective = spec.deviceDimensionality() == 3;
- fCoverageMode = get_mode_for_spec(spec);
+ fCoverageMode = spec.coverageMode();
if (fCoverageMode == CoverageMode::kWithPosition) {
if (fNeedsPerspective) {