Child fragment processors are now written as separate functions
Bug: skia:
Change-Id: Icbf8f542637a874b3e2d3513d932b39728fa5e77
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/229385
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/core/SkNormalMapSource.cpp b/src/core/SkNormalMapSource.cpp
index b359733..b84e726 100644
--- a/src/core/SkNormalMapSource.cpp
+++ b/src/core/SkNormalMapSource.cpp
@@ -50,7 +50,7 @@
"Xform", &xformUniName);
SkString dstNormalColorName("dstNormalColor");
- this->emitChild(0, &dstNormalColorName, args);
+ this->invokeChild(0, &dstNormalColorName, args);
fragBuilder->codeAppendf("float3 normal = normalize(%s.rgb - float3(0.5));",
dstNormalColorName.c_str());
diff --git a/src/gpu/GrColorSpaceXform.cpp b/src/gpu/GrColorSpaceXform.cpp
index 39118a6..e8d739c 100644
--- a/src/gpu/GrColorSpaceXform.cpp
+++ b/src/gpu/GrColorSpaceXform.cpp
@@ -66,7 +66,7 @@
if (this->numChildProcessors()) {
SkString childColor("src_color");
- this->emitChild(0, &childColor, args);
+ this->invokeChild(0, &childColor, args);
SkString xformedColor;
fragBuilder->appendColorGamutXform(&xformedColor, childColor.c_str(), &fColorSpaceHelper);
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index d2d9902..41975b3 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -233,7 +233,7 @@
public:
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- this->emitChild(0, args);
+ this->invokeChild(0, args);
fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
args.fInputColor);
fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
@@ -310,15 +310,15 @@
void emitCode(EmitArgs& args) override {
// First guy's input might be nil.
SkString temp("out0");
- this->emitChild(0, args.fInputColor, &temp, args);
+ this->invokeChild(0, args.fInputColor, &temp, args);
SkString input = temp;
for (int i = 1; i < this->numChildProcessors() - 1; ++i) {
temp.printf("out%d", i);
- this->emitChild(i, input.c_str(), &temp, args);
+ this->invokeChild(i, input.c_str(), &temp, args);
input = temp;
}
// Last guy writes to our output variable.
- this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
+ this->invokeChild(this->numChildProcessors() - 1, input.c_str(), args);
}
};
return new GLFP;
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index cd8803e..5a9367a 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -162,7 +162,7 @@
std::vector<SkString> childNames;
for (int i = 0; i < this->numChildProcessors(); ++i) {
childNames.push_back(SkStringPrintf("_child%d", i));
- this->emitChild(i, &childNames[i], args);
+ this->invokeChild(i, &childNames[i], args);
}
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
int substringStartIndex = 0;
diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
index 1424939..d21b498 100644
--- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
+++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
@@ -221,10 +221,10 @@
// declare outputColor and emit the code for each of the two children
SkString srcColor("xfer_src");
- this->emitChild(0, inputColor, &srcColor, args);
+ this->invokeChild(0, inputColor, &srcColor, args);
SkString dstColor("xfer_dst");
- this->emitChild(1, inputColor, &dstColor, args);
+ this->invokeChild(1, inputColor, &dstColor, args);
// emit blend code
SkBlendMode mode = cs.getMode();
@@ -439,7 +439,7 @@
ComposeOneFragmentProcessor::Child child =
args.fFp.cast<ComposeOneFragmentProcessor>().child();
SkString childColor("child");
- this->emitChild(0, &childColor, args);
+ this->invokeChild(0, &childColor, args);
// emit blend code
fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkBlendMode_Name(mode));
diff --git a/src/gpu/effects/generated/GrComposeLerpEffect.cpp b/src/gpu/effects/generated/GrComposeLerpEffect.cpp
index c9b4d3b..1f0d9f4 100644
--- a/src/gpu/effects/generated/GrComposeLerpEffect.cpp
+++ b/src/gpu/effects/generated/GrComposeLerpEffect.cpp
@@ -29,13 +29,13 @@
args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, "weight");
SkString _child0("_child0");
if (_outer.child1_index >= 0) {
- this->emitChild(_outer.child1_index, &_child0, args);
+ this->invokeChild(_outer.child1_index, &_child0, args);
} else {
fragBuilder->codeAppendf("half4 %s;", _child0.c_str());
}
SkString _child1("_child1");
if (_outer.child2_index >= 0) {
- this->emitChild(_outer.child2_index, &_child1, args);
+ this->invokeChild(_outer.child2_index, &_child1, args);
} else {
fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
}
diff --git a/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp b/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp
index d75b411..d82bf0a 100644
--- a/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp
+++ b/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp
@@ -25,18 +25,18 @@
(void)_outer;
SkString _child0("_child0");
if (_outer.child1_index >= 0) {
- this->emitChild(_outer.child1_index, &_child0, args);
+ this->invokeChild(_outer.child1_index, &_child0, args);
} else {
fragBuilder->codeAppendf("half4 %s;", _child0.c_str());
}
SkString _child1("_child1");
if (_outer.child2_index >= 0) {
- this->emitChild(_outer.child2_index, &_child1, args);
+ this->invokeChild(_outer.child2_index, &_child1, args);
} else {
fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
}
SkString _child2("_child2");
- this->emitChild(_outer.lerp_index, &_child2, args);
+ this->invokeChild(_outer.lerp_index, &_child2, args);
fragBuilder->codeAppendf("%s = mix(%s ? %s : %s, %s ? %s : %s, %s.x);\n", args.fOutputColor,
_outer.child1_index >= 0 ? "true" : "false", _child0.c_str(),
args.fInputColor, _outer.child2_index >= 0 ? "true" : "false",
diff --git a/src/gpu/effects/generated/GrMixerEffect.cpp b/src/gpu/effects/generated/GrMixerEffect.cpp
index af5a7af..f0da5b3 100644
--- a/src/gpu/effects/generated/GrMixerEffect.cpp
+++ b/src/gpu/effects/generated/GrMixerEffect.cpp
@@ -29,12 +29,12 @@
args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "weight");
SkString _input0 = SkStringPrintf("%s", args.fInputColor);
SkString _child0("_child0");
- this->emitChild(_outer.fp0_index, _input0.c_str(), &_child0, args);
+ this->invokeChild(_outer.fp0_index, _input0.c_str(), &_child0, args);
fragBuilder->codeAppendf("half4 in0 = %s;", _child0.c_str());
SkString _input1 = SkStringPrintf("%s", args.fInputColor);
SkString _child1("_child1");
if (_outer.fp1_index >= 0) {
- this->emitChild(_outer.fp1_index, _input1.c_str(), &_child1, args);
+ this->invokeChild(_outer.fp1_index, _input1.c_str(), &_child1, args);
} else {
fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
}
diff --git a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
index 9d7934e..689e079 100644
--- a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
+++ b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
@@ -44,7 +44,7 @@
_outer.literalColor.fA);
SkString _input0("constColor");
SkString _child0("_child0");
- this->emitChild(_outer.fp_index, _input0.c_str(), &_child0, args);
+ this->invokeChild(_outer.fp_index, _input0.c_str(), &_child0, args);
fragBuilder->codeAppendf("\n%s = %s;\n", args.fOutputColor, _child0.c_str());
}
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 4101860..dec2c96 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -16,21 +16,33 @@
this->onSetData(pdman, processor);
}
-void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor, EmitArgs& args) {
- this->internalEmitChild(childIndex, inputColor, args.fOutputColor, args);
+void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor, EmitArgs& args) {
+ while (childIndex >= (int) fFunctionNames.size()) {
+ fFunctionNames.emplace_back();
+ }
+ this->internalInvokeChild(childIndex, inputColor, args.fOutputColor, args);
}
-void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
- SkString* outputColor, EmitArgs& args) {
+void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor,
+ SkString* outputColor, EmitArgs& args) {
SkASSERT(outputColor);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
outputColor->append(fragBuilder->getMangleString());
fragBuilder->codeAppendf("half4 %s;", outputColor->c_str());
- this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args);
+ while (childIndex >= (int) fFunctionNames.size()) {
+ fFunctionNames.emplace_back();
+ }
+ if (fFunctionNames[childIndex].size() == 0) {
+ this->internalInvokeChild(childIndex, inputColor, outputColor->c_str(), args);
+ } else {
+ fragBuilder->codeAppendf("%s = %s(%s);", outputColor->c_str(),
+ fFunctionNames[childIndex].c_str(),
+ inputColor ? inputColor : "half4(1)");
+ }
}
-void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor,
- const char* outputColor, EmitArgs& args) {
+void GrGLSLFragmentProcessor::internalInvokeChild(int childIndex, const char* inputColor,
+ const char* outputColor, EmitArgs& args) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated
@@ -48,24 +60,24 @@
const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
- // emit the code for the child in its own scope
- fragBuilder->codeAppend("{\n");
- fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
- fragBuilder->getMangleString().c_str(), childProc.name());
TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
- // EmitArgs properly updates inputColor to half4(1) if it was null
EmitArgs childArgs(fragBuilder,
args.fUniformHandler,
args.fShaderCaps,
childProc,
outputColor,
- inputName.size() > 0 ? inputName.c_str() : nullptr,
+ "_input",
coordVars,
textureSamplers);
- this->childProcessor(childIndex)->emitCode(childArgs);
- fragBuilder->codeAppend("}\n");
+ 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)");
fragBuilder->onAfterChildProcEmitCode();
}
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index 4a8ce70..c9971a2 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -136,31 +136,31 @@
return fChildProcessors[index];
}
- // Emit the child with the default input color (solid white)
- inline void emitChild(int childIndex, SkString* outputColor, EmitArgs& parentArgs) {
- this->emitChild(childIndex, nullptr, outputColor, parentArgs);
+ // 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);
}
- /** Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and
- * emitChild will automatically extract the coords and samplers of that child and pass them
- * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will
- * have their names mangled to prevent redefinitions. The output color name is also mangled
- * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is
- * legal to pass nullptr as inputColor, since all fragment processors are required to work
- * without an input color.
+ /** Invokes a child proc in its own scope. Pass in the parent's EmitArgs and invokeChild will
+ * automatically extract the coords and samplers of that child and pass them on to the child's
+ * emitCode(). Also, any uniforms or functions emitted by the child will have their names
+ * mangled to prevent redefinitions. The output color name is also mangled therefore in an
+ * in/out param. It will be declared in mangled form by invokeChild(). It is legal to pass
+ * nullptr as inputColor, since all fragment processors are required to work without an input
+ * color.
*/
- void emitChild(int childIndex, const char* inputColor, SkString* outputColor,
- EmitArgs& parentArgs);
+ void invokeChild(int childIndex, const char* inputColor, SkString* outputColor,
+ EmitArgs& parentArgs);
// Use the parent's output color to hold child's output, and use the
// default input color of solid white
- inline void emitChild(int childIndex, EmitArgs& args) {
+ inline void invokeChild(int childIndex, EmitArgs& args) {
// null pointer cast required to disambiguate the function call
- this->emitChild(childIndex, (const char*) nullptr, args);
+ this->invokeChild(childIndex, (const char*) nullptr, args);
}
/** Variation that uses the parent's output color variable to hold the child's output.*/
- void emitChild(int childIndex, const char* inputColor, EmitArgs& parentArgs);
+ void invokeChild(int childIndex, const char* inputColor, EmitArgs& parentArgs);
/**
* Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
@@ -189,7 +189,10 @@
virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
private:
- void internalEmitChild(int, const char*, const char*, EmitArgs&);
+ void internalInvokeChild(int, const char*, const char*, EmitArgs&);
+
+ // one per child; either not present or empty string if not yet emitted
+ SkTArray<SkString> fFunctionNames;
SkTArray<GrGLSLFragmentProcessor*, true> fChildProcessors;
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index 2b6894a..986ad37 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -156,6 +156,26 @@
this->codeAppendf("}");
}
+SkString GrGLSLFPFragmentBuilder::writeProcessorFunction(GrGLSLFragmentProcessor* fp,
+ GrGLSLFragmentProcessor::EmitArgs& args) {
+ this->onBeforeChildProcEmitCode();
+ this->nextStage();
+ this->codeAppendf("half4 %s;\n", args.fOutputColor);
+ fp->emitCode(args);
+ this->codeAppendf("return %s;", args.fOutputColor);
+ GrShaderVar inColor(args.fInputColor, kHalf4_GrSLType);
+ SkString result;
+ this->emitFunction(kHalf4_GrSLType,
+ "stage",
+ 1,
+ &inColor,
+ this->code().c_str(),
+ &result);
+ this->deleteStage();
+ this->onAfterChildProcEmitCode();
+ return result;
+}
+
const char* GrGLSLFragmentShaderBuilder::dstColor() {
SkDEBUGCODE(fHasReadDstColorThisStage_DebugOnly = true;)
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index 050029c..e454fc8 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -10,6 +10,7 @@
#include "include/gpu/GrBlend.h"
#include "src/gpu/GrProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLShaderBuilder.h"
class GrRenderTarget;
@@ -97,6 +98,9 @@
virtual void onBeforeChildProcEmitCode() = 0;
virtual void onAfterChildProcEmitCode() = 0;
+ virtual SkString writeProcessorFunction(GrGLSLFragmentProcessor* fp,
+ GrGLSLFragmentProcessor::EmitArgs& args);
+
virtual const SkString& getMangleString() const = 0;
virtual void forceHighPrecision() = 0;
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index 0086e85..959d24a 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -198,6 +198,11 @@
fCodeIndex++;
}
+ void deleteStage() {
+ fShaderStrings.pop_back();
+ fCodeIndex--;
+ }
+
SkString& extensions() { return fShaderStrings[kExtensions]; }
SkString& definitions() { return fShaderStrings[kDefinitions]; }
SkString& precisionQualifier() { return fShaderStrings[kPrecisionQualifier]; }
diff --git a/src/gpu/gradients/generated/GrClampedGradientEffect.cpp b/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
index 7bb2452..fb9369e 100644
--- a/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
+++ b/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
@@ -36,7 +36,7 @@
rightBorderColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
kHalf4_GrSLType, "rightBorderColor");
SkString _child1("_child1");
- this->emitChild(_outer.gradLayout_index, &_child1, args);
+ this->invokeChild(_outer.gradLayout_index, &_child1, args);
fragBuilder->codeAppendf(
"half4 t = %s;\nif (!%s && t.y < 0.0) {\n %s = half4(0.0);\n} else if (t.x < "
"0.0) {\n %s = %s;\n} else if (t.x > 1.0) {\n %s = %s;\n} else {",
@@ -48,7 +48,7 @@
args.fUniformHandler->getUniformCStr(rightBorderColorVar));
SkString _input0("t");
SkString _child0("_child0");
- this->emitChild(_outer.colorizer_index, _input0.c_str(), &_child0, args);
+ this->invokeChild(_outer.colorizer_index, _input0.c_str(), &_child0, args);
fragBuilder->codeAppendf("\n %s = %s;\n}\n@if (%s) {\n %s.xyz *= %s.w;\n}\n",
args.fOutputColor, _child0.c_str(),
(_outer.makePremul ? "true" : "false"), args.fOutputColor,
diff --git a/src/gpu/gradients/generated/GrTiledGradientEffect.cpp b/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
index cf5d583..76a0975 100644
--- a/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
+++ b/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
@@ -30,7 +30,7 @@
auto colorsAreOpaque = _outer.colorsAreOpaque;
(void)colorsAreOpaque;
SkString _child1("_child1");
- this->emitChild(_outer.gradLayout_index, &_child1, args);
+ this->invokeChild(_outer.gradLayout_index, &_child1, args);
fragBuilder->codeAppendf(
"half4 t = %s;\nif (!%s && t.y < 0.0) {\n %s = half4(0.0);\n} else {\n @if "
"(%s) {\n half t_1 = t.x - 1.0;\n half tiled_t = (t_1 - 2.0 * "
@@ -43,7 +43,7 @@
args.fOutputColor, (_outer.mirror ? "true" : "false"));
SkString _input0("t");
SkString _child0("_child0");
- this->emitChild(_outer.colorizer_index, _input0.c_str(), &_child0, args);
+ this->invokeChild(_outer.colorizer_index, _input0.c_str(), &_child0, args);
fragBuilder->codeAppendf("\n %s = %s;\n}\n@if (%s) {\n %s.xyz *= %s.w;\n}\n",
args.fOutputColor, _child0.c_str(),
(_outer.makePremul ? "true" : "false"), args.fOutputColor,
diff --git a/src/shaders/SkLightingShader.cpp b/src/shaders/SkLightingShader.cpp
index fc8dff8..4614431 100644
--- a/src/shaders/SkLightingShader.cpp
+++ b/src/shaders/SkLightingShader.cpp
@@ -166,7 +166,7 @@
fragBuilder->codeAppendf("half4 diffuseColor = %s;", args.fInputColor);
SkString dstNormalName("dstNormal");
- this->emitChild(0, &dstNormalName, args);
+ this->invokeChild(0, &dstNormalName, args);
fragBuilder->codeAppendf("float3 normal = %s.xyz;", dstNormalName.c_str());
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index c7846ad..f564f3c 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -431,16 +431,16 @@
// Set to the empty string when no input color parameter should be emitted, which means this
// must be properly formatted with a prefixed comma when the parameter should be inserted
- // into the emitChild() parameter list.
+ // into the invokeChild() parameter list.
String inputArg;
if (c.fArguments.size() > 1) {
SkASSERT(c.fArguments.size() == 2);
- // Use the emitChild() variant that accepts an input color, so convert the 2nd
+ // Use the invokeChild() variant that accepts an input color, so convert the 2nd
// argument's expression into C++ code that produces sksl stored in an SkString.
String inputName = "_input" + to_string(index);
addExtraEmitCodeLine(convertSKSLExpressionToCPP(*c.fArguments[1], inputName));
- // emitChild() needs a char*
+ // invokeChild() needs a char*
inputArg = ", " + inputName + ".c_str()";
}
@@ -450,7 +450,7 @@
if (c.fArguments[0]->fType.kind() == Type::kNullable_Kind) {
addExtraEmitCodeLine("if (_outer." + String(child.fName) + "_index >= 0) {\n ");
}
- addExtraEmitCodeLine("this->emitChild(_outer." + String(child.fName) + "_index" +
+ addExtraEmitCodeLine("this->invokeChild(_outer." + String(child.fName) + "_index" +
inputArg + ", &" + childName + ", args);");
if (c.fArguments[0]->fType.kind() == Type::kNullable_Kind) {
// Null FPs are not emitted, but their output can still be referenced in dependent
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 2f2989b..1079d96 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -1035,6 +1035,8 @@
}
void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
+ fSetupFragPositionLocal = false;
+ fSetupFragCoordWorkaround = false;
if (fProgramKind != Program::kPipelineStage_Kind) {
this->writeTypePrecision(f.fDeclaration.fReturnType);
this->writeType(f.fDeclaration.fReturnType);
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index df5455c..4b625a3 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -244,6 +244,11 @@
this->write("_globals");
separator = ", ";
}
+ if (this->requirements(c.fFunction) & kFragCoord_Requirement) {
+ this->write(separator);
+ this->write("_fragCoord");
+ separator = ", ";
+ }
for (size_t i = 0; i < c.fArguments.size(); ++i) {
const Expression& arg = *c.fArguments[i];
this->write(separator);
@@ -499,8 +504,8 @@
void MetalCodeGenerator::writeFragCoord() {
if (fProgram.fInputs.fRTHeight) {
- this->write("float4(_fragCoord.x, _anonInterface0.u_skRTHeight - _fragCoord.y, 0.0, "
- "_fragCoord.w)");
+ this->write("float4(_fragCoord.x, _globals->_anonInterface0->u_skRTHeight - "
+ "_fragCoord.y, 0.0, _fragCoord.w)");
} else {
this->write("float4(_fragCoord.x, _fragCoord.y, 0.0, _fragCoord.w)");
}
@@ -853,25 +858,31 @@
this->write(" ");
this->writeName(f.fDeclaration.fName);
this->write("(");
- if (this->requirements(f.fDeclaration) & kInputs_Requirement) {
+ Requirements requirements = this->requirements(f.fDeclaration);
+ if (requirements & kInputs_Requirement) {
this->write("Inputs _in");
separator = ", ";
}
- if (this->requirements(f.fDeclaration) & kOutputs_Requirement) {
+ if (requirements & kOutputs_Requirement) {
this->write(separator);
this->write("thread Outputs* _out");
separator = ", ";
}
- if (this->requirements(f.fDeclaration) & kUniforms_Requirement) {
+ if (requirements & kUniforms_Requirement) {
this->write(separator);
this->write("Uniforms _uniforms");
separator = ", ";
}
- if (this->requirements(f.fDeclaration) & kGlobals_Requirement) {
+ if (requirements & kGlobals_Requirement) {
this->write(separator);
this->write("thread Globals* _globals");
separator = ", ";
}
+ if (requirements & kFragCoord_Requirement) {
+ this->write(separator);
+ this->write("float4 _fragCoord");
+ separator = ", ";
+ }
}
for (const auto& param : f.fDeclaration.fParameters) {
this->write(separator);
@@ -1543,7 +1554,7 @@
const VariableReference& v = (const VariableReference&) e;
Requirements result = kNo_Requirements;
if (v.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
- result = kInputs_Requirement;
+ result = kGlobals_Requirement | kFragCoord_Requirement;
} else if (Variable::kGlobal_Storage == v.fVariable.fStorage) {
if (v.fVariable.fModifiers.fFlags & Modifiers::kIn_Flag) {
result = kInputs_Requirement;
diff --git a/src/sksl/SkSLMetalCodeGenerator.h b/src/sksl/SkSLMetalCodeGenerator.h
index a777a51..1cf4198 100644
--- a/src/sksl/SkSLMetalCodeGenerator.h
+++ b/src/sksl/SkSLMetalCodeGenerator.h
@@ -90,11 +90,12 @@
protected:
typedef int Requirements;
- static constexpr Requirements kNo_Requirements = 0;
- static constexpr Requirements kInputs_Requirement = 1 << 0;
- static constexpr Requirements kOutputs_Requirement = 1 << 1;
- static constexpr Requirements kUniforms_Requirement = 1 << 2;
- static constexpr Requirements kGlobals_Requirement = 1 << 3;
+ static constexpr Requirements kNo_Requirements = 0;
+ static constexpr Requirements kInputs_Requirement = 1 << 0;
+ static constexpr Requirements kOutputs_Requirement = 1 << 1;
+ static constexpr Requirements kUniforms_Requirement = 1 << 2;
+ static constexpr Requirements kGlobals_Requirement = 1 << 3;
+ static constexpr Requirements kFragCoord_Requirement = 1 << 4;
enum IntrinsicKind {
kSpecial_IntrinsicKind,
diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
index 113cee6..424dff6 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -100,7 +100,7 @@
}
}
SkASSERT(found);
- fExtraEmitCodeCode += " this->emitChild(" + to_string(index) + ", fChildren[" +
+ fExtraEmitCodeCode += " this->invokeChild(" + to_string(index) + ", fChildren[" +
to_string(index) + "], args);\n";
this->write("%s");
fFormatArgs->push_back(Compiler::FormatArg(Compiler::FormatArg::Kind::kChildProcessor,