emitChild() used to generate a mangled outputColor based on the parent's outputColor...
authorwangyix <wangyix@google.com>
Tue, 8 Sep 2015 15:41:51 +0000 (08:41 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 8 Sep 2015 15:41:51 +0000 (08:41 -0700)
BUG=skia:4182

Review URL: https://codereview.chromium.org/1321253003

src/core/SkComposeShader.cpp
src/gpu/effects/GrExtractAlphaFragmentProcessor.cpp
src/gpu/gl/GrGLFragmentProcessor.cpp
src/gpu/gl/GrGLFragmentProcessor.h
src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
src/gpu/gl/builders/GrGLFragmentShaderBuilder.h

index 095dca2..50fc6aa 100644 (file)
@@ -283,18 +283,23 @@ void GrGLComposeEffect::emitCode(EmitArgs& args) {
     fsBuilder->codeAppendf("float %s = %s.a;", inputAlpha.c_str(), args.fInputColor);
     fsBuilder->codeAppendf("%s /= %s.a;", args.fInputColor, args.fInputColor);
 
-    // emit the code of the two child shaders
-    SkString mangledOutputColorA;
-    this->emitChild(0, args.fInputColor, &mangledOutputColorA, args);
-    SkString mangledOutputColorB;
-    this->emitChild(1, args.fInputColor, &mangledOutputColorB, args);
+    // declare outputColor and emit the code for each of the two children
+    SkString outputColorA(args.fOutputColor);
+    outputColorA.append("_dst");
+    fsBuilder->codeAppendf("vec4 %s;\n", outputColorA.c_str());
+    this->emitChild(0, args.fInputColor, outputColorA.c_str(), args);
+
+    SkString outputColorB(args.fOutputColor);
+    outputColorB.append("_src");
+    fsBuilder->codeAppendf("vec4 %s;\n", outputColorB.c_str());
+    this->emitChild(1, args.fInputColor, outputColorB.c_str(), args);
 
     // emit blend code
     SkXfermode::Mode mode = cs.getMode();
     fsBuilder->codeAppend("{");
     fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
-    GrGLBlend::AppendPorterDuffBlend(fsBuilder, mangledOutputColorB.c_str(),
-                                     mangledOutputColorA.c_str(), args.fOutputColor, mode);
+    GrGLBlend::AppendPorterDuffBlend(fsBuilder, outputColorB.c_str(),
+                                     outputColorA.c_str(), args.fOutputColor, mode);
     fsBuilder->codeAppend("}");
 
     // re-multiply the output color by the input color's alpha
index 3414df2..c5ee9b8 100644 (file)
@@ -16,9 +16,7 @@ public:
     void emitCode(EmitArgs& args) override {
         GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
         fsBuilder->codeAppendf("vec4 alpha4 = %s.aaaa;", args.fInputColor);
-        SkString output;
-        this->emitChild(0, "alpha4", &output, args);
-        fsBuilder->codeAppendf("%s = %s;", args.fOutputColor, output.c_str());
+        this->emitChild(0, "alpha4", args.fOutputColor, args);
     }
 
 private:
index 078491a..6d91c72 100644 (file)
@@ -20,16 +20,12 @@ void GrGLFragmentProcessor::setData(const GrGLProgramDataManager& pdman,
 }
 
 void GrGLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
-                                      SkString* outputColor, EmitArgs& args) {
+                                      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);
 
-    // Mangle the name of the outputColor
-    outputColor->set(args.fOutputColor);
-    outputColor->append(fb->getMangleStringThisLevel());
-
     /*
      * We now want to find the subset of coords and samplers that belong to the child and its
      * descendants and put that into childCoords and childSamplers. To do so, we'll do a forwards
@@ -78,13 +74,12 @@ void GrGLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
     }
 
     // emit the code for the child in its own scope
-    fb->codeAppendf("vec4 %s;\n", outputColor->c_str());
     fb->codeAppend("{\n");
     fb->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
                     fb->getMangleString().c_str(), childProc.name());
     EmitArgs childArgs(args.fBuilder,
                        childProc,
-                       outputColor->c_str(),
+                       outputColor,
                        inputColor,
                        childCoords,
                        childSamplers);
index b8e2afc..e11d28b 100644 (file)
@@ -80,7 +80,12 @@ public:
         return fChildProcessors[index];
     }
 
-    void emitChild(int childIndex, const char* inputColor, SkString* outputColor, EmitArgs& args);
+    /** 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.
+     */
+    void emitChild(int childIndex, const char* inputColor, const char* outputColor, EmitArgs& args);
 
 protected:
     /** A GrGLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
index 20bb3a3..a5b3a99 100644 (file)
@@ -302,13 +302,17 @@ void GrGLFragmentShaderBuilder::addVarying(GrGLVarying* v, GrSLPrecision fsPrec)
 }
 
 void GrGLFragmentBuilder::onBeforeChildProcEmitCode() {
-    fSubstageIndices.back()++;
+    SkASSERT(fSubstageIndices.count() >= 1);
     fSubstageIndices.push_back(0);
-    fMangleString.append(this->getMangleStringThisLevel());
+    // second-to-last value in the fSubstageIndices stack is the index of the child proc
+    // at that level which is currently emitting code.
+    fMangleString.appendf("_c%d", fSubstageIndices[fSubstageIndices.count() - 2]);
 }
 
 void GrGLFragmentBuilder::onAfterChildProcEmitCode() {
+    SkASSERT(fSubstageIndices.count() >= 2);
     fSubstageIndices.pop_back();
+    fSubstageIndices.back()++;
     int removeAt = fMangleString.findLastOf('_');
     fMangleString.remove(removeAt, fMangleString.size() - removeAt);
 }
index 912de0a..4f17b68 100644 (file)
@@ -57,26 +57,8 @@ public:
     void onBeforeChildProcEmitCode();
     void onAfterChildProcEmitCode();
 
-    int getChildNumberThisLevel() const {
-        if (fSubstageIndices.count() > 1) {
-            // second-to-last value in the fSubstageIndices stack is the index of the child proc
-            // at that level which is currently emitting code.
-            return fSubstageIndices[fSubstageIndices.count() - 2];
-        }
-        return -1;
-    }
-
     const SkString& getMangleString() const { return fMangleString; }
 
-    SkString getMangleStringThisLevel() const {
-        SkString ret;
-        int childNumber = this->getChildNumberThisLevel();
-        if (childNumber >= 0) {
-            ret.printf("_c%d", childNumber);
-        }
-        return ret;
-    }
-
 private:
     /*
      * State that tracks which child proc in the proc tree is currently emitting code.  This is