Reland "Switch runtime SkSL to always sample at explicit coords"
This reverts commit d4bf54eac6243b2b5c2125f6e696d880bbe3ec33.
Change-Id: I65bfea4d880de29394e25d44d781fd18508fe337
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/266942
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/effects/imagefilters/SkArithmeticImageFilter.cpp b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
index 5f2a20e..1e91985 100644
--- a/src/effects/imagefilters/SkArithmeticImageFilter.cpp
+++ b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
@@ -36,8 +36,8 @@
in bool enforcePMColor;
in fragmentProcessor child;
-void main(inout half4 color) {
- half4 dst = sample(child);
+void main(float x, float y, inout half4 color) {
+ half4 dst = sample(child, float2(x, y));
color = saturate(half(k.x) * color * dst + half(k.y) * color + half(k.z) * dst + half(k.w));
@if (enforcePMColor) {
color.rgb = min(color.rgb, color.a);
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index c10bac4..48d3b79 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -22,13 +22,11 @@
GrGLSLSkSLFP(SkSL::PipelineStageArgs&& args) : fArgs(std::move(args)) {}
SkSL::String expandFormatArgs(const SkSL::String& raw,
- const EmitArgs& args,
- const std::vector<SkSL::Compiler::FormatArg> formatArgs,
- const char* coordsName,
- const std::vector<SkString>& childNames) {
+ EmitArgs& args,
+ std::vector<SkSL::Compiler::FormatArg>::const_iterator& fmtArg,
+ const char* coordsName) {
SkSL::String result;
int substringStartIndex = 0;
- int formatArgIndex = 0;
for (size_t i = 0; i < raw.length(); ++i) {
char c = raw[i];
if (c == '%') {
@@ -38,7 +36,7 @@
c = raw[i];
switch (c) {
case 's': {
- const SkSL::Compiler::FormatArg& arg = formatArgs[formatArgIndex++];
+ const SkSL::Compiler::FormatArg& arg = *fmtArg++;
switch (arg.fKind) {
case SkSL::Compiler::FormatArg::Kind::kInput:
result += args.fInputColor;
@@ -58,9 +56,12 @@
result += args.fUniformHandler->getUniformCStr(
fUniformHandles[arg.fIndex]);
break;
- case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
- result += childNames[arg.fIndex].c_str();
+ case SkSL::Compiler::FormatArg::Kind::kChildProcessor: {
+ SkSL::String coords = this->expandFormatArgs(arg.fCoords, args,
+ fmtArg, coordsName);
+ result += this->invokeChild(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();
@@ -94,13 +95,17 @@
SkASSERT(args.fTransformedCoords.count() == 1);
SkString coords = fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
std::vector<SkString> childNames;
+ // 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) {
- childNames.push_back(this->invokeChild(i, args));
+ (void)this->invokeChild(i, args, SkSL::String("_coords"));
}
for (const auto& f : fArgs.fFunctions) {
fFunctionNames.emplace_back();
- SkSL::String body = this->expandFormatArgs(f.fBody.c_str(), args, f.fFormatArgs,
- coords.c_str(), childNames);
+ auto fmtArgIter = f.fFormatArgs.cbegin();
+ SkSL::String body =
+ this->expandFormatArgs(f.fBody.c_str(), args, fmtArgIter, coords.c_str());
+ SkASSERT(fmtArgIter == f.fFormatArgs.cend());
fragBuilder->emitFunction(f.fReturnType,
f.fName.c_str(),
f.fParameters.size(),
@@ -108,8 +113,10 @@
body.c_str(),
&fFunctionNames.back());
}
- fragBuilder->codeAppend(this->expandFormatArgs(fArgs.fCode.c_str(), args, fArgs.fFormatArgs,
- coords.c_str(), childNames).c_str());
+ auto fmtArgIter = fArgs.fFormatArgs.cbegin();
+ fragBuilder->codeAppend(this->expandFormatArgs(fArgs.fCode.c_str(), args, fmtArgIter,
+ coords.c_str()).c_str());
+ SkASSERT(fmtArgIter == fArgs.fFormatArgs.cend());
}
void onSetData(const GrGLSLProgramDataManager& pdman,
@@ -198,6 +205,7 @@
}
void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) {
+ child->setSampledWithExplicitCoords(true);
this->registerChildProcessor(std::move(child));
}
@@ -244,7 +252,7 @@
std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const {
std::unique_ptr<GrSkSLFP> result(new GrSkSLFP(*this));
for (int i = 0; i < this->numChildProcessors(); ++i) {
- result->registerChildProcessor(this->childProcessor(i).clone());
+ result->addChild(this->childProcessor(i).clone());
}
return std::unique_ptr<GrFragmentProcessor>(result.release());
}
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index 25762e8..cf657e5 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -92,8 +92,8 @@
, fIndex(index) {}
Kind fKind;
-
int fIndex;
+ String fCoords;
};
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
index 08cedbf..907009d 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -56,9 +56,10 @@
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() == 1);
+ SkASSERT(c.fArguments.size() == 2);
SkASSERT("fragmentProcessor" == c.fArguments[0]->fType.name() ||
"fragmentProcessor?" == c.fArguments[0]->fType.name());
+ SkASSERT("float2" == c.fArguments[1]->fType.name());
SkASSERT(Expression::kVariableReference_Kind == c.fArguments[0]->fKind);
int index = 0;
bool found = false;
@@ -80,8 +81,15 @@
}
SkASSERT(found);
this->write("%s");
+ size_t childCallIndex = fArgs->fFormatArgs.size();
fArgs->fFormatArgs.push_back(
Compiler::FormatArg(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();
return;
}
if (c.fFunction.fBuiltin) {
diff --git a/src/sksl/sksl_pipeline.inc b/src/sksl/sksl_pipeline.inc
index 56f189e..ff7068b 100644
--- a/src/sksl/sksl_pipeline.inc
+++ b/src/sksl/sksl_pipeline.inc
@@ -1,3 +1,3 @@
STRINGIFY(
- half4 sample(fragmentProcessor fp);
+ half4 sample(fragmentProcessor fp, float2 coords);
)
diff --git a/tools/viewer/SkSLSlide.cpp b/tools/viewer/SkSLSlide.cpp
index c2ca079..01619f8 100644
--- a/tools/viewer/SkSLSlide.cpp
+++ b/tools/viewer/SkSLSlide.cpp
@@ -8,6 +8,7 @@
#include "tools/viewer/SkSLSlide.h"
#include "include/effects/SkGradientShader.h"
+#include "include/effects/SkPerlinNoiseShader.h"
#include "src/core/SkEnumerate.h"
#include "tools/Resources.h"
#include "tools/viewer/ImGuiLayer.h"
@@ -36,10 +37,10 @@
fSkSL =
- "uniform half4 gColor;\n"
+ "in fragmentProcessor fp;\n"
"\n"
"void main(float x, float y, inout half4 color) {\n"
- " color = half4(half(x)*(1.0/255), half(y)*(1.0/255), gColor.b, 1);\n"
+ " color = sample(fp, float2(x, y));\n"
"}\n";
}
@@ -62,6 +63,9 @@
shader = GetResourceAsImage("images/mandrill_256.png")->makeShader();
fShaders.push_back(std::make_pair("Mandrill", shader));
+ shader = SkPerlinNoiseShader::MakeImprovedNoise(0.025f, 0.025f, 3, 0.0f);
+ fShaders.push_back(std::make_pair("Perlin Noise", shader));
+
this->rebuild();
}