Fix implicit references to _input when GrSkSLFP invokes children
This actually solves two different bugs: 1) A call to sample(child) in a helper function would fail to compile. We were invoking the child's entry point with the default color argument of args.fInputColor. That was "_input", which is a parameter to our main. 2) The runtime effect's FP hard-wired references to the main color parameter to args.fInputColor (via a builtin id). This meant that the user code could change the variable, then call sample and have those changes visible to the child. That shoudln't happen (unless you actually pass a color to the child explicitly). Doing this with an extra global variable is somewhat ugly, and adds some overhead. Hopefully the driver is able to see through it and optimize this. Bug: skia:10506 Change-Id: I11d152bd9f8b270afd53d3bfa71d2e728c8fd729 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/397154 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
829de5b409
commit
ce585026db
@ -37,8 +37,11 @@ public:
|
||||
|
||||
class FPCallbacks : public SkSL::PipelineStage::Callbacks {
|
||||
public:
|
||||
FPCallbacks(GrGLSLSkSLFP* self, EmitArgs& args, const SkSL::Context& context)
|
||||
: fSelf(self), fArgs(args), fContext(context) {}
|
||||
FPCallbacks(GrGLSLSkSLFP* self,
|
||||
EmitArgs& args,
|
||||
const char* inputColor,
|
||||
const SkSL::Context& context)
|
||||
: fSelf(self), fArgs(args), fInputColor(inputColor), fContext(context) {}
|
||||
|
||||
using String = SkSL::String;
|
||||
|
||||
@ -93,7 +96,7 @@ public:
|
||||
}
|
||||
|
||||
String sampleChild(int index, String coords) override {
|
||||
return String(fSelf->invokeChild(index, fArgs, coords).c_str());
|
||||
return String(fSelf->invokeChild(index, fInputColor, fArgs, coords).c_str());
|
||||
}
|
||||
|
||||
String sampleChildWithMatrix(int index, String matrix) override {
|
||||
@ -104,16 +107,25 @@ public:
|
||||
const GrFragmentProcessor* child = fArgs.fFp.childProcessor(index);
|
||||
const bool hasUniformMatrix = child && child->sampleUsage().hasUniformMatrix();
|
||||
return String(
|
||||
fSelf->invokeChildWithMatrix(index, fArgs, hasUniformMatrix ? "" : matrix)
|
||||
fSelf->invokeChildWithMatrix(
|
||||
index, fInputColor, fArgs, hasUniformMatrix ? "" : matrix)
|
||||
.c_str());
|
||||
}
|
||||
|
||||
GrGLSLSkSLFP* fSelf;
|
||||
EmitArgs& fArgs;
|
||||
const char* fInputColor;
|
||||
const SkSL::Context& fContext;
|
||||
};
|
||||
|
||||
FPCallbacks callbacks(this, args, *program.fContext);
|
||||
// Snap off a global copy of the input color at the start of main. We need this when
|
||||
// we call child processors (particularly from helper functions, which can't "see" the
|
||||
// parameter to main). Even from within main, if the code mutates the parameter, calls to
|
||||
// sample should still be passing the original color (by default).
|
||||
GrShaderVar inputColorCopy(args.fFragBuilder->getMangledFunctionName("inColor"),
|
||||
kHalf4_GrSLType);
|
||||
args.fFragBuilder->declareGlobal(inputColorCopy);
|
||||
args.fFragBuilder->codeAppendf("%s = %s;\n", inputColorCopy.c_str(), args.fInputColor);
|
||||
|
||||
// Callback to define a function (and return its mangled name)
|
||||
SkString coordsVarName = args.fFragBuilder->newTmpVarName("coords");
|
||||
@ -123,6 +135,7 @@ public:
|
||||
args.fFragBuilder->codeAppendf("float2 %s = %s;\n", coords, args.fSampleCoord);
|
||||
}
|
||||
|
||||
FPCallbacks callbacks(this, args, inputColorCopy.c_str(), *program.fContext);
|
||||
SkSL::PipelineStage::ConvertProgram(program, coords, args.fInputColor, &callbacks);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user