SkSL sample() now permits specification of coordinates
Bug: skia:
Change-Id: I16073008ac852f1864bd1d2bd38087a5b661d05a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/232581
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/GrCoordTransform.h b/src/gpu/GrCoordTransform.h
index fac7844..2451363 100644
--- a/src/gpu/GrCoordTransform.h
+++ b/src/gpu/GrCoordTransform.h
@@ -23,7 +23,8 @@
GrCoordTransform()
: fProxy(nullptr)
, fNormalize(false)
- , fReverseY(false) {
+ , fReverseY(false)
+ , fComputeInVertexShader(true) {
SkDEBUGCODE(fInProcessor = false);
}
@@ -100,6 +101,12 @@
// successfully instantiated
GrTexture* peekTexture() const { return fProxy->peekTexture(); }
+ bool computeInVertexShader() const { return fComputeInVertexShader; }
+
+ void setComputeInVertexShader(bool computeInVertexShader) {
+ fComputeInVertexShader = computeInVertexShader;
+ }
+
private:
void reset(const SkMatrix& m, GrTextureProxy* proxy = nullptr) {
SkASSERT(!fInProcessor);
@@ -108,6 +115,7 @@
fProxy = proxy;
fNormalize = proxy && proxy->textureType() != GrTextureType::kRectangle;
fReverseY = proxy && kBottomLeft_GrSurfaceOrigin == proxy->origin();
+ fComputeInVertexShader = true;
}
// The textures' effect is to optionally normalize the final matrix, so a blind
@@ -119,6 +127,7 @@
const GrTextureProxy* fProxy;
bool fNormalize;
bool fReverseY;
+ bool fComputeInVertexShader;
#ifdef SK_DEBUG
public:
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 41975b3..2e6b1a1 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -69,7 +69,8 @@
return this->onTextureSampler(i);
}
-void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
+void GrFragmentProcessor::addCoordTransform(GrCoordTransform* transform) {
+ transform->setComputeInVertexShader(this->computeLocalCoordsInVertexShader());
fCoordTransforms.push_back(transform);
fFlags |= kUsesLocalCoords_Flag;
SkDEBUGCODE(transform->setInProcessor();)
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 1e19997..b9035ff 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -8,10 +8,10 @@
#ifndef GrFragmentProcessor_DEFINED
#define GrFragmentProcessor_DEFINED
+#include "src/gpu/GrCoordTransform.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/ops/GrOp.h"
-class GrCoordTransform;
class GrGLSLFragmentProcessor;
class GrPaint;
class GrPipeline;
@@ -114,7 +114,7 @@
numTransforms(). */
const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
- const SkTArray<const GrCoordTransform*, true>& coordTransforms() const {
+ const SkTArray<GrCoordTransform*, true>& coordTransforms() const {
return fCoordTransforms;
}
@@ -127,6 +127,24 @@
/** Do any of the coordtransforms for this processor require local coords? */
bool usesLocalCoords() const { return SkToBool(fFlags & kUsesLocalCoords_Flag); }
+ bool computeLocalCoordsInVertexShader() const {
+ return SkToBool(fFlags & kComputeLocalCoordsInVertexShader_Flag);
+ }
+
+ void setComputeLocalCoordsInVertexShader(bool value) const {
+ if (value) {
+ fFlags |= kComputeLocalCoordsInVertexShader_Flag;
+ } else {
+ fFlags &= ~kComputeLocalCoordsInVertexShader_Flag;
+ }
+ for (GrCoordTransform* transform : fCoordTransforms) {
+ transform->setComputeInVertexShader(value);
+ }
+ for (const auto& child : fChildProcessors) {
+ child->setComputeLocalCoordsInVertexShader(value);
+ }
+ }
+
/**
* A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color
* output under the following scenario:
@@ -284,8 +302,8 @@
GrFragmentProcessor(ClassID classID, OptimizationFlags optimizationFlags)
: INHERITED(classID)
- , fFlags(optimizationFlags) {
- SkASSERT((fFlags & ~kAll_OptimizationFlags) == 0);
+ , fFlags(optimizationFlags | kComputeLocalCoordsInVertexShader_Flag) {
+ SkASSERT((optimizationFlags & ~kAll_OptimizationFlags) == 0);
}
OptimizationFlags optimizationFlags() const {
@@ -325,7 +343,7 @@
* transforms in a consistent order. The non-virtual implementation of isEqual() automatically
* compares transforms and will assume they line up across the two processor instances.
*/
- void addCoordTransform(const GrCoordTransform*);
+ void addCoordTransform(GrCoordTransform*);
/**
* FragmentProcessor subclasses call this from their constructor to register any child
@@ -382,13 +400,14 @@
enum PrivateFlags {
kFirstPrivateFlag = kAll_OptimizationFlags + 1,
kUsesLocalCoords_Flag = kFirstPrivateFlag,
+ kComputeLocalCoordsInVertexShader_Flag = kFirstPrivateFlag << 1,
};
- mutable uint32_t fFlags = 0;
+ mutable uint32_t fFlags = kComputeLocalCoordsInVertexShader_Flag;
int fTextureSamplerCnt = 0;
- SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
+ SkSTArray<4, GrCoordTransform*, true> fCoordTransforms;
SkSTArray<1, std::unique_ptr<GrFragmentProcessor>, true> fChildProcessors;
diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp
index 7e36968..861ff1b 100644
--- a/src/gpu/GrPathProcessor.cpp
+++ b/src/gpu/GrPathProcessor.cpp
@@ -49,6 +49,11 @@
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
}
+ SkString matrix_to_sksl(const SkMatrix& m) {
+ return SkStringPrintf("float3x3(%f, %f, %f, %f, %f, %f, %f, %f, %f)", m[0], m[1], m[2],
+ m[3], m[4], m[5], m[6], m[7], m[8]);
+ }
+
void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
FPCoordTransformHandler* transformHandler) {
int i = 0;
@@ -66,7 +71,11 @@
&v).toIndex();
fInstalledTransforms.back().fType = varyingType;
- transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
+ transformHandler->specifyCoordsForCurrCoordTransform(
+ matrix_to_sksl(coordTransform->getMatrix()),
+ UniformHandle(),
+ GrShaderVar(SkString(v.fsIn()),
+ varyingType));
++i;
}
}
diff --git a/src/gpu/GrPrimitiveProcessor.cpp b/src/gpu/GrPrimitiveProcessor.cpp
index 1ce6ca2..70a812b 100644
--- a/src/gpu/GrPrimitiveProcessor.cpp
+++ b/src/gpu/GrPrimitiveProcessor.cpp
@@ -25,7 +25,7 @@
}
uint32_t
-GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
+GrPrimitiveProcessor::getTransformKey(const SkTArray<GrCoordTransform*, true>& coords,
int numCoords) const {
uint32_t totalKey = 0;
for (int t = 0; t < numCoords; ++t) {
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index ca79985..7145688 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -174,7 +174,7 @@
*
* TODO: A better name for this function would be "compute" instead of "get".
*/
- uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
+ uint32_t getTransformKey(const SkTArray<GrCoordTransform*, true>& coords,
int numCoords) const;
/**
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index a33ce64..e59ed01 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -46,7 +46,7 @@
const char* dims = uniformHandler->getUniformCStr(fDimensions);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
/*
* Filter weights come from Don Mitchell & Arun Netravali's 'Reconstruction Filters in Computer
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
index 33d916c..1c7e4db 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
@@ -56,7 +56,7 @@
"Kernel", arrayCount);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf("%s = half4(0, 0, 0, 0);", args.fOutputColor);
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index f4ec11d..86df7a0 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -63,7 +63,7 @@
const char* bias = uniformHandler->getUniformCStr(fBiasUni);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppend("half4 sum = half4(0, 0, 0, 0);");
fragBuilder->codeAppendf("float2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset, imgInc);
fragBuilder->codeAppend("half4 c;");
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 01722ee..c9ae676 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -167,7 +167,7 @@
int substringStartIndex = 0;
int formatArgIndex = 0;
SkString coords = args.fTransformedCoords.count()
- ? fragBuilder->ensureCoords2D(args.fTransformedCoords[0])
+ ? fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint)
: SkString("sk_FragCoord");
for (size_t i = 0; i < fGLSL.length(); ++i) {
char c = fGLSL[i];
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 65411f1..4bd1538 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -315,7 +315,8 @@
const GrTextureDomain& domain = tde.fTextureDomain;
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString coords2D =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fGLDomain.sampleTexture(fragBuilder,
args.fUniformHandler,
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 44033ad..a82aec7 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -98,7 +98,7 @@
SkString coords[4];
for (int i = 0; i < numSamplers; ++i) {
- coords[i] = fragBuilder->ensureCoords2D(args.fTransformedCoords[i]);
+ coords[i] = fragBuilder->ensureCoords2D(args.fTransformedCoords[i].fVaryingPoint);
}
for (int i = 0; i < numSamplers; ++i) {
diff --git a/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp
index 8661e24..506cedb 100644
--- a/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp
+++ b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp
@@ -41,7 +41,8 @@
"innerThreshold");
outerThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
"outerThreshold");
- SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_0 =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf(
"half4 color = %s;\nhalf4 mask_color = sample(%s, %s).%s;\nif (mask_color.w < 0.5) "
"{\n if (color.w > %s) {\n half scale = %s / color.w;\n color.xyz "
@@ -50,7 +51,8 @@
"color.w = %s;\n}\n%s = color;\n",
args.fInputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
- sk_TransformedCoords2D_0.c_str(),
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
args.fUniformHandler->getUniformCStr(outerThresholdVar),
args.fUniformHandler->getUniformCStr(outerThresholdVar),
diff --git a/src/gpu/effects/generated/GrMagnifierEffect.cpp b/src/gpu/effects/generated/GrMagnifierEffect.cpp
index 0526e83..4f7a2ea 100644
--- a/src/gpu/effects/generated/GrMagnifierEffect.cpp
+++ b/src/gpu/effects/generated/GrMagnifierEffect.cpp
@@ -47,7 +47,8 @@
kFragment_GrShaderFlag, kFloat_GrSLType, "yInvInset");
offsetVar =
args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "offset");
- SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_0 =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf(
"float2 coord = %s;\nfloat2 zoom_coord = float2(%s) + coord * float2(%s, "
"%s);\nfloat2 delta = (coord - %s.xy) * %s.zw;\ndelta = min(delta, "
@@ -56,7 +57,8 @@
"- delta;\n float dist = length(delta);\n dist = max(2.0 - dist, 0.0);\n "
"weight = min(dist * dist, 1.0);\n} else {\n float2 delta_squared = delta * "
"delta;\n weight = min(min(delta_squared.x, delta_square",
- sk_TransformedCoords2D_0.c_str(),
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
args.fUniformHandler->getUniformCStr(offsetVar),
args.fUniformHandler->getUniformCStr(xInvZoomVar),
args.fUniformHandler->getUniformCStr(yInvZoomVar),
diff --git a/src/gpu/effects/generated/GrMixerEffect.cpp b/src/gpu/effects/generated/GrMixerEffect.cpp
index 9914d3a..88ca234 100644
--- a/src/gpu/effects/generated/GrMixerEffect.cpp
+++ b/src/gpu/effects/generated/GrMixerEffect.cpp
@@ -27,14 +27,14 @@
(void)weight;
weightVar =
args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "weight");
- SkString _input0 = SkStringPrintf("%s", args.fInputColor);
+ SkString _input1278 = SkStringPrintf("%s", args.fInputColor);
SkString _sample1278("_sample1278");
- this->invokeChild(_outer.fp0_index, _input0.c_str(), &_sample1278, args);
+ this->invokeChild(_outer.fp0_index, _input1278.c_str(), &_sample1278, args);
fragBuilder->codeAppendf("half4 in0 = %s;", _sample1278.c_str());
- SkString _input1 = SkStringPrintf("%s", args.fInputColor);
+ SkString _input1335 = SkStringPrintf("%s", args.fInputColor);
SkString _sample1335("_sample1335");
if (_outer.fp1_index >= 0) {
- this->invokeChild(_outer.fp1_index, _input1.c_str(), &_sample1335, args);
+ this->invokeChild(_outer.fp1_index, _input1335.c_str(), &_sample1335, args);
} else {
fragBuilder->codeAppendf("half4 %s;", _sample1335.c_str());
}
diff --git a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
index 852111d..56a55dc 100644
--- a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
+++ b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
@@ -42,9 +42,9 @@
: "half4(0)",
_outer.literalColor.fR, _outer.literalColor.fG, _outer.literalColor.fB,
_outer.literalColor.fA);
- SkString _input0("constColor");
+ SkString _input1992("constColor");
SkString _sample1992("_sample1992");
- this->invokeChild(_outer.fp_index, _input0.c_str(), &_sample1992, args);
+ this->invokeChild(_outer.fp_index, _input1992.c_str(), &_sample1992, args);
fragBuilder->codeAppendf("\n%s = %s;\n", args.fOutputColor, _sample1992.c_str());
}
diff --git a/src/gpu/effects/generated/GrSimpleTextureEffect.cpp b/src/gpu/effects/generated/GrSimpleTextureEffect.cpp
index 693c5f6..5f57e2e 100644
--- a/src/gpu/effects/generated/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/generated/GrSimpleTextureEffect.cpp
@@ -25,11 +25,13 @@
(void)_outer;
auto matrix = _outer.matrix;
(void)matrix;
- SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_0 =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf(
"%s = %s * sample(%s, %s).%s;\n", args.fOutputColor, args.fInputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
- sk_TransformedCoords2D_0.c_str(),
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
}
diff --git a/src/gpu/gl/GrGLUniformHandler.h b/src/gpu/gl/GrGLUniformHandler.h
index 829e016..817be54 100644
--- a/src/gpu/gl/GrGLUniformHandler.h
+++ b/src/gpu/gl/GrGLUniformHandler.h
@@ -38,6 +38,10 @@
int arrayCount,
const char** outName) override;
+ void updateUniformVisibility(UniformHandle u, uint32_t visibility) override {
+ fUniforms[u.toIndex()].fVisibility |= visibility;
+ }
+
SamplerHandle addSampler(const GrTexture*, const GrSamplerState&, const GrSwizzle&,
const char* name, const GrShaderCaps*) override;
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index dec2c96..e5e97de 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "src/gpu/GrCoordTransform.h"
#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
@@ -16,15 +17,36 @@
this->onSetData(pdman, processor);
}
-void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor, EmitArgs& args) {
+void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor, EmitArgs& args,
+ SkSL::String skslCoords) {
while (childIndex >= (int) fFunctionNames.size()) {
fFunctionNames.emplace_back();
}
- this->internalInvokeChild(childIndex, inputColor, args.fOutputColor, args);
+ this->internalInvokeChild(childIndex, inputColor, args.fOutputColor, args, skslCoords);
+}
+
+void GrGLSLFragmentProcessor::writeChildCall(GrGLSLFPFragmentBuilder* fragBuilder, int childIndex,
+ TransformedCoordVars coordVars, const char* inputColor,
+ const char* outputColor, EmitArgs& args,
+ SkSL::String skslCoords) {
+ std::vector<SkString> coordParams;
+ for (int i = 0; i < coordVars.count(); ++i) {
+ coordParams.push_back(fragBuilder->ensureCoords2D(coordVars[i].fVaryingPoint));
+ }
+ // if the fragment processor is invoked with overridden coordinates, it must *always* be invoked
+ // with overridden coords
+ SkASSERT(args.fFp.computeLocalCoordsInVertexShader() == (skslCoords.length() == 0));
+ fragBuilder->codeAppendf("%s = %s(%s", outputColor, fFunctionNames[childIndex].c_str(),
+ inputColor ? inputColor : "half4(1)");
+ if (skslCoords.length()) {
+ fragBuilder->codeAppendf(", %s", skslCoords.c_str());
+ }
+ fragBuilder->codeAppend(");\n");
}
void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor,
- SkString* outputColor, EmitArgs& args) {
+ SkString* outputColor, EmitArgs& args,
+ SkSL::String skslCoords) {
SkASSERT(outputColor);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
outputColor->append(fragBuilder->getMangleString());
@@ -32,17 +54,32 @@
while (childIndex >= (int) fFunctionNames.size()) {
fFunctionNames.emplace_back();
}
+ if (!args.fFp.computeLocalCoordsInVertexShader() && skslCoords.length() == 0) {
+ skslCoords = "_coords";
+ }
if (fFunctionNames[childIndex].size() == 0) {
- this->internalInvokeChild(childIndex, inputColor, outputColor->c_str(), args);
+ this->internalInvokeChild(childIndex, inputColor, outputColor->c_str(), args, skslCoords);
} else {
- fragBuilder->codeAppendf("%s = %s(%s);", outputColor->c_str(),
- fFunctionNames[childIndex].c_str(),
- inputColor ? inputColor : "half4(1)");
+ const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
+
+ TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
+ TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
+ EmitArgs childArgs(fragBuilder,
+ args.fUniformHandler,
+ args.fShaderCaps,
+ childProc,
+ outputColor->c_str(),
+ "_input",
+ coordVars,
+ textureSamplers);
+ this->writeChildCall(fragBuilder, childIndex, coordVars, inputColor, outputColor->c_str(),
+ childArgs, skslCoords);
}
}
void GrGLSLFragmentProcessor::internalInvokeChild(int childIndex, const char* inputColor,
- const char* outputColor, EmitArgs& args) {
+ const char* outputColor, EmitArgs& args,
+ SkSL::String skslCoords) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated
@@ -59,7 +96,6 @@
}
const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
-
TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
@@ -74,11 +110,8 @@
fFunctionNames[childIndex] = fragBuilder->writeProcessorFunction(
this->childProcessor(childIndex),
childArgs);
- fragBuilder->codeAppendf("%s = %s(%s);\n", outputColor,
- fFunctionNames[childIndex].c_str(),
- inputName.size() > 0 ? inputName.c_str()
- : "half4(1)");
-
+ this->writeChildCall(fragBuilder, childIndex, coordVars, inputColor, outputColor, childArgs,
+ skslCoords);
fragBuilder->onAfterChildProcEmitCode();
}
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index c9971a2..ad441d8 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -10,8 +10,10 @@
#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrShaderVar.h"
+#include "src/gpu/glsl/GrGLSLPrimitiveProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
+#include "src/sksl/SkSLString.h"
class GrProcessor;
class GrProcessorKeyBuilder;
@@ -69,8 +71,8 @@
};
public:
- using TransformedCoordVars =
- BuilderInputProvider<GrShaderVar, &GrFragmentProcessor::numCoordTransforms>;
+ using TransformedCoordVars = BuilderInputProvider<GrGLSLPrimitiveProcessor::TransformVar,
+ &GrFragmentProcessor::numCoordTransforms>;
using TextureSamplers =
BuilderInputProvider<SamplerHandle, &GrFragmentProcessor::numTextureSamplers>;
@@ -137,8 +139,9 @@
}
// Invoke the child with the default input color (solid white)
- inline void invokeChild(int childIndex, SkString* outputColor, EmitArgs& parentArgs) {
- this->invokeChild(childIndex, nullptr, outputColor, parentArgs);
+ inline void invokeChild(int childIndex, SkString* outputColor, EmitArgs& parentArgs,
+ SkSL::String skslCoords = "") {
+ this->invokeChild(childIndex, nullptr, outputColor, parentArgs, skslCoords);
}
/** Invokes a child proc in its own scope. Pass in the parent's EmitArgs and invokeChild will
@@ -150,17 +153,18 @@
* color.
*/
void invokeChild(int childIndex, const char* inputColor, SkString* outputColor,
- EmitArgs& parentArgs);
+ EmitArgs& parentArgs, SkSL::String skslCoords = "");
// Use the parent's output color to hold child's output, and use the
// default input color of solid white
- inline void invokeChild(int childIndex, EmitArgs& args) {
+ inline void invokeChild(int childIndex, EmitArgs& args, SkSL::String skslCoords = "") {
// null pointer cast required to disambiguate the function call
- this->invokeChild(childIndex, (const char*) nullptr, args);
+ this->invokeChild(childIndex, (const char*) nullptr, args, skslCoords);
}
/** Variation that uses the parent's output color variable to hold the child's output.*/
- void invokeChild(int childIndex, const char* inputColor, EmitArgs& parentArgs);
+ void invokeChild(int childIndex, const char* inputColor, EmitArgs& parentArgs,
+ SkSL::String skslCoords = "");
/**
* Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
@@ -189,7 +193,12 @@
virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
private:
- void internalInvokeChild(int, const char*, const char*, EmitArgs&);
+ void writeChildCall(GrGLSLFPFragmentBuilder* fragBuilder, int childIndex,
+ TransformedCoordVars coordVars, const char* inputColor,
+ const char* outputColor, EmitArgs& args,
+ SkSL::String skslCoords);
+
+ void internalInvokeChild(int, const char*, const char*, EmitArgs&, SkSL::String);
// one per child; either not present or empty string if not yet emitted
SkTArray<SkString> fFunctionNames;
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index 4590d57..877a742 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -160,15 +160,27 @@
GrGLSLFragmentProcessor::EmitArgs& args) {
this->onBeforeChildProcEmitCode();
this->nextStage();
+ if (!args.fFp.computeLocalCoordsInVertexShader() && args.fTransformedCoords.count() > 0) {
+ // we currently only support overriding a single coordinate pair
+ SkASSERT(args.fTransformedCoords.count() == 1);
+ const GrGLSLProgramDataManager::UniformHandle& mat =
+ args.fTransformedCoords[0].fUniformMatrix;
+ if (mat.isValid()) {
+ args.fUniformHandler->updateUniformVisibility(mat, kFragment_GrShaderFlag);
+ this->codeAppendf("_coords = (float3(_coords, 1) * %s).xy;\n",
+ args.fTransformedCoords[0].fMatrixCode.c_str());
+ }
+ }
this->codeAppendf("half4 %s;\n", args.fOutputColor);
fp->emitCode(args);
- this->codeAppendf("return %s;", args.fOutputColor);
- GrShaderVar inColor(args.fInputColor, kHalf4_GrSLType);
+ this->codeAppendf("return %s;\n", args.fOutputColor);
+ GrShaderVar params[] = { GrShaderVar(args.fInputColor, kHalf4_GrSLType),
+ GrShaderVar("_coords", kFloat2_GrSLType) };
SkString result;
this->emitFunction(kHalf4_GrSLType,
"stage",
- 1,
- &inColor,
+ args.fFp.computeLocalCoordsInVertexShader() ? 1 : 2,
+ params,
this->code().c_str(),
&result);
this->deleteStage();
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index af9bd5c..d99239e 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -84,15 +84,18 @@
SkString strVaryingName;
strVaryingName.printf("TransformedCoords_%d", i);
GrGLSLVarying v(varyingType);
- varyingHandler->addVarying(strVaryingName.c_str(), &v);
+ if (coordTransform->computeInVertexShader()) {
+ varyingHandler->addVarying(strVaryingName.c_str(), &v);
- handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
-
- if (kFloat2_GrSLType == varyingType) {
- vb->codeAppendf("%s = (%s * %s).xy;", v.vsOut(), uniName, localCoords.c_str());
- } else {
- vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, localCoords.c_str());
+ if (kFloat2_GrSLType == varyingType) {
+ vb->codeAppendf("%s = (%s * %s).xy;", v.vsOut(), uniName, localCoords.c_str());
+ } else {
+ vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, localCoords.c_str());
+ }
}
+ handler->specifyCoordsForCurrCoordTransform(SkString(uniName),
+ fInstalledTransforms.back().fHandle,
+ GrShaderVar(SkString(v.fsIn()), varyingType));
++i;
}
}
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
index 5c02647..12fb74f 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
@@ -23,12 +23,29 @@
class GrGLSLPrimitiveProcessor {
public:
+ using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
using FPCoordTransformIter = GrFragmentProcessor::CoordTransformIter;
- virtual ~GrGLSLPrimitiveProcessor() {}
+ struct TransformVar {
+ TransformVar() = default;
- using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
- using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ TransformVar(SkString matrixCode, UniformHandle uniformMatrix, GrShaderVar varyingPoint)
+ : fMatrixCode(std::move(matrixCode))
+ , fUniformMatrix(uniformMatrix)
+ , fVaryingPoint(varyingPoint) {}
+
+ // a string of SkSL code which resolves to the transformation matrix
+ SkString fMatrixCode;
+ // the variable containing the matrix, if any, otherwise an invalid handle
+ UniformHandle fUniformMatrix;
+ // the transformed coordinate output by the vertex shader and consumed by the fragment
+ // shader
+ GrShaderVar fVaryingPoint;
+ };
+
+
+ virtual ~GrGLSLPrimitiveProcessor() {}
/**
* This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
@@ -40,7 +57,7 @@
class FPCoordTransformHandler : public SkNoncopyable {
public:
FPCoordTransformHandler(const GrPipeline& pipeline,
- SkTArray<GrShaderVar>* transformedCoordVars)
+ SkTArray<TransformVar>* transformedCoordVars)
: fIter(pipeline)
, fTransformedCoordVars(transformedCoordVars) {}
@@ -60,7 +77,7 @@
GrFragmentProcessor::CoordTransformIter fIter;
SkDEBUGCODE(bool fAddedCoord = false;)
SkDEBUGCODE(const GrCoordTransform* fCurr = nullptr;)
- SkTArray<GrShaderVar>* fTransformedCoordVars;
+ SkTArray<TransformVar>* fTransformedCoordVars;
};
struct EmitArgs {
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index fb90fc7..c71071b 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -196,7 +196,8 @@
}
}
- const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
+ const GrGLSLPrimitiveProcessor::TransformVar* coordVars = fTransformedCoordVars.begin() +
+ transformedCoordVarsIdx;
GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, texSamplers.begin());
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 44db251..9f5e3a3 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -169,8 +169,8 @@
#endif
// These are used to check that we don't excede the allowable number of resources in a shader.
- int fNumFragmentSamplers;
- SkSTArray<4, GrShaderVar> fTransformedCoordVars;
+ int fNumFragmentSamplers;
+ SkSTArray<4, GrGLSLPrimitiveProcessor::TransformVar> fTransformedCoordVars;
};
#endif
diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h
index 3380e70..c3232cd 100644
--- a/src/gpu/glsl/GrGLSLUniformHandler.h
+++ b/src/gpu/glsl/GrGLSLUniformHandler.h
@@ -64,6 +64,11 @@
virtual const GrShaderVar& getUniformVariable(UniformHandle u) const = 0;
/**
+ * 'Or's the visibility parameter with the current uniform visibililty.
+ */
+ virtual void updateUniformVisibility(UniformHandle u, uint32_t visibility) = 0;
+
+ /**
* Shortcut for getUniformVariable(u).c_str()
*/
virtual const char* getUniformCStr(UniformHandle u) const = 0;
diff --git a/src/gpu/gradients/generated/GrClampedGradientEffect.cpp b/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
index 658f6b8..268fc6f 100644
--- a/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
+++ b/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
@@ -46,9 +46,9 @@
args.fOutputColor, args.fOutputColor,
args.fUniformHandler->getUniformCStr(leftBorderColorVar), args.fOutputColor,
args.fUniformHandler->getUniformCStr(rightBorderColorVar));
- SkString _input0("t");
+ SkString _input1767("t");
SkString _sample1767("_sample1767");
- this->invokeChild(_outer.colorizer_index, _input0.c_str(), &_sample1767, args);
+ this->invokeChild(_outer.colorizer_index, _input1767.c_str(), &_sample1767, args);
fragBuilder->codeAppendf("\n %s = %s;\n}\n@if (%s) {\n %s.xyz *= %s.w;\n}\n",
args.fOutputColor, _sample1767.c_str(),
(_outer.makePremul ? "true" : "false"), args.fOutputColor,
diff --git a/src/gpu/gradients/generated/GrLinearGradientLayout.cpp b/src/gpu/gradients/generated/GrLinearGradientLayout.cpp
index 28e7da8..a20b0e5 100644
--- a/src/gpu/gradients/generated/GrLinearGradientLayout.cpp
+++ b/src/gpu/gradients/generated/GrLinearGradientLayout.cpp
@@ -25,10 +25,13 @@
(void)_outer;
auto gradientMatrix = _outer.gradientMatrix;
(void)gradientMatrix;
- SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_0 =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf(
"half t = half(%s.x) + 9.9999997473787516e-06;\n%s = half4(t, 1.0, 0.0, 0.0);\n",
- sk_TransformedCoords2D_0.c_str(), args.fOutputColor);
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ args.fOutputColor);
}
private:
diff --git a/src/gpu/gradients/generated/GrRadialGradientLayout.cpp b/src/gpu/gradients/generated/GrRadialGradientLayout.cpp
index 213be21..f163943 100644
--- a/src/gpu/gradients/generated/GrRadialGradientLayout.cpp
+++ b/src/gpu/gradients/generated/GrRadialGradientLayout.cpp
@@ -25,9 +25,13 @@
(void)_outer;
auto gradientMatrix = _outer.gradientMatrix;
(void)gradientMatrix;
- SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_0 =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf("half t = half(length(%s));\n%s = half4(t, 1.0, 0.0, 0.0);\n",
- sk_TransformedCoords2D_0.c_str(), args.fOutputColor);
+ _outer.computeLocalCoordsInVertexShader()
+ ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ args.fOutputColor);
}
private:
diff --git a/src/gpu/gradients/generated/GrSweepGradientLayout.cpp b/src/gpu/gradients/generated/GrSweepGradientLayout.cpp
index 18b4739..6abcbb1 100644
--- a/src/gpu/gradients/generated/GrSweepGradientLayout.cpp
+++ b/src/gpu/gradients/generated/GrSweepGradientLayout.cpp
@@ -32,15 +32,24 @@
biasVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "bias");
scaleVar =
args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "scale");
- SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_0 =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf(
"half angle;\nif (sk_Caps.atan2ImplementedAsAtanYOverX) {\n angle = half(2.0 * "
"atan(-%s.y, length(%s) - %s.x));\n} else {\n angle = half(atan(-%s.y, "
"-%s.x));\n}\nhalf t = ((angle * 0.15915493667125702 + 0.5) + %s) * %s;\n%s = "
"half4(t, 1.0, 0.0, 0.0);\n",
- sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str(),
- sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str(),
- sk_TransformedCoords2D_0.c_str(), args.fUniformHandler->getUniformCStr(biasVar),
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ args.fUniformHandler->getUniformCStr(biasVar),
args.fUniformHandler->getUniformCStr(scaleVar), args.fOutputColor);
}
diff --git a/src/gpu/gradients/generated/GrTiledGradientEffect.cpp b/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
index 4c85ed6..9d0637f 100644
--- a/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
+++ b/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
@@ -41,9 +41,9 @@
(_outer.childProcessor(_outer.gradLayout_index).preservesOpaqueInput() ? "true"
: "false"),
args.fOutputColor, (_outer.mirror ? "true" : "false"));
- SkString _input0("t");
+ SkString _input1464("t");
SkString _sample1464("_sample1464");
- this->invokeChild(_outer.colorizer_index, _input0.c_str(), &_sample1464, args);
+ this->invokeChild(_outer.colorizer_index, _input1464.c_str(), &_sample1464, args);
fragBuilder->codeAppendf("\n %s = %s;\n}\n@if (%s) {\n %s.xyz *= %s.w;\n}\n",
args.fOutputColor, _sample1464.c_str(),
(_outer.makePremul ? "true" : "false"), args.fOutputColor,
diff --git a/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp b/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp
index 5421d2c..804a42c 100644
--- a/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp
+++ b/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp
@@ -42,7 +42,8 @@
(void)focalParams;
focalParamsVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
"focalParams");
- SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ SkString sk_TransformedCoords2D_0 =
+ fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
fragBuilder->codeAppendf(
"float2 p = %s;\nfloat t = -1.0;\nhalf v = 1.0;\n@switch (%d) {\n case 1:\n "
" {\n half r0_2 = %s.y;\n t = float(r0_2) - p.y * p.y;\n "
@@ -51,8 +52,9 @@
"0:\n {\n half r0 = %s.x;\n @if (%s) {\n "
" t = length(p) - float(r0);\n } else {\n t = "
"-length(p) - float(r0);\n ",
- sk_TransformedCoords2D_0.c_str(), (int)_outer.type,
- args.fUniformHandler->getUniformCStr(focalParamsVar),
+ _outer.computeLocalCoordsInVertexShader() ? sk_TransformedCoords2D_0.c_str()
+ : "_coords",
+ (int)_outer.type, args.fUniformHandler->getUniformCStr(focalParamsVar),
args.fUniformHandler->getUniformCStr(focalParamsVar),
(_outer.isRadiusIncreasing ? "true" : "false"));
fragBuilder->codeAppendf(
diff --git a/src/gpu/mtl/GrMtlUniformHandler.h b/src/gpu/mtl/GrMtlUniformHandler.h
index 407540b..9c789ff 100644
--- a/src/gpu/mtl/GrMtlUniformHandler.h
+++ b/src/gpu/mtl/GrMtlUniformHandler.h
@@ -57,6 +57,10 @@
int arrayCount,
const char** outName) override;
+ void updateUniformVisibility(UniformHandle u, uint32_t visibility) override {
+ fUniforms[u.toIndex()].fVisibility |= visibility;
+ }
+
SamplerHandle addSampler(const GrTexture*,
const GrSamplerState&,
const GrSwizzle&,
diff --git a/src/gpu/vk/GrVkUniformHandler.h b/src/gpu/vk/GrVkUniformHandler.h
index 6e594c8..de6a3e4 100644
--- a/src/gpu/vk/GrVkUniformHandler.h
+++ b/src/gpu/vk/GrVkUniformHandler.h
@@ -73,6 +73,10 @@
int arrayCount,
const char** outName) override;
+ void updateUniformVisibility(UniformHandle u, uint32_t visibility) override {
+ fUniforms[u.toIndex()].fVisibility |= visibility;
+ }
+
SamplerHandle addSampler(const GrTexture* texture,
const GrSamplerState&,
const GrSwizzle&,