From 38ddbadd00d60576f29d2ca33316b4626c9b0470 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Thu, 24 Sep 2015 06:00:00 -0700 Subject: Mangle output var in GrGLFragmentProcessor::emitChild R=joshualitt@google.com Review URL: https://codereview.chromium.org/1362873002 --- src/effects/SkArithmeticMode_gpu.cpp | 6 ++--- src/gpu/effects/GrXfermodeFragmentProcessor.cpp | 29 +++++++++---------------- src/gpu/gl/GrGLFragmentProcessor.cpp | 17 ++++++++++++++- src/gpu/gl/GrGLFragmentProcessor.h | 19 +++++++++++----- 4 files changed, 43 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/effects/SkArithmeticMode_gpu.cpp b/src/effects/SkArithmeticMode_gpu.cpp index 5f149d0712..ab447e7548 100644 --- a/src/effects/SkArithmeticMode_gpu.cpp +++ b/src/effects/SkArithmeticMode_gpu.cpp @@ -60,15 +60,15 @@ public: void emitCode(EmitArgs& args) override { GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); - fsBuilder->codeAppend("vec4 _dstColor;"); - this->emitChild(0, nullptr, "_dstColor", args); + SkString dstColor("dstColor"); + this->emitChild(0, nullptr, &dstColor, args); fKUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec4f_GrSLType, kDefault_GrSLPrecision, "k"); const char* kUni = args.fBuilder->getUniformCStr(fKUni); - add_arithmetic_code(fsBuilder, args.fInputColor, "_dstColor", args.fOutputColor, kUni, + add_arithmetic_code(fsBuilder, args.fInputColor, dstColor.c_str(), args.fOutputColor, kUni, fEnforcePMColor); } diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp index 942251c980..2bd641247f 100644 --- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp +++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp @@ -106,23 +106,16 @@ void GLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) { } // declare outputColor and emit the code for each of the two children - SkString outputColorSrc(args.fOutputColor); - outputColorSrc.append("_src"); - fsBuilder->codeAppendf("vec4 %s;\n", outputColorSrc.c_str()); - this->emitChild(0, opaqueInput, outputColorSrc.c_str(), args); + SkString srcColor("src"); + this->emitChild(0, opaqueInput, &srcColor, args); - SkString outputColorDst(args.fOutputColor); - outputColorDst.append("_dst"); - fsBuilder->codeAppendf("vec4 %s;\n", outputColorDst.c_str()); - this->emitChild(1, opaqueInput, outputColorDst.c_str(), args); + SkString dstColor("dst"); + this->emitChild(1, opaqueInput, &dstColor, args); // emit blend code SkXfermode::Mode mode = cs.getMode(); - fsBuilder->codeAppend("{"); fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode)); - GrGLSLBlend::AppendMode(fsBuilder, outputColorSrc.c_str(), - outputColorDst.c_str(), args.fOutputColor, mode); - fsBuilder->codeAppend("}"); + GrGLSLBlend::AppendMode(fsBuilder, srcColor.c_str(), dstColor.c_str(), args.fOutputColor, mode); // re-multiply the output color by the input color's alpha if (inputAlpha) { @@ -237,9 +230,8 @@ public: SkXfermode::Mode mode = args.fFp.cast().mode(); ComposeOneFragmentProcessor::Child child = args.fFp.cast().child(); - // declare _dstColor and emit the code for the two child - fsBuilder->codeAppendf("vec4 _child;"); - this->emitChild(0, nullptr, "_child", args); + SkString childColor("child"); + this->emitChild(0, nullptr, &childColor, args); const char* inputColor = args.fInputColor; // We don't try to optimize for this case at all @@ -249,14 +241,13 @@ public: } // emit blend code - fsBuilder->codeAppend("{"); fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode)); + const char* childStr = childColor.c_str(); if (ComposeOneFragmentProcessor::kDst_Child == child) { - GrGLSLBlend::AppendMode(fsBuilder, inputColor, "_child", args.fOutputColor, mode); + GrGLSLBlend::AppendMode(fsBuilder, inputColor, childStr, args.fOutputColor, mode); } else { - GrGLSLBlend::AppendMode(fsBuilder, "_child", inputColor, args.fOutputColor, mode); + GrGLSLBlend::AppendMode(fsBuilder, childStr, inputColor, args.fOutputColor, mode); } - fsBuilder->codeAppend("}"); } private: diff --git a/src/gpu/gl/GrGLFragmentProcessor.cpp b/src/gpu/gl/GrGLFragmentProcessor.cpp index 6d91c72fcf..225e5bffff 100644 --- a/src/gpu/gl/GrGLFragmentProcessor.cpp +++ b/src/gpu/gl/GrGLFragmentProcessor.cpp @@ -19,9 +19,24 @@ void GrGLFragmentProcessor::setData(const GrGLProgramDataManager& pdman, } } +void GrGLFragmentProcessor::emitChild(int childIndex, const char* inputColor, EmitArgs& args) { + this->internalEmitChild(childIndex, inputColor, args.fOutputColor, args); +} + void GrGLFragmentProcessor::emitChild(int childIndex, const char* inputColor, - const char* outputColor, EmitArgs& args) { + SkString* outputColor, EmitArgs& args) { + + SkASSERT(outputColor); GrGLFragmentBuilder* fb = args.fBuilder->getFragmentShaderBuilder(); + outputColor->append(fb->getMangleString()); + fb->codeAppendf("vec4 %s;", outputColor->c_str()); + this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args); +} + +void GrGLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor, + const char* outputColor, EmitArgs& args) { + GrGLFragmentBuilder* fb = args.fBuilder->getFragmentShaderBuilder(); + fb->onBeforeChildProcEmitCode(); // call first so mangleString is updated const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex); diff --git a/src/gpu/gl/GrGLFragmentProcessor.h b/src/gpu/gl/GrGLFragmentProcessor.h index e11d28b26b..1e4dd481b3 100644 --- a/src/gpu/gl/GrGLFragmentProcessor.h +++ b/src/gpu/gl/GrGLFragmentProcessor.h @@ -45,7 +45,7 @@ public: @param samplers Contains one entry for each GrTextureAccess of the GrProcessor. These can be passed to the builder to emit texture reads in the generated code. - */ + */ struct EmitArgs { EmitArgs(GrGLFPBuilder* builder, @@ -81,11 +81,18 @@ public: } /** 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. + * 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. */ - void emitChild(int childIndex, const char* inputColor, const char* outputColor, EmitArgs& args); + void emitChild(int childIndex, const char* inputColor, SkString* outputColor, + EmitArgs& parentArgs); + + /** Variation that uses the parent's output color variable to hold the child's output.*/ + void emitChild(int childIndex, const char* inputColor, EmitArgs& parentArgs); protected: /** A GrGLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces @@ -97,6 +104,8 @@ protected: virtual void onSetData(const GrGLProgramDataManager&, const GrProcessor&) {} private: + void internalEmitChild(int, const char*, const char*, EmitArgs&); + SkTArray fChildProcessors; friend class GrFragmentProcessor; -- cgit v1.2.3