Add separate src and dst arguments to runtime-blend SkSL functions.

When called in the typical FP context, we only have a paint color, not a
separate source and destination color. So we pass the paint color in
each slot. This seems counterintuitive, but the upshot is that a runtime
blender will now pass the paint color as the input color to the source
effect and dest effect. (In a followup CL, sampling directly from a
runtime blender will allow distinct values to be passed into each slot,
and these values will be honored as-is.)

Change-Id: I96b016527d1066f0431a763f6609c3983b4854ec
Bug: skia:12257
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/433516
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 30e14b9..1b08730 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -175,6 +175,20 @@
                                            this->invokeChild(fp.fInputChildIndex, args).c_str());
         }
 
+        if (fp.fEffect->allowBlender()) {
+            // If we have an dest-color child, we invoke it now, and make the result of that be the
+            // "dest color" for all other purposes later.
+            if (fp.fDestColorChildIndex >= 0) {
+                args.fFragBuilder->codeAppendf(
+                        "%s = %s;\n",
+                        args.fDestColor,
+                        this->invokeChild(fp.fDestColorChildIndex, args.fDestColor, args).c_str());
+            }
+        } else {
+            // We're not making a blender, so we don't expect a dest-color child FP to exist.
+            SkASSERT(fp.fDestColorChildIndex < 0);
+        }
+
         // 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
@@ -202,17 +216,6 @@
             args.fFragBuilder->codeAppendf("float2 %s = %s;\n", coords, args.fSampleCoord);
         }
 
-        // For runtime blends, the destination color is stored as a child FP.
-        // Invoke that FP here and store it in a local variable.
-        const char* destColor = "half4(1)";
-        SkString destColorVarName;
-        if (fp.fDestColorChildIndex >= 0) {
-            destColorVarName = args.fFragBuilder->newTmpVarName("destColor");
-            destColor = destColorVarName.c_str();
-            SkString childFP = this->invokeChild(fp.fDestColorChildIndex, args);
-            args.fFragBuilder->codeAppendf("half4 %s = %s;", destColor, childFP.c_str());
-        }
-
         FPCallbacks callbacks(this,
                               args,
                               inputColorName.c_str(),
@@ -220,7 +223,7 @@
                               fp.uniformData(),
                               fp.uniformFlags());
         SkSL::PipelineStage::ConvertProgram(
-                program, coords, args.fInputColor, destColor, &callbacks);
+                program, coords, args.fInputColor, args.fDestColor, &callbacks);
     }
 
     void onSetData(const GrGLSLProgramDataManager& pdman,
@@ -285,6 +288,7 @@
     }
     if (destColorFP) {
         fp->setDestColorFP(std::move(destColorFP));
+        fp->setIsBlendFunction();
     }
     return fp;
 }