Pull out sksl emission logic for per-edge aa from GrTextureOp
Bug: skia:
Change-Id: Iba068276e618d7d962b0b4ab059541f3b431539b
Reviewed-on: https://skia-review.googlesource.com/c/165528
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index 0eca1e6..ecacd60 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -7,6 +7,11 @@
#include "GrQuadPerEdgeAA.h"
#include "GrQuad.h"
+#include "glsl/GrGLSLColorSpaceXformHelper.h"
+#include "glsl/GrGLSLPrimitiveProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLVarying.h"
+#include "glsl/GrGLSLVertexGeoBuilder.h"
#include "SkNx.h"
namespace {
@@ -367,3 +372,165 @@
vb += vertexSize;
}
}
+
+GrQuadPerEdgeAA::GPAttributes::GPAttributes(int posDim, int localDim, bool hasColor, GrAAType aa,
+ Domain domain) {
+ SkASSERT(posDim == 2 || posDim == 3);
+ SkASSERT(localDim == 0 || localDim == 2 || localDim == 3);
+
+ if (posDim == 3) {
+ fPositions = {"position", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
+ } else {
+ fPositions = {"position", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
+ }
+
+ if (localDim == 3) {
+ fLocalCoords = {"localCoord", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
+ } else if (localDim == 2) {
+ fLocalCoords = {"localCoord", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
+ } // else localDim == 0 and attribute remains uninitialized
+
+ if (hasColor) {
+ fColors = {"color", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
+ }
+
+ if (domain == Domain::kYes) {
+ fDomain = {"domain", kFloat4_GrVertexAttribType, kFloat4_GrSLType};
+ }
+
+ if (aa == GrAAType::kCoverage) {
+ fAAEdges[0] = {"aaEdge0", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
+ fAAEdges[1] = {"aaEdge1", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
+ fAAEdges[2] = {"aaEdge2", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
+ fAAEdges[3] = {"aaEdge3", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
+ }
+}
+
+bool GrQuadPerEdgeAA::GPAttributes::needsPerspectiveInterpolation() const {
+ // This only needs to check the position; local position having perspective does not change
+ // how the varyings are interpolated
+ return fPositions.cpuType() == kFloat3_GrVertexAttribType;
+}
+
+int GrQuadPerEdgeAA::GPAttributes::vertexAttributeCount() const {
+ // Always has position, hence 1+
+ return (1 + this->hasLocalCoords() + this->hasVertexColors() + this->hasDomain() +
+ 4 * this->usesCoverageAA());
+}
+
+uint32_t GrQuadPerEdgeAA::GPAttributes::getKey() const {
+ // aa, color, domain are single bit flags
+ uint32_t x = this->usesCoverageAA() ? 0 : 1;
+ x |= this->hasVertexColors() ? 0 : 2;
+ x |= this->hasDomain() ? 0 : 4;
+ // regular position has two options as well
+ x |= kFloat3_GrVertexAttribType == fPositions.cpuType() ? 0 : 8;
+ // local coords require 2 bits (3 choices), 00 for none, 01 for 2d, 10 for 3d
+ if (this->hasLocalCoords()) {
+ x |= kFloat3_GrVertexAttribType == fLocalCoords.cpuType() ? 16 : 32;
+ }
+ return x;
+}
+
+void GrQuadPerEdgeAA::GPAttributes::emitColor(GrGLSLPrimitiveProcessor::EmitArgs& args,
+ GrGLSLColorSpaceXformHelper* csXformHelper,
+ const char* colorVarName) const {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+
+ if (!fColors.isInitialized()) {
+ return;
+ }
+
+ if (csXformHelper == nullptr || csXformHelper->isNoop()) {
+ args.fVaryingHandler->addPassThroughAttribute(
+ fColors, args.fOutputColor, Interpolation::kCanBeFlat);
+ } else {
+ GrGLSLVarying varying(kHalf4_GrSLType);
+ args.fVaryingHandler->addVarying(colorVarName, &varying);
+ args.fVertBuilder->codeAppendf("half4 %s = ", colorVarName);
+ args.fVertBuilder->appendColorGamutXform(fColors.name(), csXformHelper);
+ args.fVertBuilder->codeAppend(";");
+ args.fVertBuilder->codeAppendf("%s = half4(%s.rgb * %s.a, %s.a);",
+ varying.vsOut(), colorVarName, colorVarName, colorVarName);
+ args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
+ }
+}
+
+void GrQuadPerEdgeAA::GPAttributes::emitExplicitLocalCoords(
+ GrGLSLPrimitiveProcessor::EmitArgs& args, const char* localCoordName,
+ const char* domainName) const {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+ if (!this->hasLocalCoords()) {
+ return;
+ }
+
+ args.fFragBuilder->codeAppendf("float2 %s;", localCoordName);
+ bool localHasPerspective = fLocalCoords.cpuType() == kFloat3_GrVertexAttribType;
+ if (localHasPerspective) {
+ // Can't do a pass through since we need to perform perspective division
+ GrGLSLVarying v(fLocalCoords.gpuType());
+ args.fVaryingHandler->addVarying(fLocalCoords.name(), &v);
+ args.fVertBuilder->codeAppendf("%s = %s;", v.vsOut(), fLocalCoords.name());
+ args.fFragBuilder->codeAppendf("%s = %s.xy / %s.z;", localCoordName, v.fsIn(), v.fsIn());
+ } else {
+ args.fVaryingHandler->addPassThroughAttribute(fLocalCoords, localCoordName);
+ }
+
+ // Clamp the now 2D localCoordName variable by the domain if it is provided
+ if (this->hasDomain()) {
+ args.fFragBuilder->codeAppendf("float4 %s;", domainName);
+ args.fVaryingHandler->addPassThroughAttribute(fDomain, domainName,
+ Interpolation::kCanBeFlat);
+ args.fFragBuilder->codeAppendf("%s = clamp(%s, %s.xy, %s.zw);",
+ localCoordName, localCoordName, domainName, domainName);
+ }
+}
+
+void GrQuadPerEdgeAA::GPAttributes::emitCoverage(GrGLSLPrimitiveProcessor::EmitArgs& args,
+ const char* edgeDistName) const {
+ if (this->usesCoverageAA()) {
+ bool mulByFragCoordW = false;
+ GrGLSLVarying aaDistVarying(kFloat4_GrSLType,
+ GrGLSLVarying::Scope::kVertToFrag);
+ args.fVaryingHandler->addVarying(edgeDistName, &aaDistVarying);
+
+ if (kFloat3_GrVertexAttribType == fPositions.cpuType()) {
+ // The distance from edge equation e to homogeneous point p=sk_Position
+ // is e.x*p.x/p.w + e.y*p.y/p.w + e.z. However, we want screen space
+ // interpolation of this distance. We can do this by multiplying the
+ // varying in the VS by p.w and then multiplying by sk_FragCoord.w in
+ // the FS. So we output e.x*p.x + e.y*p.y + e.z * p.w
+ args.fVertBuilder->codeAppendf(
+ R"(%s = float4(dot(%s, %s), dot(%s, %s),
+ dot(%s, %s), dot(%s, %s));)",
+ aaDistVarying.vsOut(), fAAEdges[0].name(), fPositions.name(),
+ fAAEdges[1].name(), fPositions.name(), fAAEdges[2].name(), fPositions.name(),
+ fAAEdges[3].name(), fPositions.name());
+ mulByFragCoordW = true;
+ } else {
+ args.fVertBuilder->codeAppendf(
+ R"(%s = float4(dot(%s.xy, %s.xy) + %s.z,
+ dot(%s.xy, %s.xy) + %s.z,
+ dot(%s.xy, %s.xy) + %s.z,
+ dot(%s.xy, %s.xy) + %s.z);)",
+ aaDistVarying.vsOut(),
+ fAAEdges[0].name(), fPositions.name(), fAAEdges[0].name(),
+ fAAEdges[1].name(), fPositions.name(), fAAEdges[1].name(),
+ fAAEdges[2].name(), fPositions.name(), fAAEdges[2].name(),
+ fAAEdges[3].name(), fPositions.name(), fAAEdges[3].name());
+ }
+
+ args.fFragBuilder->codeAppendf(
+ "float min%s = min(min(%s.x, %s.y), min(%s.z, %s.w));",
+ edgeDistName, aaDistVarying.fsIn(), aaDistVarying.fsIn(), aaDistVarying.fsIn(),
+ aaDistVarying.fsIn());
+ if (mulByFragCoordW) {
+ args.fFragBuilder->codeAppendf("min%s *= sk_FragCoord.w;", edgeDistName);
+ }
+ args.fFragBuilder->codeAppendf("%s = float4(saturate(min%s));",
+ args.fOutputCoverage, edgeDistName);
+ } else {
+ // Set coverage to 1
+ args.fFragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage);
+ }
+}
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.h b/src/gpu/ops/GrQuadPerEdgeAA.h
index 643a757..9a70850 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.h
+++ b/src/gpu/ops/GrQuadPerEdgeAA.h
@@ -9,11 +9,14 @@
#define GrQuadPerEdgeAA_DEFINED
#include "GrColor.h"
+#include "GrPrimitiveProcessor.h"
#include "GrSamplerState.h"
#include "GrTypesPriv.h"
+#include "glsl/GrGLSLPrimitiveProcessor.h"
#include "SkPoint.h"
#include "SkPoint3.h"
+class GrGLSLColorSpaceXformHelper;
class GrPerspQuad;
class GrQuadPerEdgeAA {
@@ -57,6 +60,76 @@
char fData[kVertexSize];
};
+ // Utility class that manages the attribute state necessary to render a particular batch of
+ // quads. It is similar to a geometry processor but is meant to be included in a has-a
+ // relationship by specialized GP's that provide further functionality on top of the per-edge AA
+ // coverage.
+ //
+ // For performance reasons, this uses fixed names for the attribute variables; since it defines
+ // the majority of attributes a GP will likely need, this shouldn't be too limiting.
+ //
+ // In terms of responsibilities, the actual geometry processor must still call emitTransforms(),
+ // using the localCoords() attribute as the 4th argument; it must set the transform data helper
+ // to use the identity matrix; it must manage the color space transform for the quad's paint
+ // color; it should include getKey() in the geometry processor's key builder; and it should
+ // return these managed attributes from its onVertexAttribute() function.
+ class GPAttributes {
+ public:
+ using Attribute = GrPrimitiveProcessor::Attribute;
+
+ GPAttributes(int posDim, int localDim, bool hasColor, GrAAType aa, Domain domain);
+
+ const Attribute& positions() const { return fPositions; }
+ const Attribute& colors() const { return fColors; }
+ const Attribute& localCoords() const { return fLocalCoords; }
+ const Attribute& domain() const { return fDomain; }
+ const Attribute& edges(int i) const { return fAAEdges[i]; }
+
+ bool hasVertexColors() const { return fColors.isInitialized(); }
+
+ bool usesCoverageAA() const { return fAAEdges[0].isInitialized(); }
+
+ bool hasLocalCoords() const { return fLocalCoords.isInitialized(); }
+
+ bool hasDomain() const { return fDomain.isInitialized(); }
+
+ bool needsPerspectiveInterpolation() const;
+
+ int vertexAttributeCount() const;
+
+ uint32_t getKey() const;
+
+ // Functions to be called at appropriate times in a processor's onEmitCode() block. These
+ // are separated into discrete pieces so that they can be interleaved with the rest of the
+ // processor's shader code as needed. The functions take char* arguments for the names of
+ // variables the emitted code must declare, so that the calling GP can ensure there's no
+ // naming conflicts with their own code.
+
+ void emitColor(GrGLSLPrimitiveProcessor::EmitArgs& args,
+ GrGLSLColorSpaceXformHelper* colorSpaceXformHelper,
+ const char* colorVarName) const;
+
+ // localCoordName will be declared as a float2, with any domain applied after any
+ // perspective division is performed.
+ //
+ // Note: this should only be used if the local coordinates need to be passed separately
+ // from the standard coord transform process that is used by FPs.
+ // FIXME: This can go in two directions from here, if GrTextureOp stops needing per-quad
+ // domains it can be removed and GrTextureOp rewritten to use coord transforms. Or
+ // emitTransform() in the primitive builder can be updated to have a notion of domain for
+ // local coords, and all domain-needing code (blurs, filters, etc.) can switch to that magic
+ void emitExplicitLocalCoords(GrGLSLPrimitiveProcessor::EmitArgs& args,
+ const char* localCoordName, const char* domainVarName) const;
+
+ void emitCoverage(GrGLSLPrimitiveProcessor::EmitArgs& args, const char* edgeDistName) const;
+ private:
+ Attribute fPositions; // named "position" in SkSL
+ Attribute fColors; // named "color" in SkSL
+ Attribute fLocalCoords; // named "localCoord" in SkSL
+ Attribute fDomain; // named "domain" in SkSL
+ Attribute fAAEdges[4]; // named "aaEdgeX" for X = 0,1,2,3
+ };
+
// Tessellate the given quad specification into the vertices buffer. If the specific vertex
// type does not use color, local positions, domain, etc. then the passed in values used for
// that field will be ignored.
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index dbe7de8..0bf4d27 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -31,10 +31,8 @@
#include "SkRectPriv.h"
#include "SkTo.h"
#include "glsl/GrGLSLColorSpaceXformHelper.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLGeometryProcessor.h"
#include "glsl/GrGLSLVarying.h"
-#include "glsl/GrGLSLVertexGeoBuilder.h"
namespace {
@@ -52,11 +50,11 @@
const GrSamplerState::Filter filter,
sk_sp<GrColorSpaceXform> textureColorSpaceXform,
sk_sp<GrColorSpaceXform> paintColorSpaceXform,
- bool coverageAA, bool perspective,
- Domain domain, const GrShaderCaps& caps) {
+ int positionDim, GrAAType aa, Domain domain,
+ const GrShaderCaps& caps) {
return sk_sp<TextureGeometryProcessor>(new TextureGeometryProcessor(
textureType, textureConfig, filter, std::move(textureColorSpaceXform),
- std::move(paintColorSpaceXform), coverageAA, perspective, domain, caps));
+ std::move(paintColorSpaceXform), positionDim, aa, domain, caps));
}
const char* name() const override { return "TextureGeometryProcessor"; }
@@ -64,10 +62,7 @@
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
b->add32(GrColorSpaceXform::XformKey(fTextureColorSpaceXform.get()));
b->add32(GrColorSpaceXform::XformKey(fPaintColorSpaceXform.get()));
- uint32_t x = this->usesCoverageEdgeAA() ? 0 : 1;
- x |= kFloat3_GrVertexAttribType == fPositions.cpuType() ? 0 : 2;
- x |= fDomain.isInitialized() ? 4 : 0;
- b->add32(x);
+ b->add32(fAttrs.getKey());
}
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override {
@@ -84,94 +79,33 @@
private:
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
- using Interpolation = GrGLSLVaryingHandler::Interpolation;
const auto& textureGP = args.fGP.cast<TextureGeometryProcessor>();
fTextureColorSpaceXformHelper.emitCode(
args.fUniformHandler, textureGP.fTextureColorSpaceXform.get());
fPaintColorSpaceXformHelper.emitCode(
args.fUniformHandler, textureGP.fPaintColorSpaceXform.get(),
kVertex_GrShaderFlag);
- if (kFloat2_GrVertexAttribType == textureGP.fPositions.cpuType()) {
+ if (!textureGP.fAttrs.needsPerspectiveInterpolation()) {
args.fVaryingHandler->setNoPerspective();
}
args.fVaryingHandler->emitAttributes(textureGP);
- gpArgs->fPositionVar = textureGP.fPositions.asShaderVar();
+ gpArgs->fPositionVar = textureGP.fAttrs.positions().asShaderVar();
this->emitTransforms(args.fVertBuilder,
args.fVaryingHandler,
args.fUniformHandler,
- textureGP.fTextureCoords.asShaderVar(),
+ textureGP.fAttrs.localCoords().asShaderVar(),
args.fFPCoordTransformHandler);
- if (fPaintColorSpaceXformHelper.isNoop()) {
- args.fVaryingHandler->addPassThroughAttribute(
- textureGP.fColors, args.fOutputColor, Interpolation::kCanBeFlat);
- } else {
- GrGLSLVarying varying(kHalf4_GrSLType);
- args.fVaryingHandler->addVarying("color", &varying);
- args.fVertBuilder->codeAppend("half4 color = ");
- args.fVertBuilder->appendColorGamutXform(textureGP.fColors.name(),
- &fPaintColorSpaceXformHelper);
- args.fVertBuilder->codeAppend(";");
- args.fVertBuilder->codeAppendf("%s = half4(color.rgb * color.a, color.a);",
- varying.vsOut());
- args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
- }
- args.fFragBuilder->codeAppend("float2 texCoord;");
- args.fVaryingHandler->addPassThroughAttribute(textureGP.fTextureCoords, "texCoord");
- if (textureGP.fDomain.isInitialized()) {
- args.fFragBuilder->codeAppend("float4 domain;");
- args.fVaryingHandler->addPassThroughAttribute(
- textureGP.fDomain, "domain",
- GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
- args.fFragBuilder->codeAppend(
- "texCoord = clamp(texCoord, domain.xy, domain.zw);");
- }
+ textureGP.fAttrs.emitColor(args, &fPaintColorSpaceXformHelper, "paintColor");
+ textureGP.fAttrs.emitExplicitLocalCoords(args, "texCoord", "domain");
+
args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor);
args.fFragBuilder->appendTextureLookupAndModulate(
args.fOutputColor, args.fTexSamplers[0], "texCoord", kFloat2_GrSLType,
&fTextureColorSpaceXformHelper);
args.fFragBuilder->codeAppend(";");
- if (textureGP.usesCoverageEdgeAA()) {
- bool mulByFragCoordW = false;
- GrGLSLVarying aaDistVarying(kFloat4_GrSLType,
- GrGLSLVarying::Scope::kVertToFrag);
- if (kFloat3_GrVertexAttribType == textureGP.fPositions.cpuType()) {
- args.fVaryingHandler->addVarying("aaDists", &aaDistVarying);
- // The distance from edge equation e to homogeneous point p=sk_Position
- // is e.x*p.x/p.w + e.y*p.y/p.w + e.z. However, we want screen space
- // interpolation of this distance. We can do this by multiplying the
- // varying in the VS by p.w and then multiplying by sk_FragCoord.w in
- // the FS. So we output e.x*p.x + e.y*p.y + e.z * p.w
- args.fVertBuilder->codeAppendf(
- R"(%s = float4(dot(aaEdge0, %s), dot(aaEdge1, %s),
- dot(aaEdge2, %s), dot(aaEdge3, %s));)",
- aaDistVarying.vsOut(), textureGP.fPositions.name(),
- textureGP.fPositions.name(), textureGP.fPositions.name(),
- textureGP.fPositions.name());
- mulByFragCoordW = true;
- } else {
- args.fVaryingHandler->addVarying("aaDists", &aaDistVarying);
- args.fVertBuilder->codeAppendf(
- R"(%s = float4(dot(aaEdge0.xy, %s.xy) + aaEdge0.z,
- dot(aaEdge1.xy, %s.xy) + aaEdge1.z,
- dot(aaEdge2.xy, %s.xy) + aaEdge2.z,
- dot(aaEdge3.xy, %s.xy) + aaEdge3.z);)",
- aaDistVarying.vsOut(), textureGP.fPositions.name(),
- textureGP.fPositions.name(), textureGP.fPositions.name(),
- textureGP.fPositions.name());
- }
- args.fFragBuilder->codeAppendf(
- "float mindist = min(min(%s.x, %s.y), min(%s.z, %s.w));",
- aaDistVarying.fsIn(), aaDistVarying.fsIn(), aaDistVarying.fsIn(),
- aaDistVarying.fsIn());
- if (mulByFragCoordW) {
- args.fFragBuilder->codeAppend("mindist *= sk_FragCoord.w;");
- }
- args.fFragBuilder->codeAppendf("%s = float4(saturate(mindist));",
- args.fOutputCoverage);
- } else {
- args.fFragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage);
- }
+
+ textureGP.fAttrs.emitCoverage(args, "aaDist");
}
GrGLSLColorSpaceXformHelper fTextureColorSpaceXformHelper;
GrGLSLColorSpaceXformHelper fPaintColorSpaceXformHelper;
@@ -179,55 +113,30 @@
return new GLSLProcessor;
}
- bool usesCoverageEdgeAA() const { return SkToBool(fAAEdges[0].isInitialized()); }
-
private:
TextureGeometryProcessor(GrTextureType textureType, GrPixelConfig textureConfig,
GrSamplerState::Filter filter,
sk_sp<GrColorSpaceXform> textureColorSpaceXform,
- sk_sp<GrColorSpaceXform> paintColorSpaceXform, bool coverageAA,
- bool perspective, Domain domain, const GrShaderCaps& caps)
+ sk_sp<GrColorSpaceXform> paintColorSpaceXform, int positionDim,
+ GrAAType aa, Domain domain, const GrShaderCaps& caps)
: INHERITED(kTextureGeometryProcessor_ClassID)
+ , fAttrs(positionDim, /* src dim */ 2, /* vertex color */ true, aa, domain)
, fTextureColorSpaceXform(std::move(textureColorSpaceXform))
, fPaintColorSpaceXform(std::move(paintColorSpaceXform))
, fSampler(textureType, textureConfig, filter) {
this->setTextureSamplerCnt(1);
-
- if (perspective) {
- fPositions = {"position", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
- } else {
- fPositions = {"position", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
- }
- fColors = {"color", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
- fTextureCoords = {"textureCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
- int vertexAttributeCnt = 3;
-
- if (domain == Domain::kYes) {
- fDomain = {"domain", kFloat4_GrVertexAttribType, kFloat4_GrSLType};
- ++vertexAttributeCnt;
- }
- if (coverageAA) {
- fAAEdges[0] = {"aaEdge0", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
- fAAEdges[1] = {"aaEdge1", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
- fAAEdges[2] = {"aaEdge2", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
- fAAEdges[3] = {"aaEdge3", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
- vertexAttributeCnt += 4;
- }
- this->setVertexAttributeCnt(vertexAttributeCnt);
+ this->setVertexAttributeCnt(fAttrs.vertexAttributeCount());
}
const Attribute& onVertexAttribute(int i) const override {
- return IthInitializedAttribute(i, fPositions, fColors, fTextureCoords, fDomain, fAAEdges[0],
- fAAEdges[1], fAAEdges[2], fAAEdges[3]);
+ return IthInitializedAttribute(i, fAttrs.positions(), fAttrs.colors(), fAttrs.localCoords(),
+ fAttrs.domain(), fAttrs.edges(0), fAttrs.edges(1),
+ fAttrs.edges(2), fAttrs.edges(3));
}
const TextureSampler& onTextureSampler(int) const override { return fSampler; }
- Attribute fPositions;
- Attribute fColors;
- Attribute fTextureCoords;
- Attribute fDomain;
- Attribute fAAEdges[4];
+ GrQuadPerEdgeAA::GPAttributes fAttrs;
sk_sp<GrColorSpaceXform> fTextureColorSpaceXform;
sk_sp<GrColorSpaceXform> fPaintColorSpaceXform;
TextureSampler fSampler;
@@ -548,10 +457,9 @@
}
}
- bool coverageAA = GrAAType::kCoverage == aaType;
sk_sp<GrGeometryProcessor> gp = TextureGeometryProcessor::Make(
textureType, config, this->filter(), std::move(fTextureColorSpaceXform),
- std::move(fPaintColorSpaceXform), coverageAA, hasPerspective, domain,
+ std::move(fPaintColorSpaceXform), hasPerspective ? 3 : 2, aaType, domain,
*target->caps().shaderCaps());
GrPipeline::InitArgs args;
args.fProxy = target->proxy();
@@ -597,9 +505,9 @@
};
#undef TESS_FN_AND_VERTEX_SIZE
int tessFnIdx = 0;
- tessFnIdx |= coverageAA ? 0x1 : 0x0;
- tessFnIdx |= (domain == Domain::kYes) ? 0x2 : 0x0;
- tessFnIdx |= hasPerspective ? 0x4 : 0x0;
+ tessFnIdx |= (GrAAType::kCoverage == aaType) ? 0x1 : 0x0;
+ tessFnIdx |= (domain == Domain::kYes) ? 0x2 : 0x0;
+ tessFnIdx |= hasPerspective ? 0x4 : 0x0;
size_t vertexSize = kTessFnsAndVertexSizes[tessFnIdx].fVertexSize;
SkASSERT(vertexSize == gp->debugOnly_vertexStride());