Change SampleMatrix to SampleUsage
It now tracks all sample calls of a child (matrix, explicit coords,
pass through). There is now just one registerChild() call, and the
sampling pattern of that child is fully determined by the SampleUsage
parameter.
Change-Id: Iaadcd325fca64a59f24192aadd06923c66362181
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/299875
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index ae0daf0..6dc8bf7 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -93,7 +93,7 @@
size_t offset = 0, uniformSize = 0;
std::vector<Variable> inAndUniformVars;
std::vector<SkString> children;
- std::vector<SkSL::SampleMatrix> sampleMatrices;
+ std::vector<SkSL::SampleUsage> sampleUsages;
std::vector<Varying> varyings;
const SkSL::Context& ctx(compiler->context());
@@ -138,8 +138,7 @@
if (var.fModifiers.fFlags & flag) {
if (&var.fType == ctx.fFragmentProcessor_Type.get()) {
children.push_back(var.fName);
- sampleMatrices.push_back(
- SkSL::Analysis::GetSampleMatrix(*program, var));
+ sampleUsages.push_back(SkSL::Analysis::GetSampleUsage(*program, var));
continue;
}
@@ -264,7 +263,7 @@
std::move(program),
std::move(inAndUniformVars),
std::move(children),
- std::move(sampleMatrices),
+ std::move(sampleUsages),
std::move(varyings),
uniformSize,
mainHasSampleCoords));
@@ -294,7 +293,7 @@
std::unique_ptr<SkSL::Program> baseProgram,
std::vector<Variable>&& inAndUniformVars,
std::vector<SkString>&& children,
- std::vector<SkSL::SampleMatrix>&& sampleMatrices,
+ std::vector<SkSL::SampleUsage>&& sampleUsages,
std::vector<Varying>&& varyings,
size_t uniformSize,
bool mainHasSampleCoords)
@@ -303,14 +302,14 @@
, fBaseProgram(std::move(baseProgram))
, fInAndUniformVars(std::move(inAndUniformVars))
, fChildren(std::move(children))
- , fSampleMatrices(std::move(sampleMatrices))
+ , fSampleUsages(std::move(sampleUsages))
, fVaryings(std::move(varyings))
, fUniformSize(uniformSize)
, fMainFunctionHasSampleCoords(mainHasSampleCoords) {
SkASSERT(fBaseProgram);
SkASSERT(SkIsAlign4(fUniformSize));
SkASSERT(fUniformSize <= this->inputSize());
- SkASSERT(fChildren.size() == fSampleMatrices.size());
+ SkASSERT(fChildren.size() == fSampleUsages.size());
}
SkRuntimeEffect::~SkRuntimeEffect() = default;
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 39b7062..06ea770 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -308,7 +308,7 @@
// Not bothering with table-specific optimizations.
: INHERITED(kColorTableEffect_ClassID, kNone_OptimizationFlags) {
auto te = GrTextureEffect::Make(std::move(view), kUnknown_SkAlphaType);
- this->registerExplicitlySampledChild(std::move(te));
+ this->registerChild(std::move(te), SkSL::SampleUsage::Explicit());
}
ColorTableEffect::ColorTableEffect(const ColorTableEffect& that)
diff --git a/src/effects/imagefilters/SkDisplacementMapEffect.cpp b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
index d50d2ad..015a0b7 100644
--- a/src/effects/imagefilters/SkDisplacementMapEffect.cpp
+++ b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
@@ -506,7 +506,7 @@
, fYChannelSelector(yChannelSelector)
, fScale(scale) {
this->registerChild(std::move(displacement));
- this->registerExplicitlySampledChild(std::move(color));
+ this->registerChild(std::move(color), SkSL::SampleUsage::Explicit());
this->setUsesSampleCoordsDirectly();
}
diff --git a/src/effects/imagefilters/SkLightingImageFilter.cpp b/src/effects/imagefilters/SkLightingImageFilter.cpp
index 4b3232b..c243592 100644
--- a/src/effects/imagefilters/SkLightingImageFilter.cpp
+++ b/src/effects/imagefilters/SkLightingImageFilter.cpp
@@ -1629,7 +1629,7 @@
child = GrTextureEffect::Make(std::move(view), kPremul_SkAlphaType, SkMatrix::I(), kSampler,
caps);
}
- this->registerExplicitlySampledChild(std::move(child));
+ this->registerChild(std::move(child), SkSL::SampleUsage::Explicit());
this->setUsesSampleCoordsDirectly();
}
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index bdeb6e3..c6aa8c4 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -340,7 +340,7 @@
, fUseRange(SkToBool(range)) {
this->setUsesSampleCoordsDirectly();
auto te = GrTextureEffect::Make(std::move(view), srcAlphaType);
- this->registerExplicitlySampledChild(std::move(te));
+ this->registerChild(std::move(te), SkSL::SampleUsage::Explicit());
if (fUseRange) {
fRange[0] = range[0];
fRange[1] = range[1];
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index f358a47..a6c7cc6 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -71,7 +71,7 @@
int GrFragmentProcessor::numCoordTransforms() const {
if (SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) && !this->isSampledWithExplicitCoords()) {
// coordTransform(0) will return an implicitly defined coord transform so that varyings are
- // added for this FP in order to support const/uniform sample matrix lifting.
+ // added for this FP in order to support uniform sample matrix lifting.
return 1;
} else {
return 0;
@@ -87,23 +87,6 @@
return kImplicitIdentity;
}
-void GrFragmentProcessor::setSampleMatrix(SkSL::SampleMatrix newMatrix) {
- SkASSERT(!newMatrix.isNoOp());
- SkASSERT(fMatrix.isNoOp());
-
- fMatrix = newMatrix;
- // When an FP is sampled using variable matrix expressions, it is effectively being sampled
- // explicitly, except that the call site will automatically evaluate the matrix expression to
- // produce the float2 passed into this FP.
- if (fMatrix.isVariable()) {
- this->addAndPushFlagToChildren(kSampledWithExplicitCoords_Flag);
- }
- // Push perspective matrix type to children
- if (fMatrix.fHasPerspective) {
- this->addAndPushFlagToChildren(kNetTransformHasPerspective_Flag);
- }
-}
-
void GrFragmentProcessor::addAndPushFlagToChildren(PrivateFlags flag) {
// This propagates down, so if we've already marked it, all our children should have it too
if (!(fFlags & flag)) {
@@ -138,24 +121,35 @@
#endif
int GrFragmentProcessor::registerChild(std::unique_ptr<GrFragmentProcessor> child,
- SkSL::SampleMatrix sampleMatrix,
- bool explicitlySampled) {
+ SkSL::SampleUsage sampleUsage) {
// The child should not have been attached to another FP already and not had any sampling
// strategy set on it.
- SkASSERT(child && !child->fParent && child->sampleMatrix().isNoOp() &&
+ SkASSERT(child && !child->fParent && !child->sampleUsage().isSampled() &&
!child->isSampledWithExplicitCoords() && !child->hasPerspectiveTransform());
+ // If a child is sampled directly (sample(child)), and with a single uniform matrix, we need to
+ // treat it as if it were sampled with multiple matrices (eg variable).
+ bool variableMatrix = sampleUsage.hasVariableMatrix() ||
+ (sampleUsage.fPassThrough && sampleUsage.hasUniformMatrix());
+
// Configure child's sampling state first
- if (explicitlySampled) {
+ child->fUsage = sampleUsage;
+
+ // When an FP is sampled using variable matrix expressions, it is effectively being sampled
+ // explicitly, except that the call site will automatically evaluate the matrix expression to
+ // produce the float2 passed into this FP.
+ if (sampleUsage.fExplicitCoords || variableMatrix) {
child->addAndPushFlagToChildren(kSampledWithExplicitCoords_Flag);
}
- if (sampleMatrix.fKind != SkSL::SampleMatrix::Kind::kNone) {
- child->setSampleMatrix(sampleMatrix);
+
+ // Push perspective matrix type to children
+ if (sampleUsage.fHasPerspective) {
+ child->addAndPushFlagToChildren(kNetTransformHasPerspective_Flag);
}
- if (child->sampleMatrix().fKind == SkSL::SampleMatrix::Kind::kVariable) {
- // Since the child is sampled with a variable matrix expression, auto-generated code in
- // invokeChildWithMatrix() for this FP will refer to the local coordinates.
+ // If the child is sampled with a variable matrix expression, auto-generated code in
+ // invokeChildWithMatrix() for this FP will refer to the local coordinates.
+ if (variableMatrix) {
this->setUsesSampleCoordsDirectly();
}
@@ -181,14 +175,13 @@
// Sanity check: our sample strategy comes from a parent we shouldn't have yet.
SkASSERT(!this->isSampledWithExplicitCoords() && !this->hasPerspectiveTransform() &&
- fMatrix.isNoOp() && !fParent);
+ !fUsage.isSampled() && !fParent);
return index;
}
int GrFragmentProcessor::cloneAndRegisterChildProcessor(const GrFragmentProcessor& fp) {
std::unique_ptr<GrFragmentProcessor> clone = fp.clone();
- return this->registerChild(std::move(clone), fp.sampleMatrix(),
- fp.isSampledWithExplicitCoords());
+ return this->registerChild(std::move(clone), fp.sampleUsage());
}
void GrFragmentProcessor::cloneAndRegisterAllChildProcessors(const GrFragmentProcessor& src) {
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 17cba88..fc2360a 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -10,7 +10,7 @@
#include <tuple>
-#include "include/private/SkSLSampleMatrix.h"
+#include "include/private/SkSLSampleUsage.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/ops/GrOp.h"
@@ -171,10 +171,10 @@
return SkToBool(fFlags & kNetTransformHasPerspective_Flag);
}
- // The SampleMatrix describing how this FP is invoked by its parent using 'sample(matrix)'
+ // The SampleUsage describing how this FP is invoked by its parent using 'sample(matrix)'
// This only reflects the immediate sampling from parent to this FP
- const SkSL::SampleMatrix& sampleMatrix() const {
- return fMatrix;
+ const SkSL::SampleUsage& sampleUsage() const {
+ return fUsage;
}
/**
@@ -397,27 +397,14 @@
* FragmentProcessors they have. This must be called AFTER all texture accesses and coord
* transforms have been added.
* This is for processors whose shader code will be composed of nested processors whose output
- * colors will be combined somehow to produce its output color. Registering these child
+ * colors will be combined somehow to produce its output color. Registering these child
* processors will allow the ProgramBuilder to automatically handle their transformed coords and
* texture accesses and mangle their uniform and output color names.
*
- * Depending on the 2nd and 3rd parameters, this corresponds to the following SkSL sample calls:
- * - sample(child): Keep default arguments
- * - sample(child, matrix): Provide approprate SampleMatrix matching SkSL
- * - sample(child, float2): SampleMatrix() and 'true', or use 'registerExplicitlySampledChild'
- * - sample(child, matrix)+sample(child, float2): Appropriate SampleMatrix and 'true'
+ * The SampleUsage parameter describes all of the ways that the child is sampled by the parent.
*/
int registerChild(std::unique_ptr<GrFragmentProcessor> child,
- SkSL::SampleMatrix sampleMatrix = SkSL::SampleMatrix(),
- bool explicitlySampled = false);
-
- /**
- * A helper for use when the child is only invoked with sample(float2), and not sample()
- * or sample(matrix).
- */
- int registerExplicitlySampledChild(std::unique_ptr<GrFragmentProcessor> child) {
- return this->registerChild(std::move(child), SkSL::SampleMatrix(), true);
- }
+ SkSL::SampleUsage sampleUsage = SkSL::SampleUsage::PassThrough());
/**
* This method takes an existing fragment processor, clones it, registers it as a child of this
@@ -482,8 +469,6 @@
bool hasSameTransforms(const GrFragmentProcessor&) const;
- void setSampleMatrix(SkSL::SampleMatrix matrix);
-
enum PrivateFlags {
kFirstPrivateFlag = kAll_OptimizationFlags + 1,
@@ -505,7 +490,7 @@
SkSTArray<1, std::unique_ptr<GrFragmentProcessor>, true> fChildProcessors;
const GrFragmentProcessor* fParent = nullptr;
- SkSL::SampleMatrix fMatrix;
+ SkSL::SampleUsage fUsage;
typedef GrProcessor INHERITED;
};
diff --git a/src/gpu/GrPrimitiveProcessor.cpp b/src/gpu/GrPrimitiveProcessor.cpp
index ca384f0..6a844da 100644
--- a/src/gpu/GrPrimitiveProcessor.cpp
+++ b/src/gpu/GrPrimitiveProcessor.cpp
@@ -15,17 +15,17 @@
* the transform code is applied.
*/
enum SampleFlag {
- kExplicitlySampled_Flag = 0b00001, // GrFP::isSampledWithExplicitCoords()
+ kExplicitlySampled_Flag = 0b00001, // GrFP::isSampledWithExplicitCoords()
- kLegacyCoordTransform_Flag = 0b00010, // !GrFP::coordTransform(i)::isNoOp()
+ kLegacyCoordTransform_Flag = 0b00010, // !GrFP::coordTransform(i)::isNoOp()
- kNone_SampleMatrix_Flag = 0b00100, // GrFP::sampleMatrix()::isNoOp()
- kConstUniform_SampleMatrix_Flag = 0b01000, // GrFP::sampleMatrix()::isConstUniform()
- kVariable_SampleMatrix_Flag = 0b01100, // GrFP::sampleMatrix()::isVariable()
+ kNone_SampleMatrix_Flag = 0b00100, // GrFP::sampleUsage()::hasMatrix() == false
+ kUniform_SampleMatrix_Flag = 0b01000, // GrFP::sampleUsage()::hasUniformMatrix()
+ kVariable_SampleMatrix_Flag = 0b01100, // GrFP::sampleUsage()::hasVariableMatrix()
// Currently, sample(matrix) only specializes on no-perspective or general.
// FIXME add new flags as more matrix types are supported.
- kPersp_Matrix_Flag = 0b10000, // GrFP::sampleMatrix()::fHasPerspective
+ kPersp_Matrix_Flag = 0b10000, // GrFP::sampleUsage()::fHasPerspective
};
GrPrimitiveProcessor::GrPrimitiveProcessor(ClassID classID) : GrProcessor(classID) {}
@@ -47,18 +47,18 @@
key |= kExplicitlySampled_Flag;
}
- switch(fp.sampleMatrix().fKind) {
- case SkSL::SampleMatrix::Kind::kNone:
+ switch(fp.sampleUsage().fKind) {
+ case SkSL::SampleUsage::Kind::kNone:
key |= kNone_SampleMatrix_Flag;
break;
- case SkSL::SampleMatrix::Kind::kConstantOrUniform:
- key |= kConstUniform_SampleMatrix_Flag;
+ case SkSL::SampleUsage::Kind::kUniform:
+ key |= kUniform_SampleMatrix_Flag;
break;
- case SkSL::SampleMatrix::Kind::kVariable:
+ case SkSL::SampleUsage::Kind::kVariable:
key |= kVariable_SampleMatrix_Flag;
break;
}
- if (fp.sampleMatrix().fHasPerspective) {
+ if (fp.sampleUsage().fHasPerspective) {
key |= kPersp_Matrix_Flag;
}
diff --git a/src/gpu/ccpr/GrCCClipProcessor.cpp b/src/gpu/ccpr/GrCCClipProcessor.cpp
index 718985a..baa27e9 100644
--- a/src/gpu/ccpr/GrCCClipProcessor.cpp
+++ b/src/gpu/ccpr/GrCCClipProcessor.cpp
@@ -30,7 +30,7 @@
, fMustCheckBounds(MustCheckBounds::kYes == mustCheckBounds) {
auto view = make_view(caps, clipPath->atlasLazyProxy(), fIsCoverageCount);
auto texEffect = GrTextureEffect::Make(std::move(view), kUnknown_SkAlphaType);
- this->registerExplicitlySampledChild(std::move(texEffect));
+ this->registerChild(std::move(texEffect), SkSL::SampleUsage::Explicit());
if (inputFP != nullptr) {
this->registerChild(std::move(inputFP));
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index c607caf..e71faca 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -199,7 +199,7 @@
, fDirection(direction)
, fClamp(clamp) {
this->setUsesSampleCoordsDirectly();
- this->registerExplicitlySampledChild(std::move(fp));
+ this->registerChild(std::move(fp), SkSL::SampleUsage::Explicit());
}
GrBicubicEffect::GrBicubicEffect(const GrBicubicEffect& that)
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
index a8ab80a..55fe393 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
@@ -169,7 +169,7 @@
ProcessorOptimizationFlags(child.get()))
, fRadius(radius)
, fDirection(direction) {
- this->registerExplicitlySampledChild(std::move(child));
+ this->registerChild(std::move(child), SkSL::SampleUsage::Explicit());
SkASSERT(radius <= kMaxKernelRadius);
fill_in_1D_gaussian_kernel(fKernel, gaussianSigma, fRadius);
this->setUsesSampleCoordsDirectly();
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 12443af..6fb6b42 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -292,9 +292,9 @@
, fGain(SkScalarToFloat(gain))
, fBias(SkScalarToFloat(bias) / 255.0f)
, fConvolveAlpha(convolveAlpha) {
- this->registerExplicitlySampledChild(std::move(child));
+ this->registerChild(std::move(child), SkSL::SampleUsage::Explicit());
if (kernelFP) {
- this->registerExplicitlySampledChild(std::move(kernelFP));
+ this->registerChild(std::move(kernelFP), SkSL::SampleUsage::Explicit());
}
fKernelOffset = {static_cast<float>(kernelOffset.x()),
static_cast<float>(kernelOffset.y())};
diff --git a/src/gpu/effects/GrMatrixEffect.h b/src/gpu/effects/GrMatrixEffect.h
index ebc3833..0e6bba0 100644
--- a/src/gpu/effects/GrMatrixEffect.h
+++ b/src/gpu/effects/GrMatrixEffect.h
@@ -20,10 +20,7 @@
if (matrix.isIdentity()) {
return child;
}
- SkASSERT(!child->isSampledWithExplicitCoords());
- SkASSERT(child->sampleMatrix().fKind == SkSL::SampleMatrix::Kind::kNone);
- return std::unique_ptr<GrFragmentProcessor>(
- new GrMatrixEffect(matrix, std::move(child)));
+ return std::unique_ptr<GrFragmentProcessor>(new GrMatrixEffect(matrix, std::move(child)));
}
std::unique_ptr<GrFragmentProcessor> clone() const override;
@@ -38,7 +35,7 @@
, fMatrix(matrix) {
SkASSERT(child);
this->registerChild(std::move(child),
- SkSL::SampleMatrix::MakeConstUniform(
+ SkSL::SampleUsage::UniformMatrix(
"matrix", matrix.hasPerspective()));
}
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index c706f2a..1f9f429 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -52,15 +52,15 @@
}
case SkSL::Compiler::FormatArg::Kind::kChildProcessorWithMatrix: {
const auto& fp(args.fFp.cast<GrSkSLFP>());
- const auto& sampleMatrices(fp.fEffect->fSampleMatrices);
+ const auto& sampleUsages(fp.fEffect->fSampleUsages);
- SkASSERT((size_t)arg.fIndex < sampleMatrices.size());
- const SkSL::SampleMatrix& sampleMatrix(sampleMatrices[arg.fIndex]);
+ SkASSERT((size_t)arg.fIndex < sampleUsages.size());
+ const SkSL::SampleUsage& sampleUsage(sampleUsages[arg.fIndex]);
SkSL::String coords = this->expandFormatArgs(arg.fCoords, args, fmtArg);
result += this->invokeChildWithMatrix(
arg.fIndex, args,
- sampleMatrix.isConstUniform() ? "" : coords)
+ sampleUsage.hasUniformMatrix() ? "" : coords)
.c_str();
break;
}
@@ -200,14 +200,8 @@
void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) {
int childIndex = this->numChildProcessors();
- SkASSERT((size_t)childIndex < fEffect->fSampleMatrices.size());
- const auto& sampleMatrix(fEffect->fSampleMatrices[childIndex]);
- // TODO: This doesn't account for calls to sample(child) with no matrix or explicit coords
- if (sampleMatrix.isNoOp()) {
- this->registerExplicitlySampledChild(std::move(child));
- } else {
- this->registerChild(std::move(child), sampleMatrix);
- }
+ SkASSERT((size_t)childIndex < fEffect->fSampleUsages.size());
+ this->registerChild(std::move(child), fEffect->fSampleUsages[childIndex]);
}
GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 236a9de..c453a3d 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -147,7 +147,7 @@
// Need this so that we can access coords in SKSL to perform snapping.
this->setUsesSampleCoordsDirectly();
for (int i = 0; i < numPlanes; ++i) {
- this->registerExplicitlySampledChild(std::move(planeFPs[i]));
+ this->registerChild(std::move(planeFPs[i]), SkSL::SampleUsage::Explicit());
}
} else {
for (int i = 0; i < numPlanes; ++i) {
diff --git a/src/gpu/effects/generated/GrAARectEffect.h b/src/gpu/effects/generated/GrAARectEffect.h
index 332ec62..a3f0085 100644
--- a/src/gpu/effects/generated/GrAARectEffect.h
+++ b/src/gpu/effects/generated/GrAARectEffect.h
@@ -42,7 +42,8 @@
, edgeType(edgeType)
, rect(rect) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h
index a09909f..780914c 100644
--- a/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h
+++ b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h
@@ -46,10 +46,11 @@
, innerThreshold(innerThreshold)
, outerThreshold(outerThreshold) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
SkASSERT(maskFP);
- maskFP_index = this->registerChild(std::move(maskFP));
+ maskFP_index = this->registerChild(std::move(maskFP), SkSL::SampleUsage::PassThrough());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h b/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h
index 8af063e..2fdc7e7 100644
--- a/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h
+++ b/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h
@@ -35,7 +35,8 @@
: INHERITED(kGrBlurredEdgeFragmentProcessor_ClassID, kNone_OptimizationFlags)
, mode(mode) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h
index 3b17900..c306382 100644
--- a/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h
+++ b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h
@@ -47,10 +47,12 @@
, solidRadius(solidRadius)
, textureRadius(textureRadius) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
SkASSERT(blurProfile);
- blurProfile_index = this->registerExplicitlySampledChild(std::move(blurProfile));
+ blurProfile_index =
+ this->registerChild(std::move(blurProfile), SkSL::SampleUsage::Explicit());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/generated/GrCircleEffect.h b/src/gpu/effects/generated/GrCircleEffect.h
index e77aa6f..0fc1de7 100644
--- a/src/gpu/effects/generated/GrCircleEffect.h
+++ b/src/gpu/effects/generated/GrCircleEffect.h
@@ -51,7 +51,8 @@
, center(center)
, radius(radius) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrClampFragmentProcessor.h b/src/gpu/effects/generated/GrClampFragmentProcessor.h
index b36c22a..e6e2d58 100644
--- a/src/gpu/effects/generated/GrClampFragmentProcessor.h
+++ b/src/gpu/effects/generated/GrClampFragmentProcessor.h
@@ -47,7 +47,8 @@
kPreservesOpaqueInput_OptimizationFlag))
, clampToPremul(clampToPremul) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.h b/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.h
index 5a3c00f..15d0c88 100644
--- a/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.h
+++ b/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.h
@@ -85,7 +85,8 @@
, clampRGBOutput(clampRGBOutput)
, premulOutput(premulOutput) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrComposeLerpEffect.h b/src/gpu/effects/generated/GrComposeLerpEffect.h
index f43b484..1a7fdf6 100644
--- a/src/gpu/effects/generated/GrComposeLerpEffect.h
+++ b/src/gpu/effects/generated/GrComposeLerpEffect.h
@@ -37,10 +37,10 @@
float weight)
: INHERITED(kGrComposeLerpEffect_ClassID, kNone_OptimizationFlags), weight(weight) {
if (child1) {
- child1_index = this->registerChild(std::move(child1));
+ child1_index = this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());
}
if (child2) {
- child2_index = this->registerChild(std::move(child2));
+ child2_index = this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrConstColorProcessor.h b/src/gpu/effects/generated/GrConstColorProcessor.h
index 2394bf0..0e3d6ea 100644
--- a/src/gpu/effects/generated/GrConstColorProcessor.h
+++ b/src/gpu/effects/generated/GrConstColorProcessor.h
@@ -73,7 +73,8 @@
, color(color)
, mode(mode) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrDeviceSpaceEffect.h b/src/gpu/effects/generated/GrDeviceSpaceEffect.h
index dd4d4f7..bd40d38 100644
--- a/src/gpu/effects/generated/GrDeviceSpaceEffect.h
+++ b/src/gpu/effects/generated/GrDeviceSpaceEffect.h
@@ -35,7 +35,7 @@
: INHERITED(kGrDeviceSpaceEffect_ClassID,
(OptimizationFlags)ProcessorOptimizationFlags(fp.get())) {
SkASSERT(fp);
- fp_index = this->registerExplicitlySampledChild(std::move(fp));
+ fp_index = this->registerChild(std::move(fp), SkSL::SampleUsage::Explicit());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/generated/GrEllipseEffect.h b/src/gpu/effects/generated/GrEllipseEffect.h
index 28df4ee..8726651 100644
--- a/src/gpu/effects/generated/GrEllipseEffect.h
+++ b/src/gpu/effects/generated/GrEllipseEffect.h
@@ -61,7 +61,8 @@
, center(center)
, radii(radii) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrHSLToRGBFilterEffect.h b/src/gpu/effects/generated/GrHSLToRGBFilterEffect.h
index 912ed1b..f346a4d 100644
--- a/src/gpu/effects/generated/GrHSLToRGBFilterEffect.h
+++ b/src/gpu/effects/generated/GrHSLToRGBFilterEffect.h
@@ -50,7 +50,8 @@
(kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrLumaColorFilterEffect.h b/src/gpu/effects/generated/GrLumaColorFilterEffect.h
index 624587b..301df9c 100644
--- a/src/gpu/effects/generated/GrLumaColorFilterEffect.h
+++ b/src/gpu/effects/generated/GrLumaColorFilterEffect.h
@@ -45,7 +45,8 @@
: kAll_OptimizationFlags) &
kConstantOutputForConstantInput_OptimizationFlag) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrMagnifierEffect.h b/src/gpu/effects/generated/GrMagnifierEffect.h
index 8cee43e..86f6ecc 100644
--- a/src/gpu/effects/generated/GrMagnifierEffect.h
+++ b/src/gpu/effects/generated/GrMagnifierEffect.h
@@ -56,7 +56,7 @@
, yInvInset(yInvInset) {
this->setUsesSampleCoordsDirectly();
SkASSERT(src);
- src_index = this->registerExplicitlySampledChild(std::move(src));
+ src_index = this->registerChild(std::move(src), SkSL::SampleUsage::Explicit());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/generated/GrMixerEffect.h b/src/gpu/effects/generated/GrMixerEffect.h
index e44ab56..24c4d34 100644
--- a/src/gpu/effects/generated/GrMixerEffect.h
+++ b/src/gpu/effects/generated/GrMixerEffect.h
@@ -55,9 +55,9 @@
: INHERITED(kGrMixerEffect_ClassID, (OptimizationFlags)OptFlags(fp0, fp1))
, weight(weight) {
SkASSERT(fp0);
- fp0_index = this->registerChild(std::move(fp0));
+ fp0_index = this->registerChild(std::move(fp0), SkSL::SampleUsage::PassThrough());
if (fp1) {
- fp1_index = this->registerChild(std::move(fp1));
+ fp1_index = this->registerChild(std::move(fp1), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h
index 620bded..e5c1280 100644
--- a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h
+++ b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h
@@ -60,7 +60,7 @@
, uniformColor(uniformColor)
, literalColor(literalColor) {
SkASSERT(fp);
- fp_index = this->registerChild(std::move(fp));
+ fp_index = this->registerChild(std::move(fp), SkSL::SampleUsage::PassThrough());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/generated/GrRGBToHSLFilterEffect.h b/src/gpu/effects/generated/GrRGBToHSLFilterEffect.h
index fdcfbb7..cafb605 100644
--- a/src/gpu/effects/generated/GrRGBToHSLFilterEffect.h
+++ b/src/gpu/effects/generated/GrRGBToHSLFilterEffect.h
@@ -52,7 +52,8 @@
(kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.h b/src/gpu/effects/generated/GrRRectBlurEffect.h
index 6b52daa..18b40b2 100644
--- a/src/gpu/effects/generated/GrRRectBlurEffect.h
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.h
@@ -138,10 +138,12 @@
, rect(rect)
, cornerRadius(cornerRadius) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
SkASSERT(ninePatchFP);
- ninePatchFP_index = this->registerExplicitlySampledChild(std::move(ninePatchFP));
+ ninePatchFP_index =
+ this->registerChild(std::move(ninePatchFP), SkSL::SampleUsage::Explicit());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/generated/GrRectBlurEffect.h b/src/gpu/effects/generated/GrRectBlurEffect.h
index 6506a09..03262b6 100644
--- a/src/gpu/effects/generated/GrRectBlurEffect.h
+++ b/src/gpu/effects/generated/GrRectBlurEffect.h
@@ -144,10 +144,11 @@
, rect(rect)
, isFast(isFast) {
if (inputFP) {
- inputFP_index = this->registerChild(std::move(inputFP));
+ inputFP_index =
+ this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
}
SkASSERT(integral);
- integral_index = this->registerExplicitlySampledChild(std::move(integral));
+ integral_index = this->registerChild(std::move(integral), SkSL::SampleUsage::Explicit());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 9b3b7b7..ad9b5ba 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -60,12 +60,12 @@
inputColor ? inputColor : "half4(1)",
skslCoords.c_str());
} else {
- // The child's function just takes a color; we should only get here for a call to
- // sample(color) without explicit coordinates, so assert that the child has no sample matrix
- // and skslCoords is _coords (a const/uniform sample call would go through
- // invokeChildWithMatrix, and if a child was sampled with sample(matrix) and sample(), it
- // should have been flagged as variable and hit the branch above).
- SkASSERT(skslCoords == args.fSampleCoord && childProc.sampleMatrix().isNoOp());
+ // The child's function just takes a color. We should only get here for a call to sample
+ // without explicit coordinates. Assert that the child has no sample matrix and skslCoords
+ // is _coords (a uniform matrix sample call would go through invokeChildWithMatrix, and if
+ // a child was sampled with sample(matrix) and sample(), it should have been flagged as
+ // variable and hit the branch above).
+ SkASSERT(skslCoords == args.fSampleCoord && !childProc.sampleUsage().hasMatrix());
return SkStringPrintf("%s(%s)", fFunctionNames[childIndex].c_str(),
inputColor ? inputColor : "half4(1)");
}
@@ -78,23 +78,23 @@
this->emitChildFunction(childIndex, args);
const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
+ SkASSERT(childProc.sampleUsage().hasMatrix());
- // Since this is const/uniform, the provided sksl expression should exactly match the
- // expression stored on the FP, or it should match the mangled uniform name.
+ // Since this is uniform, the provided sksl expression should exactly match the expression
+ // stored on the FP, or it should match the mangled uniform name.
if (skslMatrix.empty()) {
- // Empty matrix expression replaces with the sampleMatrix expression stored on the FP, but
- // that is only valid for const/uniform sampled FPs
- SkASSERT(childProc.sampleMatrix().isConstUniform());
- skslMatrix.assign(childProc.sampleMatrix().fExpression);
+ // Empty matrix expression replaces with the sample matrix expression stored on the FP, but
+ // that is only valid for uniform sampled FPs
+ SkASSERT(childProc.sampleUsage().hasUniformMatrix());
+ skslMatrix.assign(childProc.sampleUsage().fExpression);
}
- if (childProc.sampleMatrix().isConstUniform()) {
- // Attempt to resolve the uniform name from the raw name that was stored in the sample
- // matrix. Since this is const/uniform, the provided expression better match what was given
- // to the FP.
- SkASSERT(childProc.sampleMatrix().fExpression == skslMatrix);
+ if (childProc.sampleUsage().hasUniformMatrix()) {
+ // Attempt to resolve the uniform name from the raw name stored in the sample usage.
+ // Since this is uniform, the provided expression better match what was given to the FP.
+ SkASSERT(childProc.sampleUsage().fExpression == skslMatrix);
GrShaderVar uniform = args.fUniformHandler->getUniformMapping(
- args.fFp, SkString(childProc.sampleMatrix().fExpression));
+ args.fFp, SkString(childProc.sampleUsage().fExpression));
if (uniform.getType() != kVoid_GrSLType) {
// Found the uniform, so replace the expression with the actual uniform name
SkASSERT(uniform.getType() == kFloat3x3_GrSLType);
@@ -104,18 +104,17 @@
// Produce a string containing the call to the helper function. sample(matrix) is special where
// the provided skslMatrix expression means that the child FP should be invoked with coords
- // equal to matrix * parent coords. However, if matrix is a constant/uniform AND the parent
- // coords were produced by const/uniform transforms, then this expression is lifted to a vertex
+ // equal to matrix * parent coords. However, if matrix is a uniform expression AND the parent
+ // coords were produced by uniform transforms, then this expression is lifted to a vertex
// shader and is stored in a varying. In that case, childProc will not have a variable sample
// matrix and will not be sampled explicitly, so its function signature will not take in coords.
//
// In all other cases, we need to insert sksl to compute matrix * parent coords and then invoke
// the function.
if (childProc.isSampledWithExplicitCoords()) {
- SkASSERT(!childProc.sampleMatrix().isNoOp());
// Only check perspective for this specific matrix transform, not the aggregate FP property.
// Any parent perspective will have already been applied when evaluated in the FS.
- if (childProc.sampleMatrix().fHasPerspective) {
+ if (childProc.sampleUsage().fHasPerspective) {
return SkStringPrintf("%s(%s, proj((%s) * %s.xy1))", fFunctionNames[childIndex].c_str(),
inputColor ? inputColor : "half4(1)", skslMatrix.c_str(),
args.fSampleCoord);
@@ -128,10 +127,10 @@
} else {
// A variable matrix expression should mark the child as explicitly sampled. A no-op
// matrix should match sample(color), not sample(color, matrix).
- SkASSERT(childProc.sampleMatrix().isConstUniform());
+ SkASSERT(childProc.sampleUsage().hasUniformMatrix());
- // Since this is const/uniform and not explicitly sampled, it's transform has been
- // promoted to the vertex shader and the signature doesn't take a float2 coord.
+ // Since this is uniform and not explicitly sampled, it's transform has been promoted to
+ // the vertex shader and the signature doesn't take a float2 coord.
return SkStringPrintf("%s(%s)", fFunctionNames[childIndex].c_str(),
inputColor ? inputColor : "half4(1)");
}
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index 7a83fb3..3408809 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -174,7 +174,7 @@
* expression that evaluates to a float3x3 and is passed in as the 3rd argument.
*
* If skslMatrix is the empty string, then it is automatically replaced with the expression
- * attached to the child's SampleMatrix object. This is only valid if the child is sampled with
+ * attached to the child's SampleUsage object. This is only valid if the child is sampled with
* a const-uniform matrix. If the sample matrix is const-or-uniform, the expression will be
* automatically resolved to the mangled uniform name.
*/
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index 48c9053..35de523 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -149,7 +149,7 @@
this->nextStage();
// An FP's function signature is theoretically always main(half4 color, float2 _coords).
- // However, if it is only sampled by a chain of const/uniform matrices (or legacy coord
+ // However, if it is only sampled by a chain of uniform matrix expressions (or legacy coord
// transforms), the value that would have been passed to _coords is lifted to the vertex shader
// and stored in a unique varying. In that case it uses that variable and does not have a
// second actual argument for _coords.
@@ -160,7 +160,7 @@
GrShaderVar(args.fSampleCoord, kFloat2_GrSLType) };
if (!args.fFp.isSampledWithExplicitCoords()) {
- // Sampled with a const/uniform matrix and/or a legacy coord transform. The actual
+ // Sampled with a uniform matrix expression and/or a legacy coord transform. The actual
// transformation code is emitted in the vertex shader, so this only has to access it.
// Add a float2 _coords variable that maps to the associated varying and replaces the
// absent 2nd argument to the fp's function.
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index 2433a70..0415b37 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -115,8 +115,8 @@
varyingVar = getBaseLocalCoord();
}
} else {
- // The FP's local coordinates are determined by the const/uniform transform
- // hierarchy from this FP to the root, and can be computed in the vertex shader.
+ // The FP's local coordinates are determined by the uniform transform hierarchy
+ // from this FP to the root, and can be computed in the vertex shader.
// If this hierarchy would be the identity transform, then we should use the
// original local coordinate.
// NOTE: The actual transform logic is handled in emitTransformCode(), this just
@@ -127,10 +127,9 @@
const GrFragmentProcessor* node = &fp;
while(node) {
SkASSERT(!node->isSampledWithExplicitCoords() &&
- (node->sampleMatrix().isNoOp() ||
- node->sampleMatrix().isConstUniform()));
+ !node->sampleUsage().hasVariableMatrix());
- if (node->sampleMatrix().isConstUniform()) {
+ if (node->sampleUsage().hasUniformMatrix()) {
// We can stop once we hit an FP that adds transforms; this FP can reuse
// that FPs varying (possibly vivifying it if this was the first use).
transformedLocalCoord = localCoordsMap[node];
@@ -183,8 +182,8 @@
GrGLSLUniformHandler* uniformHandler) {
std::unordered_map<const GrFragmentProcessor*, GrShaderVar> localCoordsMap;
for (const auto& tr : fTransformInfos) {
- // If we recorded a transform info, its sample matrix must be const/uniform
- SkASSERT(tr.fFP->sampleMatrix().isConstUniform());
+ // If we recorded a transform info, its sample matrix must be uniform
+ SkASSERT(tr.fFP->sampleUsage().hasUniformMatrix());
SkString localCoords;
// Build a concatenated matrix expression that we apply to the root local coord.
@@ -203,11 +202,11 @@
localCoords = SkStringPrintf("%s.xy1", cachedBaseCoord.getName().c_str());
}
break;
- } else if (base->sampleMatrix().isConstUniform()) {
+ } else if (base->sampleUsage().hasUniformMatrix()) {
// The FP knows the matrix expression it's sampled with, but its parent defined
// the uniform (when the expression is not a constant).
GrShaderVar uniform = uniformHandler->liftUniformToVertexShader(
- *base->parent(), SkString(base->sampleMatrix().fExpression));
+ *base->parent(), SkString(base->sampleUsage().fExpression));
// Accumulate the base matrix expression as a preConcat
SkString matrix;
@@ -216,7 +215,7 @@
matrix = uniform.getName();
} else {
// No uniform found, so presumably this is a constant
- matrix = SkString(base->sampleMatrix().fExpression);
+ matrix = SkString(base->sampleUsage().fExpression);
}
if (!transformExpression.isEmpty()) {
@@ -226,7 +225,7 @@
} else {
// This intermediate FP is just a pass through and doesn't need to be built
// in to the expression, but must visit its parents in case they add transforms
- SkASSERT(base->sampleMatrix().isNoOp());
+ SkASSERT(!base->sampleUsage().hasMatrix() && !base->sampleUsage().fExplicitCoords);
}
base = base->parent();
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.h b/src/gpu/glsl/GrGLSLGeometryProcessor.h
index f9c2d6d..71e51d8 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.h
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.h
@@ -24,7 +24,7 @@
// 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.
+ // access to any uniforms the FPs registered for uniform sample matrix invocations.
void emitTransformCode(GrGLSLVertexBuilder* vb,
GrGLSLUniformHandler* uniformHandler) override;
diff --git a/src/gpu/glsl/GrGLSLUniformHandler.cpp b/src/gpu/glsl/GrGLSLUniformHandler.cpp
index 0d7a299..0ceb883 100644
--- a/src/gpu/glsl/GrGLSLUniformHandler.cpp
+++ b/src/gpu/glsl/GrGLSLUniformHandler.cpp
@@ -31,7 +31,7 @@
}
}
// Uniform not found; it's better to return a void variable than to assert because sample
- // matrices that are const/uniform are treated the same for most of the code. When the sample
+ // matrices that are uniform are treated the same for most of the code. When the sample
// matrix expression can't be found as a uniform, we can infer it's a constant.
return GrShaderVar();
}
diff --git a/src/gpu/gradients/generated/GrClampedGradientEffect.h b/src/gpu/gradients/generated/GrClampedGradientEffect.h
index 8d2c0bc..c2cc784 100644
--- a/src/gpu/gradients/generated/GrClampedGradientEffect.h
+++ b/src/gpu/gradients/generated/GrClampedGradientEffect.h
@@ -56,9 +56,11 @@
, makePremul(makePremul)
, colorsAreOpaque(colorsAreOpaque) {
SkASSERT(colorizer);
- colorizer_index = this->registerChild(std::move(colorizer));
+ colorizer_index =
+ this->registerChild(std::move(colorizer), SkSL::SampleUsage::PassThrough());
SkASSERT(gradLayout);
- gradLayout_index = this->registerChild(std::move(gradLayout));
+ gradLayout_index =
+ this->registerChild(std::move(gradLayout), SkSL::SampleUsage::PassThrough());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/gradients/generated/GrTextureGradientColorizer.h b/src/gpu/gradients/generated/GrTextureGradientColorizer.h
index b125b65..507e1a7 100644
--- a/src/gpu/gradients/generated/GrTextureGradientColorizer.h
+++ b/src/gpu/gradients/generated/GrTextureGradientColorizer.h
@@ -32,7 +32,7 @@
GrTextureGradientColorizer(std::unique_ptr<GrFragmentProcessor> textureFP)
: INHERITED(kGrTextureGradientColorizer_ClassID, kNone_OptimizationFlags) {
SkASSERT(textureFP);
- textureFP_index = this->registerExplicitlySampledChild(std::move(textureFP));
+ textureFP_index = this->registerChild(std::move(textureFP), SkSL::SampleUsage::Explicit());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/gradients/generated/GrTiledGradientEffect.h b/src/gpu/gradients/generated/GrTiledGradientEffect.h
index 5c004bb..561712d 100644
--- a/src/gpu/gradients/generated/GrTiledGradientEffect.h
+++ b/src/gpu/gradients/generated/GrTiledGradientEffect.h
@@ -51,9 +51,11 @@
, makePremul(makePremul)
, colorsAreOpaque(colorsAreOpaque) {
SkASSERT(colorizer);
- colorizer_index = this->registerChild(std::move(colorizer));
+ colorizer_index =
+ this->registerChild(std::move(colorizer), SkSL::SampleUsage::PassThrough());
SkASSERT(gradLayout);
- gradLayout_index = this->registerChild(std::move(gradLayout));
+ gradLayout_index =
+ this->registerChild(std::move(gradLayout), SkSL::SampleUsage::PassThrough());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index 5ea3738..134a8f4 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -32,7 +32,7 @@
}
static bool has_matrix(const GrFragmentProcessor& fp) {
- if (fp.sampleMatrix().fKind != SkSL::SampleMatrix::Kind::kNone) {
+ if (fp.sampleUsage().hasMatrix()) {
return true;
}
for (int i = fp.numChildProcessors() - 1; i >= 0; --i) {
diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp
index a38c417..2eb8125 100644
--- a/src/shaders/SkPerlinNoiseShader.cpp
+++ b/src/shaders/SkPerlinNoiseShader.cpp
@@ -783,8 +783,8 @@
, fNumOctaves(numOctaves)
, fStitchTiles(stitchTiles)
, fPaintingData(std::move(paintingData)) {
- this->registerExplicitlySampledChild(std::move(permutationsFP));
- this->registerExplicitlySampledChild(std::move(noiseFP));
+ this->registerChild(std::move(permutationsFP), SkSL::SampleUsage::Explicit());
+ this->registerChild(std::move(noiseFP), SkSL::SampleUsage::Explicit());
this->setUsesSampleCoordsDirectly();
}
@@ -1144,8 +1144,8 @@
, fOctaves(octaves)
, fZ(z)
, fPaintingData(std::move(paintingData)) {
- this->registerExplicitlySampledChild(std::move(permutationsFP));
- this->registerExplicitlySampledChild(std::move(gradientFP));
+ this->registerChild(std::move(permutationsFP), SkSL::SampleUsage::Explicit());
+ this->registerChild(std::move(gradientFP), SkSL::SampleUsage::Explicit());
this->setUsesSampleCoordsDirectly();
}
diff --git a/src/sksl/SkSLAnalysis.cpp b/src/sksl/SkSLAnalysis.cpp
index e77aa31..a221f11 100644
--- a/src/sksl/SkSLAnalysis.cpp
+++ b/src/sksl/SkSLAnalysis.cpp
@@ -7,7 +7,7 @@
#include "src/sksl/SkSLAnalysis.h"
-#include "include/private/SkSLSampleMatrix.h"
+#include "include/private/SkSLSampleUsage.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLProgramElement.h"
@@ -69,49 +69,57 @@
&((VariableReference&) *fc.fArguments[0]).fVariable == &fp;
}
-// Visitor that determines the merged SampleMatrix for a given child 'fp' in the program.
-class MergeSampleMatrixVisitor : public ProgramVisitor {
+// Visitor that determines the merged SampleUsage for a given child 'fp' in the program.
+class MergeSampleUsageVisitor : public ProgramVisitor {
public:
- MergeSampleMatrixVisitor(const Variable& fp) : fFP(fp) {}
+ MergeSampleUsageVisitor(const Variable& fp) : fFP(fp) {}
- SampleMatrix visit(const Program& program) {
- fMatrix = SampleMatrix(); // reset to none
+ SampleUsage visit(const Program& program) {
+ fUsage = SampleUsage(); // reset to none
this->INHERITED::visit(program);
- return fMatrix;
+ return fUsage;
}
protected:
const Variable& fFP;
- SampleMatrix fMatrix;
+ SampleUsage fUsage;
bool visitExpression(const Expression& e) override {
- // Looking for sample(fp, inColor?, float3x3)
+ // Looking for sample(fp, inColor?, ...)
if (e.fKind == Expression::kFunctionCall_Kind) {
const FunctionCall& fc = (const FunctionCall&) e;
- if (is_sample_call_to_fp(fc, fFP) && fc.fArguments.size() >= 2 &&
- fc.fArguments.back()->fType == *this->program().fContext->fFloat3x3_Type) {
- // Determine the type of matrix for this call site, then merge it with the
- // previously accumulated matrix state.
- if (fc.fArguments.back()->isConstantOrUniform()) {
- if (fc.fArguments.back()->fKind == Expression::Kind::kVariableReference_Kind ||
- fc.fArguments.back()->fKind == Expression::Kind::kConstructor_Kind) {
- // FIXME if this is a constant, we should parse the float3x3 constructor and
- // determine if the resulting matrix introduces perspective.
- fMatrix.merge(SampleMatrix::MakeConstUniform(
- fc.fArguments.back()->description()));
+ if (is_sample_call_to_fp(fc, fFP)) {
+ // Determine the type of call at this site, and merge it with the accumulated state
+ const Expression* lastArg = fc.fArguments.back().get();
+ const Context& context = *this->program().fContext;
+
+ if (lastArg->fType == *context.fFloat2_Type) {
+ fUsage.merge(SampleUsage::Explicit());
+ } else if (lastArg->fType == *context.fFloat3x3_Type) {
+ // Determine the type of matrix for this call site
+ if (lastArg->isConstantOrUniform()) {
+ if (lastArg->fKind == Expression::Kind::kVariableReference_Kind ||
+ lastArg->fKind == Expression::Kind::kConstructor_Kind) {
+ // FIXME if this is a constant, we should parse the float3x3 constructor
+ // and determine if the resulting matrix introduces perspective.
+ fUsage.merge(SampleUsage::UniformMatrix(lastArg->description()));
+ } else {
+ // FIXME this is really to workaround a restriction of the downstream
+ // code that relies on the SampleUsage's fExpression to identify uniform
+ // names. Once they are tracked separately, any uniform expression can
+ // work, but right now this avoids issues from '0.5 * matrix' that is
+ // both a constant AND a uniform.
+ fUsage.merge(SampleUsage::VariableMatrix());
+ }
} else {
- // FIXME this is really to workaround a restriction of the downstream code
- // that relies on the SampleMatrix's fExpression to identify uniform names.
- // Once they are tracked separately, any constant/uniform expression can
- // work, but right now this avoids issues from '0.5 * matrix' that is both
- // a constant AND a uniform.
- fMatrix.merge(SampleMatrix::MakeVariable());
+ fUsage.merge(SampleUsage::VariableMatrix());
}
} else {
- fMatrix.merge(SampleMatrix::MakeVariable());
+ // The only other signatures do pass-through sampling
+ fUsage.merge(SampleUsage::PassThrough());
}
- // NOTE: we don't return true here just because we found a sample matrix usage,
- // we need to process the entire program and merge across all encountered calls.
+ // NOTE: we don't return true here just because we found a sample call. We need to
+ // process the entire program and merge across all encountered calls.
}
}
@@ -121,30 +129,6 @@
typedef ProgramVisitor INHERITED;
};
-// Visitor that searches a program for sample() calls with the given 'fp' as the argument
-// and returns true if explicit float2 coords were passed to that call site.
-class ExplicitCoordsVisitor : public ProgramVisitor {
-public:
- ExplicitCoordsVisitor(const Variable& fp) : fFP(fp) {}
-
-protected:
- bool visitExpression(const Expression& e) override {
- // Looking for sample(fp, inColor?, float2)
- if (e.fKind == Expression::kFunctionCall_Kind) {
- const FunctionCall& fc = (const FunctionCall&) e;
- if (is_sample_call_to_fp(fc, fFP) && fc.fArguments.size() >= 2 &&
- fc.fArguments.back()->fType == *this->program().fContext->fFloat2_Type) {
- return true;
- }
- }
- return this->INHERITED::visitExpression(e);
- }
-
- const Variable& fFP;
-
- typedef ProgramVisitor INHERITED;
-};
-
// Visitor that searches through a main function of the program for reference to the
// sample coordinates provided by the parent FP or main program.
class SampleCoordsVisitor : public ProgramVisitor {
@@ -181,13 +165,8 @@
////////////////////////////////////////////////////////////////////////////////
// Analysis
-SampleMatrix Analysis::GetSampleMatrix(const Program& program, const Variable& fp) {
- MergeSampleMatrixVisitor visitor(fp);
- return visitor.visit(program);
-}
-
-bool Analysis::IsExplicitlySampled(const Program& program, const Variable& fp) {
- ExplicitCoordsVisitor visitor(fp);
+SampleUsage Analysis::GetSampleUsage(const Program& program, const Variable& fp) {
+ MergeSampleUsageVisitor visitor(fp);
return visitor.visit(program);
}
diff --git a/src/sksl/SkSLAnalysis.h b/src/sksl/SkSLAnalysis.h
index 164e026..f8b3460 100644
--- a/src/sksl/SkSLAnalysis.h
+++ b/src/sksl/SkSLAnalysis.h
@@ -8,7 +8,7 @@
#ifndef SkSLAnalysis_DEFINED
#define SkSLAnalysis_DEFINED
-#include "include/private/SkSLSampleMatrix.h"
+#include "include/private/SkSLSampleUsage.h"
#include "src/sksl/SkSLDefines.h"
namespace SkSL {
@@ -23,9 +23,7 @@
* Provides utilities for analyzing SkSL statically before it's composed into a full program.
*/
struct Analysis {
- static SampleMatrix GetSampleMatrix(const Program& program, const Variable& fp);
-
- static bool IsExplicitlySampled(const Program& program, const Variable& fp);
+ static SampleUsage GetSampleUsage(const Program& program, const Variable& fp);
static bool ReferencesSampleCoords(const Program& program);
};
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index 0a88298..4a0cad9 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -7,7 +7,7 @@
#include "src/sksl/SkSLCPPCodeGenerator.h"
-#include "include/private/SkSLSampleMatrix.h"
+#include "include/private/SkSLSampleUsage.h"
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLCPPUniformCTypes.h"
#include "src/sksl/SkSLCompiler.h"
@@ -438,9 +438,9 @@
} else if (c.fArguments.back()->fType.name() == "float3x3") {
// Invoking child with a matrix, sampling relative to the input coords.
invokeFunction = "invokeChildWithMatrix";
- SampleMatrix matrix = Analysis::GetSampleMatrix(fProgram, child);
+ SampleUsage usage = Analysis::GetSampleUsage(fProgram, child);
- if (!matrix.isConstUniform()) {
+ if (!usage.hasUniformMatrix()) {
inputCoord = "_matrix" + to_string(c.fOffset);
addExtraEmitCodeLine(convertSKSLExpressionToCPP(*c.fArguments.back(), inputCoord));
inputCoord.append(".c_str()");
diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp
index f7c324b..3f5f2f3 100644
--- a/src/sksl/SkSLHCodeGenerator.cpp
+++ b/src/sksl/SkSLHCodeGenerator.cpp
@@ -7,7 +7,7 @@
#include "src/sksl/SkSLHCodeGenerator.h"
-#include "include/private/SkSLSampleMatrix.h"
+#include "include/private/SkSLSampleUsage.h"
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLParser.h"
#include "src/sksl/SkSLUtil.h"
@@ -276,53 +276,24 @@
this->writef(" SkASSERT(%s);", String(param->fName).c_str());
}
- bool explicitCoords = Analysis::IsExplicitlySampled(fProgram, *param);
- SampleMatrix matrix = Analysis::GetSampleMatrix(fProgram, *param);
+ SampleUsage usage = Analysis::GetSampleUsage(fProgram, *param);
- String registerFunc;
- String matrixArg;
- String explicitArg;
-
- if (explicitCoords && matrix.fKind == SampleMatrix::Kind::kNone) {
- registerFunc = "registerExplicitlySampledChild";
- } else {
- registerFunc = "registerChild";
- if (explicitCoords) {
- explicitArg = ", true";
- }
- switch(matrix.fKind) {
- case SampleMatrix::Kind::kVariable:
- // FIXME As it stands, matrix.fHasPerspective will always be true. Ideally
- // we could build an expression from all const/uniform sample matrices used
- // in the sksl, e.g. m1.hasPerspective() || m2.hasPerspective(), where each
- // term was the type expression for the original const/uniform sample
- // matrices before they were merged during sksl analysis.
- matrixArg.appendf(", SkSL::SampleMatrix::MakeVariable(%s)",
- matrix.fHasPerspective ? "true" : "false");
+ std::string perspExpression;
+ if (usage.hasUniformMatrix()) {
+ for (const Variable* p : fSectionAndParameterHelper.getParameters()) {
+ if ((p->fModifiers.fFlags & Modifiers::kIn_Flag) &&
+ usage.fExpression == String(p->fName)) {
+ perspExpression = usage.fExpression + ".hasPerspective()";
break;
- case SampleMatrix::Kind::kConstantOrUniform: {
- std::string perspExpression = matrix.fHasPerspective ? "true" : "false";
- for (const Variable* p : fSectionAndParameterHelper.getParameters()) {
- if ((p->fModifiers.fFlags & Modifiers::kIn_Flag) &&
- matrix.fExpression == String(p->fName)) {
- perspExpression = matrix.fExpression + ".hasPerspective()";
- break;
- }
- }
- matrixArg.appendf(", SkSL::SampleMatrix::MakeConstUniform(\"%s\", %s)",
- matrix.fExpression.c_str(), perspExpression.c_str());
- break; }
- case SampleMatrix::Kind::kNone:
- break;
+ }
}
}
+ std::string usageArg = usage.constructor(std::move(perspExpression));
- this->writef(" %s_index = this->%s(std::move(%s)%s%s);",
+ this->writef(" %s_index = this->registerChild(std::move(%s), %s);",
FieldName(String(param->fName).c_str()).c_str(),
- registerFunc.c_str(),
String(param->fName).c_str(),
- matrixArg.c_str(),
- explicitArg.c_str());
+ usageArg.c_str());
if (param->fType.kind() == Type::kNullable_Kind) {
this->writef(" }");
diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
index 6c6925c..4b4bd76 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -37,7 +37,7 @@
void PipelineStageCodeGenerator::writeFunctionCall(const FunctionCall& c) {
if (c.fFunction.fBuiltin && c.fFunction.fName == "sample" &&
c.fArguments[0]->fType.kind() != Type::Kind::kSampler_Kind) {
- SkASSERT(c.fArguments.size() == 2);
+ SkASSERT(c.fArguments.size() <= 2);
SkASSERT("fragmentProcessor" == c.fArguments[0]->fType.name() ||
"fragmentProcessor?" == c.fArguments[0]->fType.name());
SkASSERT(Expression::kVariableReference_Kind == c.fArguments[0]->fKind);
@@ -68,12 +68,14 @@
matrixCall ? Compiler::FormatArg::Kind::kChildProcessorWithMatrix
: Compiler::FormatArg::Kind::kChildProcessor,
index));
- OutputStream* oldOut = fOut;
- StringStream buffer;
- fOut = &buffer;
- this->writeExpression(*c.fArguments[1], kSequence_Precedence);
- fOut = oldOut;
- fArgs->fFormatArgs[childCallIndex].fCoords = buffer.str();
+ if (c.fArguments.size() > 1) {
+ OutputStream* oldOut = fOut;
+ StringStream buffer;
+ fOut = &buffer;
+ this->writeExpression(*c.fArguments[1], kSequence_Precedence);
+ fOut = oldOut;
+ fArgs->fFormatArgs[childCallIndex].fCoords = buffer.str();
+ }
return;
}
if (c.fFunction.fBuiltin) {
diff --git a/src/sksl/SkSLSampleMatrix.cpp b/src/sksl/SkSLSampleMatrix.cpp
deleted file mode 100644
index c961401..0000000
--- a/src/sksl/SkSLSampleMatrix.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/private/SkSLSampleMatrix.h"
-
-#include "src/sksl/ir/SkSLBinaryExpression.h"
-#include "src/sksl/ir/SkSLConstructor.h"
-#include "src/sksl/ir/SkSLDoStatement.h"
-#include "src/sksl/ir/SkSLExpression.h"
-#include "src/sksl/ir/SkSLExpressionStatement.h"
-#include "src/sksl/ir/SkSLFieldAccess.h"
-#include "src/sksl/ir/SkSLForStatement.h"
-#include "src/sksl/ir/SkSLFunctionCall.h"
-#include "src/sksl/ir/SkSLIfStatement.h"
-#include "src/sksl/ir/SkSLIndexExpression.h"
-#include "src/sksl/ir/SkSLPostfixExpression.h"
-#include "src/sksl/ir/SkSLPrefixExpression.h"
-#include "src/sksl/ir/SkSLProgram.h"
-#include "src/sksl/ir/SkSLReturnStatement.h"
-#include "src/sksl/ir/SkSLSwitchStatement.h"
-#include "src/sksl/ir/SkSLSwizzle.h"
-#include "src/sksl/ir/SkSLTernaryExpression.h"
-#include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
-#include "src/sksl/ir/SkSLVariable.h"
-#include "src/sksl/ir/SkSLWhileStatement.h"
-
-namespace SkSL {
-
-SampleMatrix SampleMatrix::merge(const SampleMatrix& other) {
- if (fKind == Kind::kVariable || other.fKind == Kind::kVariable) {
- *this = SampleMatrix::MakeVariable(this->fHasPerspective || other.fHasPerspective);
- return *this;
- }
- if (other.fKind == Kind::kConstantOrUniform) {
- if (fKind == other.fKind) {
- if (fExpression == other.fExpression) {
- return *this;
- }
- *this = SampleMatrix::MakeVariable(this->fHasPerspective || other.fHasPerspective);
- return *this;
- }
- SkASSERT(fKind == Kind::kNone);
- *this = other;
- return *this;
- }
- return *this;
-}
-
-} // namespace
diff --git a/src/sksl/SkSLSampleUsage.cpp b/src/sksl/SkSLSampleUsage.cpp
new file mode 100644
index 0000000..6eac4b6
--- /dev/null
+++ b/src/sksl/SkSLSampleUsage.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/private/SkSLSampleUsage.h"
+
+#include "src/sksl/ir/SkSLBinaryExpression.h"
+#include "src/sksl/ir/SkSLConstructor.h"
+#include "src/sksl/ir/SkSLDoStatement.h"
+#include "src/sksl/ir/SkSLExpression.h"
+#include "src/sksl/ir/SkSLExpressionStatement.h"
+#include "src/sksl/ir/SkSLFieldAccess.h"
+#include "src/sksl/ir/SkSLForStatement.h"
+#include "src/sksl/ir/SkSLFunctionCall.h"
+#include "src/sksl/ir/SkSLIfStatement.h"
+#include "src/sksl/ir/SkSLIndexExpression.h"
+#include "src/sksl/ir/SkSLPostfixExpression.h"
+#include "src/sksl/ir/SkSLPrefixExpression.h"
+#include "src/sksl/ir/SkSLProgram.h"
+#include "src/sksl/ir/SkSLReturnStatement.h"
+#include "src/sksl/ir/SkSLSwitchStatement.h"
+#include "src/sksl/ir/SkSLSwizzle.h"
+#include "src/sksl/ir/SkSLTernaryExpression.h"
+#include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
+#include "src/sksl/ir/SkSLVariable.h"
+#include "src/sksl/ir/SkSLWhileStatement.h"
+
+namespace SkSL {
+
+SampleUsage SampleUsage::merge(const SampleUsage& other) {
+ if (other.fExplicitCoords) { fExplicitCoords = true; }
+ if (other.fPassThrough) { fPassThrough = true; }
+ if (other.fHasPerspective) { fHasPerspective = true; }
+
+ if (other.fKind == Kind::kVariable) {
+ fKind = Kind::kVariable;
+ fExpression.clear();
+ } else if (other.fKind == Kind::kUniform) {
+ if (fKind == Kind::kUniform) {
+ if (fExpression != other.fExpression) {
+ fKind = Kind::kVariable;
+ fExpression.clear();
+ } else {
+ // Identical uniform expressions, so leave things as-is
+ }
+ } else if (fKind == Kind::kNone) {
+ fKind = Kind::kUniform;
+ fExpression = other.fExpression;
+ } else {
+ // We were already variable, so leave things as-is
+ SkASSERT(fKind == Kind::kVariable);
+ }
+ } else {
+ // other had no matrix information, so we're done
+ }
+
+ return *this;
+}
+
+std::string SampleUsage::constructor(std::string perspectiveExpression) const {
+ SkASSERT(this->hasMatrix() || perspectiveExpression.empty());
+ if (perspectiveExpression.empty()) {
+ perspectiveExpression = fHasPerspective ? "true" : "false";
+ }
+
+ // Check for special cases where we can use our factories:
+ if (!this->hasMatrix()) {
+ if (fExplicitCoords && !fPassThrough) {
+ return "SkSL::SampleUsage::Explicit()";
+ } else if (fPassThrough && !fExplicitCoords) {
+ return "SkSL::SampleUsage::PassThrough()";
+ }
+ }
+ if (!fExplicitCoords && !fPassThrough) {
+ if (fKind == Kind::kVariable) {
+ return "SkSL::SampleUsage::VariableMatrix(" + perspectiveExpression + ")";
+ } else if (fKind == Kind::kUniform) {
+ return "SkSL::SampleUsage::UniformMatrix(\"" + fExpression + "\", " +
+ perspectiveExpression + ")";
+ }
+ }
+
+ // For more complex scenarios (mixed sampling), fall back to our universal constructor
+ std::string result = "SkSL::SampleUsage(SkSL::SampleUsage::Kind::";
+ switch (fKind) {
+ case Kind::kNone: result += "kNone"; break;
+ case Kind::kUniform: result += "kUniform"; break;
+ case Kind::kVariable: result += "kVariable"; break;
+ }
+ result += ", \"";
+ result += fExpression;
+ result += "\", ";
+ result += perspectiveExpression;
+ result += ", ";
+ result += fExplicitCoords ? "true, " : "false, ";
+ result += fPassThrough ? "true)" : "false)";
+
+ return result;
+}
+
+} // namespace
diff --git a/src/sksl/sksl_pipeline.inc b/src/sksl/sksl_pipeline.inc
index 2f31951..8c9d926 100644
--- a/src/sksl/sksl_pipeline.inc
+++ b/src/sksl/sksl_pipeline.inc
@@ -1,5 +1,6 @@
STRINGIFY(
layout(builtin=15) float4 sk_FragCoord;
+ half4 sample(fragmentProcessor fp);
half4 sample(fragmentProcessor fp, float2 coords);
half4 sample(fragmentProcessor fp, float3x3 transform);
)