Reland "Centralize geometry processor vertex shader transform code"
This is a reland of 0426947243e1d6b470830c4d3b1c5704ed1f23e1
Original change's description:
> Centralize geometry processor vertex shader transform code
>
> GrGLSLGeometryProcessors no longer have to call emitTransforms() in
> their onEmitCode() function. Instead, the GpArgs struct allows them to
> set a GrShaderVar that holds the computed or explicitly provided local
> coordinates in the vertex shader.
>
> The base GrGLSLGeometryProcessor now automatically uses that to collect
> all of the transforms that can then be lifted out of FPs to the vertex
> shader, and base their computation on the GP provided local coordinate.
>
> As part of this, there is no more built-in magic concatenation of a
> local matrix / inverse view matrix to these coordinate transforms. GP
> implementations that relied on this now manage their own uniform for this
> matrix and compute the local coordinate before assigning to GpArgs.
>
> The base GrGLSLGeometryProcessor is updated to provide helpers for this
> pattern.
>
> Bug: skia:10396
> Change-Id: I56afb3fff4b806f6015ab13626ac1afde9ef5c2b
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297027
> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
Bug: skia:10396
Change-Id: If1347bcacb7c405a66f9d4c5b0059e9d735b3f9a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/298062
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index 4f93238..94ba184 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -57,6 +57,7 @@
public:
GLSLProcessor()
: fViewMatrix(SkMatrix::InvalidMatrix())
+ , fLocalMatrix(SkMatrix::InvalidMatrix())
, fColor(SK_PMColor4fILLEGAL)
, fCoverage(0xff) {}
@@ -111,14 +112,14 @@
&fViewMatrixUniform);
// emit transforms using either explicit local coords or positions
- const auto& coordsAttr = gp.fInLocalCoords.isInitialized() ? gp.fInLocalCoords
- : gp.fInPosition;
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- coordsAttr.asShaderVar(),
- gp.localMatrix(),
- args.fFPCoordTransformHandler);
+ if (gp.fInLocalCoords.isInitialized()) {
+ SkASSERT(gp.localMatrix().isIdentity());
+ gpArgs->fLocalCoordVar = gp.fInLocalCoords.asShaderVar();
+ } else if (gp.fLocalCoordsWillBeRead) {
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs,
+ gp.fInPosition.asShaderVar(), gp.localMatrix(),
+ &fLocalMatrixUniform);
+ }
// Setup coverage as pass through
if (gp.hasVertexCoverage() && !tweakAlpha) {
@@ -144,8 +145,12 @@
const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
uint32_t key = def.fFlags;
key |= (def.coverage() == 0xff) ? 0x80 : 0;
- key |= (def.localCoordsWillBeRead() && def.localMatrix().hasPerspective()) ? 0x100 : 0;
- key |= ComputePosKey(def.viewMatrix()) << 20;
+ key |= def.localCoordsWillBeRead() ? 0x100 : 0;
+
+ bool usesLocalMatrix = def.localCoordsWillBeRead() &&
+ !def.fInLocalCoords.isInitialized();
+ key = AddMatrixKeys(key, def.viewMatrix(),
+ usesLocalMatrix ? def.localMatrix() : SkMatrix::I());
b->add32(key);
}
@@ -154,12 +159,9 @@
const CoordTransformRange& transformRange) override {
const DefaultGeoProc& dgp = gp.cast<DefaultGeoProc>();
- if (!dgp.viewMatrix().isIdentity() &&
- !SkMatrixPriv::CheapEqual(fViewMatrix, dgp.viewMatrix()))
- {
- fViewMatrix = dgp.viewMatrix();
- pdman.setSkMatrix(fViewMatrixUniform, fViewMatrix);
- }
+ this->setTransform(pdman, fViewMatrixUniform, dgp.viewMatrix(), &fViewMatrix);
+ this->setTransform(pdman, fLocalMatrixUniform, dgp.localMatrix(), &fLocalMatrix);
+ this->setTransformDataHelper(pdman, transformRange);
if (!dgp.hasVertexColor() && dgp.color() != fColor) {
pdman.set4fv(fColorUniform, 1, dgp.color().vec());
@@ -170,14 +172,15 @@
pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.coverage()));
fCoverage = dgp.coverage();
}
- this->setTransformDataHelper(dgp.fLocalMatrix, pdman, transformRange);
}
private:
SkMatrix fViewMatrix;
+ SkMatrix fLocalMatrix;
SkPMColor4f fColor;
uint8_t fCoverage;
UniformHandle fViewMatrixUniform;
+ UniformHandle fLocalMatrixUniform;
UniformHandle fColorUniform;
UniformHandle fCoverageUniform;
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index 40d4c93..75af35a 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -56,12 +56,14 @@
constexpr Attribute(const char* name,
GrVertexAttribType cpuType,
GrSLType gpuType)
- : fName(name), fCPUType(cpuType), fGPUType(gpuType) {}
+ : fName(name), fCPUType(cpuType), fGPUType(gpuType) {
+ SkASSERT(name && gpuType != kVoid_GrSLType);
+ }
constexpr Attribute(const Attribute&) = default;
Attribute& operator=(const Attribute&) = default;
- constexpr bool isInitialized() const { return SkToBool(fName); }
+ constexpr bool isInitialized() const { return fGPUType != kVoid_GrSLType; }
constexpr const char* name() const { return fName; }
constexpr GrVertexAttribType cpuType() const { return fCPUType; }
@@ -77,7 +79,7 @@
private:
const char* fName = nullptr;
GrVertexAttribType fCPUType = kFloat_GrVertexAttribType;
- GrSLType fGPUType = kFloat_GrSLType;
+ GrSLType fGPUType = kVoid_GrSLType;
};
class Iter {
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index d4c1d8b..e5c99c0 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -103,6 +103,10 @@
public:
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override;
+ static void GenKey(const GrCCPathProcessor& cc, GrProcessorKeyBuilder* b) {
+ b->add32(AddMatrixKeys((uint32_t) cc.fCoverageMode, SkMatrix::I(), cc.fLocalMatrix));
+ }
+
private:
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
const CoordTransformRange& transformRange) override {
@@ -110,14 +114,21 @@
pdman.set2f(fAtlasAdjustUniform,
1.0f / proc.fAtlasDimensions.fWidth,
1.0f / proc.fAtlasDimensions.fHeight);
- this->setTransformDataHelper(proc.fLocalMatrix, pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUni, proc.fLocalMatrix, &fLocalMatrix);
}
GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform;
+ GrGLSLUniformHandler::UniformHandle fLocalMatrixUni;
+ SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix();
typedef GrGLSLGeometryProcessor INHERITED;
};
+void GrCCPathProcessor::getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const {
+ GrCCPathProcessor::Impl::GenKey(*this, b);
+}
+
GrGLSLPrimitiveProcessor* GrCCPathProcessor::createGLSLInstance(const GrShaderCaps&) const {
return new Impl();
}
@@ -218,8 +229,8 @@
}
gpArgs->fPositionVar.set(kFloat2_GrSLType, "octocoord");
- this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, proc.fLocalMatrix,
- args.fFPCoordTransformHandler);
+ this->writeLocalCoord(v, args.fUniformHandler, gpArgs, gpArgs->fPositionVar, proc.fLocalMatrix,
+ &fLocalMatrixUni);
// Fragment shader.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
diff --git a/src/gpu/ccpr/GrCCPathProcessor.h b/src/gpu/ccpr/GrCCPathProcessor.h
index cb5f227..789ac2e 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.h
+++ b/src/gpu/ccpr/GrCCPathProcessor.h
@@ -64,9 +64,8 @@
const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I());
const char* name() const override { return "GrCCPathProcessor"; }
- void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
- b->add32((uint32_t)fCoverageMode);
- }
+ void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override;
+
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
void drawPaths(GrOpFlushState*, const GrPipeline&, const GrSurfaceProxy& atlasProxy,
diff --git a/src/gpu/ccpr/GrCCStroker.cpp b/src/gpu/ccpr/GrCCStroker.cpp
index 8f0a7ee..bb09fe4 100644
--- a/src/gpu/ccpr/GrCCStroker.cpp
+++ b/src/gpu/ccpr/GrCCStroker.cpp
@@ -103,7 +103,6 @@
void LinearStrokeProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
- GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
varyingHandler->emitAttributes(args.fGP.cast<LinearStrokeProcessor>());
@@ -137,8 +136,7 @@
edgeDistances.vsOut(), edgeDistances.vsOut(), edgeDistances.vsOut());
gpArgs->fPositionVar.set(kFloat2_GrSLType, "position");
- this->emitTransforms(v, varyingHandler, uniHandler, GrShaderVar("position", kFloat2_GrSLType),
- SkMatrix::I(), args.fFPCoordTransformHandler);
+ // Leave fLocalCoordVar uninitialized; this GP is not combined with frag processors
// Use the 4 edge distances to calculate coverage in the fragment shader.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
@@ -194,7 +192,6 @@
void CubicStrokeProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
- GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
varyingHandler->emitAttributes(args.fGP.cast<CubicStrokeProcessor>());
@@ -259,8 +256,7 @@
coverages.vsOut());
gpArgs->fPositionVar.set(kFloat2_GrSLType, "position");
- this->emitTransforms(v, varyingHandler, uniHandler, GrShaderVar("position", kFloat2_GrSLType),
- SkMatrix::I(), args.fFPCoordTransformHandler);
+ // Leave fLocalCoordVar uninitialized; this GP is not combined with frag processors
// Use the 2 edge distances and interpolated butt cap AA to calculate fragment coverage.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
diff --git a/src/gpu/ccpr/GrGSCoverageProcessor.cpp b/src/gpu/ccpr/GrGSCoverageProcessor.cpp
index feaac1a..44e2def 100644
--- a/src/gpu/ccpr/GrGSCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrGSCoverageProcessor.cpp
@@ -25,7 +25,7 @@
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
const CoordTransformRange& transformRange) final {
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
diff --git a/src/gpu/ccpr/GrVSCoverageProcessor.cpp b/src/gpu/ccpr/GrVSCoverageProcessor.cpp
index ee3ce64..0270cbf 100644
--- a/src/gpu/ccpr/GrVSCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrVSCoverageProcessor.cpp
@@ -20,7 +20,7 @@
private:
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
const CoordTransformRange& transformRange) final {
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
void onEmitCode(EmitArgs&, GrGPArgs*) override;
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index cbd8baa..e127ab4 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -28,12 +28,8 @@
const CoordTransformRange& transformRange) override {
const GrConicEffect& ce = primProc.cast<GrConicEffect>();
- if (!ce.viewMatrix().isIdentity() &&
- !SkMatrixPriv::CheapEqual(fViewMatrix, ce.viewMatrix()))
- {
- fViewMatrix = ce.viewMatrix();
- pdman.setSkMatrix(fViewMatrixUniform, fViewMatrix);
- }
+ this->setTransform(pdman, fViewMatrixUniform, ce.viewMatrix(), &fViewMatrix);
+ this->setTransform(pdman, fLocalMatrixUniform, ce.localMatrix(), &fLocalMatrix);
if (ce.color() != fColor) {
pdman.set4fv(fColorUniform, 1, ce.color().vec());
@@ -44,24 +40,27 @@
pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale()));
fCoverageScale = ce.coverageScale();
}
- this->setTransformDataHelper(ce.localMatrix(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
private:
SkMatrix fViewMatrix;
+ SkMatrix fLocalMatrix;
SkPMColor4f fColor;
uint8_t fCoverageScale;
UniformHandle fColorUniform;
UniformHandle fCoverageScaleUniform;
UniformHandle fViewMatrixUniform;
+ UniformHandle fLocalMatrixUniform;
typedef GrGLSLGeometryProcessor INHERITED;
};
GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor)
- : fViewMatrix(SkMatrix::InvalidMatrix())
- , fColor(SK_PMColor4fILLEGAL)
- , fCoverageScale(0xff) {}
+ : fViewMatrix(SkMatrix::InvalidMatrix())
+ , fLocalMatrix(SkMatrix::InvalidMatrix())
+ , fColor(SK_PMColor4fILLEGAL)
+ , fCoverageScale(0xff) {}
void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
@@ -87,14 +86,10 @@
gp.inPosition().name(),
gp.viewMatrix(),
&fViewMatrixUniform);
-
- // emit transforms with position
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- gp.inPosition().asShaderVar(),
- gp.localMatrix(),
- args.fFPCoordTransformHandler);
+ if (gp.usesLocalCoords()) {
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs, gp.inPosition().asShaderVar(),
+ gp.localMatrix(), &fLocalMatrixUniform);
+ }
// TODO: we should check on the number of bits float and half provide and use the smallest one
// that suffices. Additionally we should assert that the upstream code only lets us get here if
@@ -165,8 +160,9 @@
const GrConicEffect& ce = gp.cast<GrConicEffect>();
uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
key |= 0xff != ce.coverageScale() ? 0x8 : 0x0;
- key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
- key |= ComputePosKey(ce.viewMatrix()) << 5;
+ key |= ce.usesLocalCoords() ? 0x10 : 0x0;
+ key = AddMatrixKeys(key, ce.viewMatrix(), ce.usesLocalCoords() ? ce.localMatrix()
+ : SkMatrix::I());
b->add32(key);
}
@@ -227,12 +223,8 @@
const CoordTransformRange& transformRange) override {
const GrQuadEffect& qe = primProc.cast<GrQuadEffect>();
- if (!qe.viewMatrix().isIdentity() &&
- !SkMatrixPriv::CheapEqual(fViewMatrix, qe.viewMatrix()))
- {
- fViewMatrix = qe.viewMatrix();
- pdman.setSkMatrix(fViewMatrixUniform, fViewMatrix);
- }
+ this->setTransform(pdman, fViewMatrixUniform, qe.viewMatrix(), &fViewMatrix);
+ this->setTransform(pdman, fLocalMatrixUniform, qe.localMatrix(), &fLocalMatrix);
if (qe.color() != fColor) {
pdman.set4fv(fColorUniform, 1, qe.color().vec());
@@ -243,24 +235,28 @@
pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale()));
fCoverageScale = qe.coverageScale();
}
- this->setTransformDataHelper(qe.localMatrix(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
private:
SkMatrix fViewMatrix;
+ SkMatrix fLocalMatrix;
SkPMColor4f fColor;
uint8_t fCoverageScale;
+
UniformHandle fColorUniform;
UniformHandle fCoverageScaleUniform;
UniformHandle fViewMatrixUniform;
+ UniformHandle fLocalMatrixUniform;
typedef GrGLSLGeometryProcessor INHERITED;
};
GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor)
- : fViewMatrix(SkMatrix::InvalidMatrix())
- , fColor(SK_PMColor4fILLEGAL)
- , fCoverageScale(0xff) {}
+ : fViewMatrix(SkMatrix::InvalidMatrix())
+ , fLocalMatrix(SkMatrix::InvalidMatrix())
+ , fColor(SK_PMColor4fILLEGAL)
+ , fCoverageScale(0xff) {}
void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
@@ -286,14 +282,10 @@
gp.inPosition().name(),
gp.viewMatrix(),
&fViewMatrixUniform);
-
- // emit transforms with position
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- gp.inPosition().asShaderVar(),
- gp.localMatrix(),
- args.fFPCoordTransformHandler);
+ if (gp.usesLocalCoords()) {
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs, gp.inPosition().asShaderVar(),
+ gp.localMatrix(), &fLocalMatrixUniform);
+ }
fragBuilder->codeAppendf("half edgeAlpha;");
@@ -329,8 +321,9 @@
const GrQuadEffect& ce = gp.cast<GrQuadEffect>();
uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
key |= ce.coverageScale() != 0xff ? 0x8 : 0x0;
- key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
- key |= ComputePosKey(ce.viewMatrix()) << 5;
+ key |= ce.usesLocalCoords()? 0x10 : 0x0;
+ key = AddMatrixKeys(key, ce.viewMatrix(), ce.usesLocalCoords() ? ce.localMatrix()
+ : SkMatrix::I());
b->add32(key);
}
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 8761212..4a9f94e 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -20,7 +20,10 @@
class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor {
public:
- GrGLBitmapTextGeoProc() : fColor(SK_PMColor4fILLEGAL), fAtlasDimensions{0,0} {}
+ GrGLBitmapTextGeoProc()
+ : fColor(SK_PMColor4fILLEGAL)
+ , fAtlasDimensions{0,0}
+ , fLocalMatrix(SkMatrix::InvalidMatrix()) {}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const GrBitmapTextGeoProc& btgp = args.fGP.cast<GrBitmapTextGeoProc>();
@@ -53,14 +56,8 @@
// Setup position
gpArgs->fPositionVar = btgp.inPosition().asShaderVar();
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- btgp.inPosition().asShaderVar(),
- btgp.localMatrix(),
- args.fFPCoordTransformHandler);
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs, btgp.inPosition().asShaderVar(),
+ btgp.localMatrix(), &fLocalMatrixUniform);
fragBuilder->codeAppend("half4 texColor;");
append_multitexture_lookup(args, btgp.numTextureSamplers(),
@@ -92,7 +89,9 @@
1.0f / atlasDimensions.fHeight);
fAtlasDimensions = atlasDimensions;
}
- this->setTransformDataHelper(btgp.localMatrix(), pdman, transformRange);
+
+ this->setTransform(pdman, fLocalMatrixUniform, btgp.localMatrix(), &fLocalMatrix);
+ this->setTransformDataHelper(pdman, transformRange);
}
static inline void GenKey(const GrGeometryProcessor& proc,
@@ -102,6 +101,7 @@
uint32_t key = 0;
key |= btgp.usesW() ? 0x1 : 0x0;
key |= btgp.maskFormat() << 1;
+ key |= ComputeMatrixKey(btgp.localMatrix()) << 2;
b->add32(key);
b->add32(btgp.numTextureSamplers());
}
@@ -113,6 +113,9 @@
SkISize fAtlasDimensions;
UniformHandle fAtlasDimensionsInvUniform;
+ SkMatrix fLocalMatrix;
+ UniformHandle fLocalMatrixUniform;
+
typedef GrGLSLGeometryProcessor INHERITED;
};
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 3bf74e1..19c75f3 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -57,14 +57,8 @@
// Setup position
gpArgs->fPositionVar = dfTexEffect.inPosition().asShaderVar();
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- dfTexEffect.inPosition().asShaderVar(),
- dfTexEffect.localMatrix(),
- args.fFPCoordTransformHandler);
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs, gpArgs->fPositionVar,
+ dfTexEffect.localMatrix(), &fLocalMatrixUniform);
// add varyings
GrGLSLVarying uv(kFloat2_GrSLType);
@@ -185,7 +179,8 @@
1.0f / atlasDimensions.fHeight);
fAtlasDimensions = atlasDimensions;
}
- this->setTransformDataHelper(dfa8gp.localMatrix(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform, dfa8gp.localMatrix(), &fLocalMatrix);
}
static inline void GenKey(const GrGeometryProcessor& gp,
@@ -193,6 +188,7 @@
GrProcessorKeyBuilder* b) {
const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldA8TextGeoProc>();
uint32_t key = dfTexEffect.getFlags();
+ key |= ComputeMatrixKey(dfTexEffect.localMatrix()) << 16;
b->add32(key);
b->add32(dfTexEffect.numTextureSamplers());
}
@@ -202,9 +198,12 @@
float fDistanceAdjust = -1.f;
UniformHandle fDistanceAdjustUni;
#endif
- SkISize fAtlasDimensions = {0, 0};
+ SkISize fAtlasDimensions = {0, 0};
UniformHandle fAtlasDimensionsInvUniform;
+ SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix();
+ UniformHandle fLocalMatrixUniform;
+
typedef GrGLSLGeometryProcessor INHERITED;
};
@@ -354,31 +353,20 @@
varyingHandler->addPassThroughAttribute(dfPathEffect.inColor(), args.fOutputColor);
if (dfPathEffect.matrix().hasPerspective()) {
- // Setup position
+ // Setup position (output position is transformed, local coords are pass through)
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
dfPathEffect.inPosition().name(),
dfPathEffect.matrix(),
&fMatrixUniform);
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- dfPathEffect.inPosition().asShaderVar(),
- args.fFPCoordTransformHandler);
+ gpArgs->fLocalCoordVar = dfPathEffect.inPosition().asShaderVar();
} else {
- // Setup position
+ // Setup position (output position is pass through, local coords are transformed)
this->writeOutputPosition(vertBuilder, gpArgs, dfPathEffect.inPosition().name());
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- dfPathEffect.inPosition().asShaderVar(),
- dfPathEffect.matrix(),
- args.fFPCoordTransformHandler);
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs,
+ dfPathEffect.inPosition().asShaderVar(), dfPathEffect.matrix(),
+ &fMatrixUniform);
}
// Use highp to work around aliasing issues
@@ -463,10 +451,9 @@
const CoordTransformRange& transformRange) override {
const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathGeoProc>();
- if (dfpgp.matrix().hasPerspective() && !SkMatrixPriv::CheapEqual(fMatrix, dfpgp.matrix())) {
- fMatrix = dfpgp.matrix();
- pdman.setSkMatrix(fMatrixUniform, fMatrix);
- }
+ // We always set the matrix uniform; it's either used to transform from local to device
+ // for the output position, or from device to local for the local coord variable.
+ this->setTransform(pdman, fMatrixUniform, dfpgp.matrix(), &fMatrix);
const SkISize& atlasDimensions = dfpgp.atlasDimensions();
SkASSERT(SkIsPow2(atlasDimensions.fWidth) && SkIsPow2(atlasDimensions.fHeight));
@@ -477,11 +464,7 @@
fAtlasDimensions = atlasDimensions;
}
- if (dfpgp.matrix().hasPerspective()) {
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
- } else {
- this->setTransformDataHelper(dfpgp.matrix(), pdman, transformRange);
- }
+ this->setTransformDataHelper(pdman, transformRange);
}
static inline void GenKey(const GrGeometryProcessor& gp,
@@ -490,7 +473,7 @@
const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldPathGeoProc>();
uint32_t key = dfTexEffect.getFlags();
- key |= ComputePosKey(dfTexEffect.matrix()) << 16;
+ key |= ComputeMatrixKey(dfTexEffect.matrix()) << 16;
b->add32(key);
b->add32(dfTexEffect.matrix().hasPerspective());
b->add32(dfTexEffect.numTextureSamplers());
@@ -605,7 +588,9 @@
class GrGLDistanceFieldLCDTextGeoProc : public GrGLSLGeometryProcessor {
public:
- GrGLDistanceFieldLCDTextGeoProc() : fAtlasDimensions({0, 0}) {
+ GrGLDistanceFieldLCDTextGeoProc()
+ : fAtlasDimensions({0, 0})
+ , fLocalMatrix(SkMatrix::InvalidMatrix()) {
fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.0f, 1.0f, 1.0f);
}
@@ -634,14 +619,9 @@
// Setup position
gpArgs->fPositionVar = dfTexEffect.inPosition().asShaderVar();
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- dfTexEffect.inPosition().asShaderVar(),
- dfTexEffect.localMatrix(),
- args.fFPCoordTransformHandler);
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs,
+ dfTexEffect.inPosition().asShaderVar(), dfTexEffect.localMatrix(),
+ &fLocalMatrixUniform);
// set up varyings
GrGLSLVarying uv(kFloat2_GrSLType);
@@ -801,7 +781,8 @@
1.0f / atlasDimensions.fHeight);
fAtlasDimensions = atlasDimensions;
}
- this->setTransformDataHelper(dflcd.localMatrix(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform, dflcd.localMatrix(), &fLocalMatrix);
}
static inline void GenKey(const GrGeometryProcessor& gp,
@@ -809,7 +790,8 @@
GrProcessorKeyBuilder* b) {
const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldLCDTextGeoProc>();
- uint32_t key = dfTexEffect.getFlags();
+ uint32_t key = (dfTexEffect.getFlags() << 16) |
+ ComputeMatrixKey(dfTexEffect.localMatrix());
b->add32(key);
b->add32(dfTexEffect.numTextureSamplers());
}
@@ -821,6 +803,9 @@
SkISize fAtlasDimensions;
UniformHandle fAtlasDimensionsInvUniform;
+ SkMatrix fLocalMatrix;
+ UniformHandle fLocalMatrixUniform;
+
typedef GrGLSLGeometryProcessor INHERITED;
};
diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp
index de6db26..d129a7d 100644
--- a/src/gpu/effects/GrShadowGeoProc.cpp
+++ b/src/gpu/effects/GrShadowGeoProc.cpp
@@ -22,7 +22,6 @@
const GrRRectShadowGeoProc& rsgp = args.fGP.cast<GrRRectShadowGeoProc>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// emit attributes
@@ -35,13 +34,7 @@
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, rsgp.inPosition().name());
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- rsgp.inPosition().asShaderVar(),
- args.fFPCoordTransformHandler);
+ // No need for local coordinates, this GP does not combine with fragment processors
fragBuilder->codeAppend("half d = length(shadowParams.xy);");
fragBuilder->codeAppend("float2 uv = float2(shadowParams.z * (1.0 - d), 0.5);");
@@ -53,7 +46,7 @@
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
const CoordTransformRange& transformRange) override {
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
private:
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index 0d63776..334b35b 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -20,6 +20,13 @@
GrGPArgs gpArgs;
this->onEmitCode(args, &gpArgs);
+ // FIXME This must always be called at the moment, even when fLocalCoordVar is uninitialized
+ // and void because collectTransforms registers the uniforms for legacy coord transforms, which
+ // still need to be added even if the FPs are sampled explicitly. When they are gone, we only
+ // need to call this if the local coord isn't void (plus verify that FPs really don't need it).
+ this->collectTransforms(args.fVertBuilder, args.fVaryingHandler, args.fUniformHandler,
+ gpArgs.fLocalCoordVar, args.fFPCoordTransformHandler);
+
if (args.fGP.willUseTessellationShaders()) {
// Tessellation shaders are temporarily responsible for integrating their own code strings
// while we work out full support.
@@ -62,12 +69,11 @@
}
}
-void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb,
- GrGLSLVaryingHandler* varyingHandler,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderVar& localCoordsVar,
- const SkMatrix& localMatrix,
- FPCoordTransformHandler* handler) {
+void GrGLSLGeometryProcessor::collectTransforms(GrGLSLVertexBuilder* vb,
+ GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderVar& localCoordsVar,
+ FPCoordTransformHandler* handler) {
// We only require localCoordsVar to be valid if there is a coord transform that needs
// it. CTs on FPs called with explicit coords do not require a local coord.
auto getLocalCoords = [&localCoordsVar,
@@ -120,8 +126,7 @@
if (!fp.isSampledWithExplicitCoords()) {
auto [localCoordsStr, localCoordLength] = getLocalCoords();
GrGLSLVarying v(kFloat2_GrSLType);
- if (localMatrix.hasPerspective() || coordTransform.matrix().hasPerspective() ||
- localCoordLength == 3) {
+ if (coordTransform.matrix().hasPerspective() || localCoordLength == 3) {
v = GrGLSLVarying(kFloat3_GrSLType);
}
SkString strVaryingName;
@@ -182,18 +187,12 @@
}
}
-void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix,
- const GrGLSLProgramDataManager& pdman,
+void GrGLSLGeometryProcessor::setTransformDataHelper(const GrGLSLProgramDataManager& pdman,
const CoordTransformRange& transformRange) {
int i = 0;
for (auto [transform, fp] : transformRange) {
if (fInstalledTransforms[i].fHandle.isValid()) {
- SkMatrix m;
- if (fp.isSampledWithExplicitCoords()) {
- m = GetTransformMatrix(transform, SkMatrix::I());
- } else {
- m = GetTransformMatrix(transform, localMatrix);
- }
+ SkMatrix m = GetTransformMatrix(transform, SkMatrix::I());
if (!SkMatrixPriv::CheapEqual(fInstalledTransforms[i].fCurrentValue, m)) {
if (fInstalledTransforms[i].fType == kFloat4_GrSLType) {
float values[4] = {m.getScaleX(), m.getTranslateX(),
@@ -213,11 +212,94 @@
SkASSERT(i == fInstalledTransforms.count());
}
+void GrGLSLGeometryProcessor::setTransform(const GrGLSLProgramDataManager& pdman,
+ const UniformHandle& uniform,
+ const SkMatrix& matrix,
+ SkMatrix* state) const {
+ if (!uniform.isValid() || (state && SkMatrixPriv::CheapEqual(*state, matrix))) {
+ // No update needed
+ return;
+ }
+ if (state) {
+ *state = matrix;
+ }
+ if (matrix.isScaleTranslate()) {
+ // ComputeMatrixKey and writeX() assume the uniform is a float4 (can't assert since nothing
+ // is exposed on a handle, but should be caught lower down).
+ float values[4] = {matrix.getScaleX(), matrix.getTranslateX(),
+ matrix.getScaleY(), matrix.getTranslateY()};
+ pdman.set4fv(uniform, 1, values);
+ } else {
+ pdman.setSkMatrix(uniform, matrix);
+ }
+}
+
+static void write_vertex_position(GrGLSLVertexBuilder* vertBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderVar& inPos,
+ const SkMatrix& matrix,
+ const char* matrixName,
+ GrShaderVar* outPos,
+ GrGLSLGeometryProcessor::UniformHandle* matrixUniform) {
+ SkASSERT(inPos.getType() == kFloat3_GrSLType || inPos.getType() == kFloat2_GrSLType);
+ SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
+
+ if (matrix.isIdentity()) {
+ // Direct assignment, we won't use a uniform for the matrix.
+ outPos->set(inPos.getType(), outName.c_str());
+ vertBuilder->codeAppendf("float%d %s = %s;", GrSLTypeVecLength(inPos.getType()),
+ outName.c_str(), inPos.getName().c_str());
+ } else {
+ SkASSERT(matrixUniform);
+
+ bool useCompactTransform = matrix.isScaleTranslate();
+ const char* mangledMatrixName;
+ *matrixUniform = uniformHandler->addUniform(nullptr,
+ kVertex_GrShaderFlag,
+ useCompactTransform ? kFloat4_GrSLType
+ : kFloat3x3_GrSLType,
+ matrixName,
+ &mangledMatrixName);
+
+ if (inPos.getType() == kFloat3_GrSLType) {
+ // A float3 stays a float3 whether or not the matrix adds perspective
+ if (useCompactTransform) {
+ vertBuilder->codeAppendf("float3 %s = %s.xz1 * %s + %s.yw0;\n",
+ outName.c_str(), mangledMatrixName,
+ inPos.getName().c_str(), mangledMatrixName);
+ } else {
+ vertBuilder->codeAppendf("float3 %s = %s * %s;\n", outName.c_str(),
+ mangledMatrixName, inPos.getName().c_str());
+ }
+ outPos->set(kFloat3_GrSLType, outName.c_str());
+ } else if (matrix.hasPerspective()) {
+ // A float2 is promoted to a float3 if we add perspective via the matrix
+ SkASSERT(!useCompactTransform);
+ vertBuilder->codeAppendf("float3 %s = (%s * %s.xy1);",
+ outName.c_str(), mangledMatrixName, inPos.getName().c_str());
+ outPos->set(kFloat3_GrSLType, outName.c_str());
+ } else {
+ if (useCompactTransform) {
+ vertBuilder->codeAppendf("float2 %s = %s.xz * %s + %s.yw;\n",
+ outName.c_str(), mangledMatrixName,
+ inPos.getName().c_str(), mangledMatrixName);
+ } else {
+ vertBuilder->codeAppendf("float2 %s = (%s * %s.xy1).xy;\n",
+ outName.c_str(), mangledMatrixName,
+ inPos.getName().c_str());
+ }
+ outPos->set(kFloat2_GrSLType, outName.c_str());
+ }
+ }
+}
+
void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder,
GrGPArgs* gpArgs,
const char* posName) {
- gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2");
- vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
+ // writeOutputPosition assumes the incoming pos name points to a float2 variable
+ GrShaderVar inPos(posName, kFloat2_GrSLType);
+ write_vertex_position(vertBuilder, nullptr, inPos, SkMatrix::I(), "viewMatrix",
+ &gpArgs->fPositionVar, nullptr);
}
void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder,
@@ -226,24 +308,17 @@
const char* posName,
const SkMatrix& mat,
UniformHandle* viewMatrixUniform) {
- if (mat.isIdentity()) {
- gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2");
- vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
- } else {
- const char* viewMatrixName;
- *viewMatrixUniform = uniformHandler->addUniform(nullptr,
- kVertex_GrShaderFlag,
- kFloat3x3_GrSLType,
- "uViewM",
- &viewMatrixName);
- if (!mat.hasPerspective()) {
- gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2");
- vertBuilder->codeAppendf("float2 %s = (%s * float3(%s, 1)).xy;",
- gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
- } else {
- gpArgs->fPositionVar.set(kFloat3_GrSLType, "pos3");
- vertBuilder->codeAppendf("float3 %s = %s * float3(%s, 1);",
- gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
- }
- }
+ GrShaderVar inPos(posName, kFloat2_GrSLType);
+ write_vertex_position(vertBuilder, uniformHandler, inPos, mat, "viewMatrix",
+ &gpArgs->fPositionVar, viewMatrixUniform);
+}
+
+void GrGLSLGeometryProcessor::writeLocalCoord(GrGLSLVertexBuilder* vertBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ GrGPArgs* gpArgs,
+ GrShaderVar localVar,
+ const SkMatrix& localMatrix,
+ UniformHandle* localMatrixUniform) {
+ write_vertex_position(vertBuilder, uniformHandler, localVar, localMatrix, "localMatrix",
+ &gpArgs->fLocalCoordVar, localMatrixUniform);
}
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.h b/src/gpu/glsl/GrGLSLGeometryProcessor.h
index f23bd0e..10e2137 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.h
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.h
@@ -22,41 +22,33 @@
/* Any general emit code goes in the base class emitCode. Subclasses override onEmitCode */
void emitCode(EmitArgs&) final;
-protected:
- // A helper which subclasses can use to upload coord transform matrices in setData().
- void setTransformDataHelper(const SkMatrix& localMatrix,
- const GrGLSLProgramDataManager& pdman,
- const CoordTransformRange&);
-
- // Emit transformed local coords from the vertex shader as a uniform matrix and varying per
- // coord-transform. localCoordsVar must be a 2- or 3-component vector. If it is 3 then it is
- // assumed to be a 2D homogeneous coordinate.
- void emitTransforms(GrGLSLVertexBuilder*,
- GrGLSLVaryingHandler*,
- GrGLSLUniformHandler*,
- const GrShaderVar& localCoordsVar,
- const SkMatrix& localMatrix,
- FPCoordTransformHandler*);
-
- // Version of above that assumes identity for the local matrix.
- void emitTransforms(GrGLSLVertexBuilder* vb,
- GrGLSLVaryingHandler* varyingHandler,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderVar& localCoordsVar,
- FPCoordTransformHandler* handler) {
- this->emitTransforms(vb, varyingHandler, uniformHandler, localCoordsVar, SkMatrix::I(),
- handler);
- }
-
- // TODO: doc
+ // Generate the final code for assigning transformed coordinates to the varyings recorded in
+ // the call to collectTransforms(). This must happen after FP code emission so that it has
+ // access to any uniforms the FPs registered for const/uniform sample matrix invocations.
void emitTransformCode(GrGLSLVertexBuilder* vb,
GrGLSLUniformHandler* uniformHandler) override;
+protected:
+ // A helper which subclasses can use to upload coord transform matrices in setData().
+ void setTransformDataHelper(const GrGLSLProgramDataManager& pdman,
+ const CoordTransformRange&);
+
+ // A helper for setting the matrix on a uniform handle initialized through
+ // writeOutputPosition or writeLocalCoord. Automatically handles elided uniforms,
+ // scale+translate matrices, and state tracking (if provided state pointer is non-null).
+ void setTransform(const GrGLSLProgramDataManager& pdman, const UniformHandle& uniform,
+ const SkMatrix& matrix, SkMatrix* state=nullptr) const;
+
struct GrGPArgs {
// Used to specify the output variable used by the GP to store its device position. It can
// either be a float2 or a float3 (in order to handle perspective). The subclass sets this
// in its onEmitCode().
GrShaderVar fPositionVar;
+ // Used to specify the variable storing the draw's local coordinates. It can be either a
+ // float2, float3, or void. It can only be void when no FP needs local coordinates. This
+ // variable can be an attribute or local variable, but should not itself be a varying.
+ // GrGLSLGeometryProcessor automatically determines if this must be passed to a FS.
+ GrShaderVar fLocalCoordVar;
};
// Helpers for adding code to write the transformed vertex position. The first simple version
@@ -73,19 +65,54 @@
const SkMatrix& mat,
UniformHandle* viewMatrixUniform);
- static uint32_t ComputePosKey(const SkMatrix& mat) {
+ // Helper to transform an existing variable by a given local matrix (e.g. the inverse view
+ // matrix). It will declare the transformed local coord variable and will set
+ // GrGPArgs::fLocalCoordVar.
+ void writeLocalCoord(GrGLSLVertexBuilder*, GrGLSLUniformHandler*, GrGPArgs*,
+ GrShaderVar localVar, const SkMatrix& localMatrix,
+ UniformHandle* localMatrixUniform);
+
+ // GPs that use writeOutputPosition and/or writeLocalCoord must incorporate the matrix type
+ // into their key, and should use this function or one of the other related helpers.
+ static uint32_t ComputeMatrixKey(const SkMatrix& mat) {
if (mat.isIdentity()) {
- return 0x0;
+ return 0b00;
+ } else if (mat.isScaleTranslate()) {
+ return 0b01;
} else if (!mat.hasPerspective()) {
- return 0x01;
+ return 0b10;
} else {
- return 0x02;
+ return 0b11;
}
}
+ static uint32_t ComputeMatrixKeys(const SkMatrix& viewMatrix, const SkMatrix& localMatrix) {
+ return (ComputeMatrixKey(viewMatrix) << kMatrixKeyBits) | ComputeMatrixKey(localMatrix);
+ }
+ static uint32_t AddMatrixKeys(uint32_t flags, const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix) {
+ // Shifting to make room for the matrix keys shouldn't lose bits
+ SkASSERT(((flags << (2 * kMatrixKeyBits)) >> (2 * kMatrixKeyBits)) == flags);
+ return (flags << (2 * kMatrixKeyBits)) | ComputeMatrixKeys(viewMatrix, localMatrix);
+ }
+ static constexpr int kMatrixKeyBits = 2;
private:
virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0;
+ // Iterates over the FPs in 'handler' to register additional varyings and uniforms to support
+ // VS-promoted local coord evaluation for the FPs. Subclasses must call this with
+ // 'localCoordsVar' set to an SkSL variable expression of type 'float2' or 'float3' representing
+ // the original local coordinates of the draw.
+ //
+ // This must happen before FP code emission so that the FPs can find the appropriate varying
+ // handles they use in place of explicit coord sampling; it is automatically called after
+ // onEmitCode() returns using the value stored in GpArgs::fLocalCoordVar.
+ void collectTransforms(GrGLSLVertexBuilder* vb,
+ GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderVar& localCoordsVar,
+ FPCoordTransformHandler* handler);
+
struct TransformUniform {
UniformHandle fHandle;
GrSLType fType = kVoid_GrSLType;
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
index 5b27431..e5a9c14 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
@@ -20,7 +20,8 @@
, fOutputs(GrGLSLProgramBuilder::kVarsPerBlock)
, fFeaturesAddedMask(0)
, fCodeIndex(kCode)
- , fFinalized(false) {
+ , fFinalized(false)
+ , fTmpVariableCounter(0) {
// We push back some dummy pointers which will later become our header
for (int i = 0; i <= kCode; i++) {
fShaderStrings.push_back();
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index b69abe8..b766280 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -84,6 +84,13 @@
void declareGlobal(const GrShaderVar&);
+ // Generates a unique variable name for holding the result of a temporary expression when it's
+ // not reasonable to just add a new block for scoping. Does not declare anything.
+ SkString newTmpVarName(const char* suffix) {
+ int tmpIdx = fTmpVariableCounter++;
+ return SkStringPrintf("_tmp_%d_%s", tmpIdx, suffix);
+ }
+
/**
* Called by GrGLSLProcessors to add code to one of the shaders.
*/
@@ -238,6 +245,9 @@
int fCodeIndex;
bool fFinalized;
+ // Counter for generating unique scratch variable names in a shader.
+ int fTmpVariableCounter;
+
friend class GrCCCoverageProcessor; // to access code().
friend class GrGLSLProgramBuilder;
friend class GrGLProgramBuilder;
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index ca11c0d..2dc3e1a 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -577,14 +577,11 @@
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, qe.fInPosition.name());
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- qe.fInPosition.asShaderVar(),
- qe.fLocalMatrix,
- args.fFPCoordTransformHandler);
+ if (qe.fUsesLocalCoords) {
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs,
+ qe.fInPosition.asShaderVar(), qe.fLocalMatrix,
+ &fLocalMatrixUniform);
+ }
fragBuilder->codeAppendf("half edgeAlpha;");
@@ -611,18 +608,24 @@
const GrShaderCaps&,
GrProcessorKeyBuilder* b) {
const QuadEdgeEffect& qee = gp.cast<QuadEdgeEffect>();
- b->add32(SkToBool(qee.fUsesLocalCoords && qee.fLocalMatrix.hasPerspective()));
+ uint32_t key = (uint32_t) qee.fUsesLocalCoords;
+ key |= ComputeMatrixKey(qee.fLocalMatrix) << 1;
+ b->add32(key);
}
void setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& gp,
const CoordTransformRange& transformRange) override {
const QuadEdgeEffect& qe = gp.cast<QuadEdgeEffect>();
- this->setTransformDataHelper(qe.fLocalMatrix, pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform, qe.fLocalMatrix, &fLocalMatrix);
}
private:
typedef GrGLSLGeometryProcessor INHERITED;
+
+ SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix();
+ UniformHandle fLocalMatrixUniform;
};
void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index 6f663f6..5ee04a4 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -876,14 +876,19 @@
private:
UniformHandle fParamUniform;
UniformHandle fColorUniform;
+ UniformHandle fLocalMatrixUniform;
+
+ SkMatrix fLocalMatrix;
SkPMColor4f fColor;
SkScalar fPrevRadius;
SkScalar fPrevCenterX;
SkScalar fPrevIntervalLength;
+
typedef GrGLSLGeometryProcessor INHERITED;
};
GLDashingCircleEffect::GLDashingCircleEffect() {
+ fLocalMatrix = SkMatrix::InvalidMatrix();
fColor = SK_PMColor4fILLEGAL;
fPrevRadius = SK_ScalarMin;
fPrevCenterX = SK_ScalarMin;
@@ -915,14 +920,10 @@
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, dce.fInPosition.name());
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- dce.fInPosition.asShaderVar(),
- dce.localMatrix(),
- args.fFPCoordTransformHandler);
+ if (dce.usesLocalCoords()) {
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs, dce.fInPosition.asShaderVar(),
+ dce.localMatrix(), &fLocalMatrixUniform);
+ }
// transforms all points so that we can compare them to our test circle
fragBuilder->codeAppendf("half xShifted = half(%s.x - floor(%s.x / %s.z) * %s.z);",
@@ -951,7 +952,8 @@
pdman.set4fv(fColorUniform, 1, dce.color().vec());
fColor = dce.color();
}
- this->setTransformDataHelper(dce.localMatrix(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform, dce.localMatrix(), &fLocalMatrix);
}
void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp,
@@ -959,8 +961,9 @@
GrProcessorKeyBuilder* b) {
const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>();
uint32_t key = 0;
- key |= dce.usesLocalCoords() && dce.localMatrix().hasPerspective() ? 0x1 : 0x0;
+ key |= dce.usesLocalCoords() ? 0x1 : 0x0;
key |= static_cast<uint32_t>(dce.aaMode()) << 1;
+ key |= ComputeMatrixKey(dce.localMatrix()) << 3;
b->add32(key);
}
@@ -1086,6 +1089,10 @@
private:
SkPMColor4f fColor;
UniformHandle fColorUniform;
+
+ SkMatrix fLocalMatrix;
+ UniformHandle fLocalMatrixUniform;
+
typedef GrGLSLGeometryProcessor INHERITED;
};
@@ -1118,14 +1125,10 @@
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, de.fInPosition.name());
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- de.fInPosition.asShaderVar(),
- de.localMatrix(),
- args.fFPCoordTransformHandler);
+ if (de.usesLocalCoords()) {
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs, de.fInPosition.asShaderVar(),
+ de.localMatrix(), &fLocalMatrixUniform);
+ }
// transforms all points so that we can compare them to our test rect
fragBuilder->codeAppendf("half xShifted = half(%s.x - floor(%s.x / %s.z) * %s.z);",
@@ -1178,7 +1181,8 @@
pdman.set4fv(fColorUniform, 1, de.color().vec());
fColor = de.color();
}
- this->setTransformDataHelper(de.localMatrix(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform, de.localMatrix(), &fLocalMatrix);
}
void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp,
@@ -1186,8 +1190,9 @@
GrProcessorKeyBuilder* b) {
const DashingLineEffect& de = gp.cast<DashingLineEffect>();
uint32_t key = 0;
- key |= de.usesLocalCoords() && de.localMatrix().hasPerspective() ? 0x1 : 0x0;
- key |= static_cast<int>(de.aaMode()) << 8;
+ key |= de.usesLocalCoords() ? 0x1 : 0x0;
+ key |= static_cast<int>(de.aaMode()) << 1;
+ key |= ComputeMatrixKey(de.localMatrix()) << 3;
b->add32(key);
}
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index d538805..111cc7e 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -185,12 +185,7 @@
// emit transforms using either explicit local coords or positions
const auto& coordsAttr = gp.localCoordsAttr().isInitialized() ? gp.localCoordsAttr()
: gp.positionAttr();
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- coordsAttr.asShaderVar(),
- SkMatrix::I(),
- args.fFPCoordTransformHandler);
+ gpArgs->fLocalCoordVar = coordsAttr.asShaderVar();
// Add varyings and globals for all custom attributes
using Usage = SkVertices::Attribute::Usage;
@@ -306,7 +301,7 @@
const VerticesGP& vgp = gp.cast<VerticesGP>();
uint32_t key = 0;
key |= (vgp.fColorArrayType == ColorArrayType::kSkColor) ? 0x1 : 0;
- key |= ComputePosKey(vgp.viewMatrix()) << 20;
+ key |= ComputeMatrixKey(vgp.viewMatrix()) << 20;
b->add32(key);
b->add32(GrColorSpaceXform::XformKey(vgp.fColorSpaceXform.get()));
@@ -323,19 +318,14 @@
const CoordTransformRange& transformRange) override {
const VerticesGP& vgp = gp.cast<VerticesGP>();
- if (!vgp.viewMatrix().isIdentity() &&
- !SkMatrixPriv::CheapEqual(fViewMatrix, vgp.viewMatrix())) {
- fViewMatrix = vgp.viewMatrix();
- pdman.setSkMatrix(fViewMatrixUniform, fViewMatrix);
- }
+ this->setTransform(pdman, fViewMatrixUniform, vgp.viewMatrix(), &fViewMatrix);
+ this->setTransformDataHelper(pdman, transformRange);
if (!vgp.colorAttr().isInitialized() && vgp.color() != fColor) {
pdman.set4fv(fColorUniform, 1, vgp.color().vec());
fColor = vgp.color();
}
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
-
fColorSpaceHelper.setData(pdman, vgp.fColorSpaceXform.get());
for (const auto& matrixUni : fCustomMatrixUniforms) {
diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp
index 76122e5..630955f 100644
--- a/src/gpu/ops/GrFillRRectOp.cpp
+++ b/src/gpu/ops/GrFillRRectOp.cpp
@@ -680,15 +680,13 @@
v->codeAppend("float2 aa_outset = aa_bloat_direction.xy * aa_bloatradius;");
v->codeAppend("float2 vertexpos = corner + radius_outset * radii + aa_outset;");
- // Emit transforms.
+ // Write positions
GrShaderVar localCoord("", kFloat2_GrSLType);
if (proc.fFlags & ProcessorFlags::kHasLocalCoords) {
v->codeAppend("float2 localcoord = (local_rect.xy * (1 - vertexpos) + "
"local_rect.zw * (1 + vertexpos)) * .5;");
- localCoord.set(kFloat2_GrSLType, "localcoord");
+ gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
}
- this->emitTransforms(v, varyings, args.fUniformHandler, localCoord,
- args.fFPCoordTransformHandler);
// Transform to device space.
SkASSERT(!(proc.fFlags & ProcessorFlags::kHasPerspective));
@@ -743,7 +741,7 @@
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
const CoordTransformRange& transformRange) override {
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
};
@@ -781,15 +779,13 @@
// [-1,-1,+1,+1] space.
v->codeAppend("float2 vertexpos = corner + radius_outset * radii;");
- // Emit transforms.
+ // Write positions
GrShaderVar localCoord("", kFloat2_GrSLType);
if (hasLocalCoords) {
v->codeAppend("float2 localcoord = (local_rect.xy * (1 - vertexpos) + "
"local_rect.zw * (1 + vertexpos)) * .5;");
- localCoord.set(kFloat2_GrSLType, "localcoord");
+ gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
}
- this->emitTransforms(v, varyings, args.fUniformHandler, localCoord,
- args.fFPCoordTransformHandler);
// Transform to device space.
if (!hasPerspective) {
@@ -849,7 +845,7 @@
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
const CoordTransformRange& transformRange) override {
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
};
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 7efe3a3..fe9983f 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -49,7 +49,7 @@
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
const CoordTransformRange& transformRange) override {
const auto& latticeGP = proc.cast<LatticeGP>();
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
fColorSpaceXformHelper.setData(pdman, latticeGP.fColorSpaceXform.get());
}
@@ -62,11 +62,8 @@
args.fVaryingHandler->emitAttributes(latticeGP);
this->writeOutputPosition(args.fVertBuilder, gpArgs, latticeGP.fInPosition.name());
- this->emitTransforms(args.fVertBuilder,
- args.fVaryingHandler,
- args.fUniformHandler,
- latticeGP.fInTextureCoords.asShaderVar(),
- args.fFPCoordTransformHandler);
+ gpArgs->fLocalCoordVar = latticeGP.fInTextureCoords.asShaderVar();
+
args.fFragBuilder->codeAppend("float2 textureCoords;");
args.fVaryingHandler->addPassThroughAttribute(latticeGP.fInTextureCoords,
"textureCoords");
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index d857557..f720f63 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -155,14 +155,9 @@
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, cgp.fInPosition.name());
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- cgp.fInPosition.asShaderVar(),
- cgp.fLocalMatrix,
- args.fFPCoordTransformHandler);
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs,
+ cgp.fInPosition.asShaderVar(), cgp.fLocalMatrix,
+ &fLocalMatrixUniform);
fragBuilder->codeAppend("float d = length(circleEdge.xy);");
fragBuilder->codeAppend("half distanceToOuterEdge = half(circleEdge.z * (1.0 - d));");
@@ -210,24 +205,29 @@
const GrShaderCaps&,
GrProcessorKeyBuilder* b) {
const CircleGeometryProcessor& cgp = gp.cast<CircleGeometryProcessor>();
- uint16_t key;
+ uint32_t key;
key = cgp.fStroke ? 0x01 : 0x0;
- key |= cgp.fLocalMatrix.hasPerspective() ? 0x02 : 0x0;
- key |= cgp.fInClipPlane.isInitialized() ? 0x04 : 0x0;
- key |= cgp.fInIsectPlane.isInitialized() ? 0x08 : 0x0;
- key |= cgp.fInUnionPlane.isInitialized() ? 0x10 : 0x0;
- key |= cgp.fInRoundCapCenters.isInitialized() ? 0x20 : 0x0;
+ key |= cgp.fInClipPlane.isInitialized() ? 0x02 : 0x0;
+ key |= cgp.fInIsectPlane.isInitialized() ? 0x04 : 0x0;
+ key |= cgp.fInUnionPlane.isInitialized() ? 0x08 : 0x0;
+ key |= cgp.fInRoundCapCenters.isInitialized() ? 0x10 : 0x0;
+ key |= (ComputeMatrixKey(cgp.fLocalMatrix) << 16);
b->add32(key);
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
const CoordTransformRange& transformRange) override {
- this->setTransformDataHelper(primProc.cast<CircleGeometryProcessor>().fLocalMatrix,
- pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform,
+ primProc.cast<CircleGeometryProcessor>().fLocalMatrix,
+ &fLocalMatrix);
}
private:
typedef GrGLSLGeometryProcessor INHERITED;
+
+ SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix();
+ UniformHandle fLocalMatrixUniform;
};
SkMatrix fLocalMatrix;
@@ -389,14 +389,10 @@
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, bcscgp.fInPosition.name());
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs,
+ bcscgp.fInPosition.asShaderVar(), bcscgp.fLocalMatrix,
+ &fLocalMatrixUniform);
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- bcscgp.fInPosition.asShaderVar(),
- bcscgp.fLocalMatrix,
- args.fFPCoordTransformHandler);
GrShaderVar fnArgs[] = {
GrShaderVar("angleToEdge", kFloat_GrSLType),
GrShaderVar("diameter", kFloat_GrSLType),
@@ -477,18 +473,22 @@
GrProcessorKeyBuilder* b) {
const ButtCapDashedCircleGeometryProcessor& bcscgp =
gp.cast<ButtCapDashedCircleGeometryProcessor>();
- b->add32(bcscgp.fLocalMatrix.hasPerspective());
+ b->add32(ComputeMatrixKey(bcscgp.fLocalMatrix));
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
const CoordTransformRange& transformRange) override {
- this->setTransformDataHelper(
- primProc.cast<ButtCapDashedCircleGeometryProcessor>().fLocalMatrix, pdman,
- transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform,
+ primProc.cast<ButtCapDashedCircleGeometryProcessor>().fLocalMatrix,
+ &fLocalMatrix);
}
private:
typedef GrGLSLGeometryProcessor INHERITED;
+
+ SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix();
+ UniformHandle fLocalMatrixUniform;
};
SkMatrix fLocalMatrix;
@@ -588,14 +588,10 @@
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, egp.fInPosition.name());
+ this->writeLocalCoord(vertBuilder, uniformHandler, gpArgs,
+ egp.fInPosition.asShaderVar(), egp.fLocalMatrix,
+ &fLocalMatrixUniform);
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- egp.fInPosition.asShaderVar(),
- egp.fLocalMatrix,
- args.fFPCoordTransformHandler);
// For stroked ellipses, we use the full ellipse equation (x^2/a^2 + y^2/b^2 = 1)
// to compute both the edges because we need two separate test equations for
// the single offset.
@@ -666,19 +662,23 @@
const GrShaderCaps&,
GrProcessorKeyBuilder* b) {
const EllipseGeometryProcessor& egp = gp.cast<EllipseGeometryProcessor>();
- uint16_t key = egp.fStroke ? 0x1 : 0x0;
- key |= egp.fLocalMatrix.hasPerspective() ? 0x2 : 0x0;
+ uint32_t key = egp.fStroke ? 0x1 : 0x0;
+ key |= ComputeMatrixKey(egp.fLocalMatrix) << 1;
b->add32(key);
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
const CoordTransformRange& transformRange) override {
const EllipseGeometryProcessor& egp = primProc.cast<EllipseGeometryProcessor>();
- this->setTransformDataHelper(egp.fLocalMatrix, pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUniform, egp.fLocalMatrix, &fLocalMatrix);
}
private:
typedef GrGLSLGeometryProcessor INHERITED;
+
+ SkMatrix fLocalMatrix = SkMatrix::InvalidMatrix();
+ UniformHandle fLocalMatrixUniform;
};
Attribute fInPosition;
@@ -791,13 +791,7 @@
diegp.fInPosition.name(),
diegp.fViewMatrix,
&fViewMatrixUniform);
-
- // emit transforms
- this->emitTransforms(vertBuilder,
- varyingHandler,
- uniformHandler,
- diegp.fInPosition.asShaderVar(),
- args.fFPCoordTransformHandler);
+ gpArgs->fLocalCoordVar = diegp.fInPosition.asShaderVar();
// for outer curve
fragBuilder->codeAppendf("float2 scaledOffset = %s.xy;", offsets0.fsIn());
@@ -862,8 +856,8 @@
const GrShaderCaps&,
GrProcessorKeyBuilder* b) {
const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>();
- uint16_t key = static_cast<uint16_t>(diegp.fStyle);
- key |= ComputePosKey(diegp.fViewMatrix) << 10;
+ uint32_t key = static_cast<uint32_t>(diegp.fStyle);
+ key |= ComputeMatrixKey(diegp.fViewMatrix) << 10;
b->add32(key);
}
@@ -871,17 +865,12 @@
const CoordTransformRange& transformRange) override {
const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>();
- if (!diegp.fViewMatrix.isIdentity() &&
- !SkMatrixPriv::CheapEqual(fViewMatrix, diegp.fViewMatrix))
- {
- fViewMatrix = diegp.fViewMatrix;
- pdman.setSkMatrix(fViewMatrixUniform, fViewMatrix);
- }
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransform(pdman, fViewMatrixUniform, diegp.fViewMatrix, &fViewMatrix);
+ this->setTransformDataHelper(pdman, transformRange);
}
private:
- SkMatrix fViewMatrix;
+ SkMatrix fViewMatrix;
UniformHandle fViewMatrixUniform;
typedef GrGLSLGeometryProcessor INHERITED;
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index bc5de24..ca420dd 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -571,7 +571,7 @@
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
const CoordTransformRange& transformRange) override {
const auto& gp = proc.cast<QuadPerEdgeAAGeometryProcessor>();
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
fTextureColorSpaceXformHelper.setData(pdman, gp.fTextureColorSpaceXform.get());
}
@@ -604,18 +604,10 @@
gpArgs->fPositionVar = gp.fPosition.asShaderVar();
}
- // Handle local coordinates if they exist. This is required even when the op
- // isn't providing local coords but there are FPs called with explicit coords.
- // It installs the uniforms that transform their coordinates in the fragment
- // shader.
- // NOTE: If the only usage of local coordinates is for the inline texture fetch
- // before FPs, then there are no registered FPCoordTransforms and this ends up
- // emitting nothing, so there isn't a duplication of local coordinates
- this->emitTransforms(args.fVertBuilder,
- args.fVaryingHandler,
- args.fUniformHandler,
- gp.fLocalCoord.asShaderVar(),
- args.fFPCoordTransformHandler);
+ // This attribute will be uninitialized if earlier FP analysis determined no
+ // local coordinates are needed (and this will not include the inline texture
+ // fetch this GP does before invoking FPs).
+ gpArgs->fLocalCoordVar = gp.fLocalCoord.asShaderVar();
// Solid color before any texturing gets modulated in
if (gp.fColor.isInitialized()) {
diff --git a/src/gpu/tessellate/GrDrawAtlasPathOp.cpp b/src/gpu/tessellate/GrDrawAtlasPathOp.cpp
index 2e456f5..cda13be 100644
--- a/src/gpu/tessellate/GrDrawAtlasPathOp.cpp
+++ b/src/gpu/tessellate/GrDrawAtlasPathOp.cpp
@@ -85,15 +85,12 @@
gpArgs->fPositionVar.set(kFloat2_GrSLType, "devcoord");
- GrShaderVar localCoord = gpArgs->fPositionVar;
if (shader.fUsesLocalCoords) {
args.fVertBuilder->codeAppendf(R"(
float2x2 M = float2x2(viewmatrix_scaleskew);
float2 localcoord = inverse(M) * (devcoord - viewmatrix_trans);)");
- localCoord.set(kFloat2_GrSLType, "localcoord");
+ gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
}
- this->emitTransforms(args.fVertBuilder, args.fVaryingHandler, args.fUniformHandler,
- localCoord, args.fFPCoordTransformHandler);
args.fFragBuilder->codeAppendf("%s = ", args.fOutputCoverage);
args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], atlasCoord.fsIn());
@@ -104,7 +101,7 @@
const CoordTransformRange& transformRange) override {
const SkISize& dimensions = primProc.cast<DrawAtlasPathShader>().fAtlasDimensions;
pdman.set2f(fAtlasAdjustUniform, 1.f / dimensions.width(), 1.f / dimensions.height());
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform;
diff --git a/src/gpu/tessellate/GrFillPathShader.cpp b/src/gpu/tessellate/GrFillPathShader.cpp
index f87ac4a..93e6e59 100644
--- a/src/gpu/tessellate/GrFillPathShader.cpp
+++ b/src/gpu/tessellate/GrFillPathShader.cpp
@@ -26,11 +26,8 @@
args.fVertBuilder->codeAppend("float2 localcoord, vertexpos;");
shader.emitVertexCode(this, args.fVertBuilder, viewMatrix, args.fUniformHandler);
- this->emitTransforms(args.fVertBuilder, args.fVaryingHandler, args.fUniformHandler,
- GrShaderVar("localcoord", kFloat2_GrSLType),
- args.fFPCoordTransformHandler);
-
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertexpos");
+ gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
const char* color;
fColorUniform = args.fUniformHandler->addUniform(
@@ -53,7 +50,7 @@
pdman.set4f(fPathBoundsUniform, b.left(), b.top(), b.right(), b.bottom());
}
- this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
}
GrGLSLUniformHandler::UniformHandle fViewMatrixUniform;