fixed sample(..., matrix) with runtime effects
Change-Id: Id5b7f1b5e992c587be000e112706bedfe00c90fd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294697
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index 858baed..68768b5 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -27,7 +27,6 @@
#if SK_SUPPORT_GPU
#include "include/private/GrRecordingContext.h"
#include "src/gpu/GrColorInfo.h"
-#include "src/gpu/GrFPArgs.h"
#include "src/gpu/effects/GrMatrixEffect.h"
#include "src/gpu/effects/GrSkSLFP.h"
#endif
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index a2e9b46..6cab5a8 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -19,7 +19,7 @@
class GrGLSLSkSLFP : public GrGLSLFragmentProcessor {
public:
- GrGLSLSkSLFP(SkSL::PipelineStageArgs&& args) : fArgs(std::move(args)) {}
+ GrGLSLSkSLFP(const SkSL::PipelineStageArgs& args) : fArgs(std::move(args)) {}
SkSL::String expandFormatArgs(const SkSL::String& raw,
EmitArgs& args,
@@ -57,6 +57,13 @@
result += this->invokeChild(arg.fIndex, args, coords).c_str();
break;
}
+ case SkSL::Compiler::FormatArg::Kind::kChildProcessorWithMatrix: {
+ SkSL::String coords = this->expandFormatArgs(arg.fCoords, args,
+ fmtArg, coordsName);
+ result += this->invokeChildWithMatrix(arg.fIndex, args,
+ coords).c_str();
+ break;
+ }
case SkSL::Compiler::FormatArg::Kind::kFunctionName:
SkASSERT((int) fFunctionNames.size() > arg.fIndex);
result += fFunctionNames[arg.fIndex].c_str();
@@ -95,7 +102,8 @@
// We need to ensure that we call invokeChild on each child FP at least once.
// Any child FP that isn't sampled won't trigger a call otherwise, leading to asserts later.
for (int i = 0; i < this->numChildProcessors(); ++i) {
- (void)this->invokeChild(i, args, SkSL::String("_coords"));
+ bool isExplicit = args.fFp.childProcessor(i).isSampledWithExplicitCoords();
+ (void)this->invokeChild(i, args, isExplicit ? SkSL::String("_coords") : "");
}
for (const auto& f : fArgs.fFunctions) {
fFunctionNames.emplace_back();
@@ -181,6 +189,7 @@
, fName(name)
, fInputs(std::move(inputs)) {
this->addCoordTransform(&fCoordTransform);
+ fEffect->toPipelineStage(fInputs->data(), fShaderCaps.get(), fShaderErrorHandler, &fArgs);
}
GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
@@ -189,7 +198,8 @@
, fShaderErrorHandler(other.fShaderErrorHandler)
, fEffect(other.fEffect)
, fName(other.fName)
- , fInputs(other.fInputs) {
+ , fInputs(other.fInputs)
+ , fArgs(other.fArgs) {
this->addCoordTransform(&fCoordTransform);
}
@@ -198,15 +208,18 @@
}
void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) {
- child->setSampledWithExplicitCoords();
+ int newIndex = this->numChildProcessors();
+ if ((int) fArgs.fSampleMatrices.size() > newIndex &&
+ fArgs.fSampleMatrices[newIndex].fKind != SkSL::SampleMatrix::Kind::kNone) {
+ child->setSampleMatrix(fArgs.fSampleMatrices[newIndex]);
+ } else {
+ child->setSampledWithExplicitCoords();
+ }
this->registerChildProcessor(std::move(child));
}
GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
- // Note: This is actually SkSL (again) but with inline format specifiers.
- SkSL::PipelineStageArgs args;
- fEffect->toPipelineStage(fInputs->data(), fShaderCaps.get(), fShaderErrorHandler, &args);
- return new GrGLSLSkSLFP(std::move(args));
+ return new GrGLSLSkSLFP(fArgs);
}
void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
diff --git a/src/gpu/effects/GrSkSLFP.h b/src/gpu/effects/GrSkSLFP.h
index 8dc9e30..5b94acd 100644
--- a/src/gpu/effects/GrSkSLFP.h
+++ b/src/gpu/effects/GrSkSLFP.h
@@ -94,9 +94,10 @@
sk_sp<const GrShaderCaps> fShaderCaps;
ShaderErrorHandler* fShaderErrorHandler;
- sk_sp<SkRuntimeEffect> fEffect;
- const char* fName;
- sk_sp<SkData> fInputs;
+ sk_sp<SkRuntimeEffect> fEffect;
+ const char* fName;
+ sk_sp<SkData> fInputs;
+ SkSL::PipelineStageArgs fArgs;
GrCoordTransform fCoordTransform;
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 90f50c2..6450907 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -81,6 +81,7 @@
SkString GrGLSLFragmentProcessor::invokeChildWithMatrix(int childIndex, const char* inputColor,
EmitArgs& args,
SkSL::String skslMatrix) {
+ SkASSERT(!args.fFp.isSampledWithExplicitCoords());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
while (childIndex >= (int) fFunctionNames.size()) {
fFunctionNames.emplace_back();
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index 3193197..ee0edb5 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -17,6 +17,7 @@
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLLexer.h"
+#include "src/sksl/SkSLSampleMatrix.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLSymbolTable.h"
@@ -79,6 +80,7 @@
kCoords,
kUniform,
kChildProcessor,
+ kChildProcessorWithMatrix,
kFunctionName
};
@@ -245,6 +247,7 @@
String fCode;
std::vector<Compiler::FormatArg> fFormatArgs;
std::vector<Compiler::GLSLFunction> fFunctions;
+ std::vector<SkSL::SampleMatrix> fSampleMatrices;
};
#endif
diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
index a98ad9d..4fa902c 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -81,8 +81,18 @@
SkASSERT(found);
this->write("%s");
size_t childCallIndex = fArgs->fFormatArgs.size();
+ bool matrixCall = c.fArguments.size() == 2 &&
+ c.fArguments[1]->fType.kind() == Type::kMatrix_Kind;
fArgs->fFormatArgs.push_back(
- Compiler::FormatArg(Compiler::FormatArg::Kind::kChildProcessor, index));
+ Compiler::FormatArg(matrixCall ? Compiler::FormatArg::Kind::kChildProcessorWithMatrix
+ : Compiler::FormatArg::Kind::kChildProcessor,
+ index));
+ while ((int) fArgs->fSampleMatrices.size() <= index) {
+ fArgs->fSampleMatrices.push_back(SampleMatrix(SampleMatrix::Kind::kNone));
+ }
+ if (matrixCall) {
+ fArgs->fSampleMatrices[index] = SampleMatrix(SampleMatrix::Kind::kVariable);
+ }
OutputStream* oldOut = fOut;
StringStream buffer;
fOut = &buffer;