SkSL sample() now permits specification of coordinates

Bug: skia:
Change-Id: I16073008ac852f1864bd1d2bd38087a5b661d05a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/232581
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index dec2c96..e5e97de 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "src/gpu/GrCoordTransform.h"
 #include "src/gpu/GrFragmentProcessor.h"
 #include "src/gpu/GrProcessor.h"
 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
@@ -16,15 +17,36 @@
     this->onSetData(pdman, processor);
 }
 
-void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor, EmitArgs& args) {
+void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor, EmitArgs& args,
+                                          SkSL::String skslCoords) {
     while (childIndex >= (int) fFunctionNames.size()) {
         fFunctionNames.emplace_back();
     }
-    this->internalInvokeChild(childIndex, inputColor, args.fOutputColor, args);
+    this->internalInvokeChild(childIndex, inputColor, args.fOutputColor, args, skslCoords);
+}
+
+void GrGLSLFragmentProcessor::writeChildCall(GrGLSLFPFragmentBuilder* fragBuilder, int childIndex,
+                                             TransformedCoordVars coordVars, const char* inputColor,
+                                             const char* outputColor, EmitArgs& args,
+                                             SkSL::String skslCoords) {
+    std::vector<SkString> coordParams;
+    for (int i = 0; i < coordVars.count(); ++i) {
+        coordParams.push_back(fragBuilder->ensureCoords2D(coordVars[i].fVaryingPoint));
+    }
+    // if the fragment processor is invoked with overridden coordinates, it must *always* be invoked
+    // with overridden coords
+    SkASSERT(args.fFp.computeLocalCoordsInVertexShader() == (skslCoords.length() == 0));
+    fragBuilder->codeAppendf("%s = %s(%s", outputColor, fFunctionNames[childIndex].c_str(),
+                             inputColor ? inputColor : "half4(1)");
+    if (skslCoords.length()) {
+        fragBuilder->codeAppendf(", %s", skslCoords.c_str());
+    }
+    fragBuilder->codeAppend(");\n");
 }
 
 void GrGLSLFragmentProcessor::invokeChild(int childIndex, const char* inputColor,
-                                          SkString* outputColor, EmitArgs& args) {
+                                          SkString* outputColor, EmitArgs& args,
+                                          SkSL::String skslCoords) {
     SkASSERT(outputColor);
     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
     outputColor->append(fragBuilder->getMangleString());
@@ -32,17 +54,32 @@
     while (childIndex >= (int) fFunctionNames.size()) {
         fFunctionNames.emplace_back();
     }
+    if (!args.fFp.computeLocalCoordsInVertexShader() && skslCoords.length() == 0) {
+        skslCoords = "_coords";
+    }
     if (fFunctionNames[childIndex].size() == 0) {
-        this->internalInvokeChild(childIndex, inputColor, outputColor->c_str(), args);
+        this->internalInvokeChild(childIndex, inputColor, outputColor->c_str(), args, skslCoords);
     } else {
-        fragBuilder->codeAppendf("%s = %s(%s);", outputColor->c_str(),
-                                 fFunctionNames[childIndex].c_str(),
-                                 inputColor ? inputColor : "half4(1)");
+        const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
+
+        TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
+        TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
+        EmitArgs childArgs(fragBuilder,
+                           args.fUniformHandler,
+                           args.fShaderCaps,
+                           childProc,
+                           outputColor->c_str(),
+                           "_input",
+                           coordVars,
+                           textureSamplers);
+        this->writeChildCall(fragBuilder, childIndex, coordVars, inputColor, outputColor->c_str(),
+                             childArgs, skslCoords);
     }
 }
 
 void GrGLSLFragmentProcessor::internalInvokeChild(int childIndex, const char* inputColor,
-                                                  const char* outputColor, EmitArgs& args) {
+                                                  const char* outputColor, EmitArgs& args,
+                                                  SkSL::String skslCoords) {
     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
 
     fragBuilder->onBeforeChildProcEmitCode();  // call first so mangleString is updated
@@ -59,7 +96,6 @@
     }
 
     const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
-
     TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
     TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
 
@@ -74,11 +110,8 @@
     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)");
-
+    this->writeChildCall(fragBuilder, childIndex, coordVars, inputColor, outputColor, childArgs,
+                         skslCoords);
     fragBuilder->onAfterChildProcEmitCode();
 }