Revert "Revert "Revert "Put top level FPs into their own functions"""

Flutter saw a substantial perf regression:
https://github.com/flutter/flutter/issues/62447

This reverts commit 7a96c2a6bb374b36ddf633b529c303e731e7467b.

Change-Id: Ib7d73f2df429508d85f9681eb2f0afd84917772e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/307782
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 19edaca..a0620aa 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -159,6 +159,11 @@
     AutoStageAdvance adv(this);
     this->nameExpression(&output, "output");
 
+    // Enclose custom code in a block to avoid namespace conflicts
+    SkString openBrace;
+    openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name());
+    fFS.codeAppend(openBrace.c_str());
+
     int samplerIdx = 0;
     for (auto [subFP, subGLSLFP] : GrGLSLFragmentProcessor::ParallelRange(fp, glslFP)) {
         if (auto* te = subFP.asTextureEffect()) {
@@ -178,17 +183,42 @@
                                            this->uniformHandler(),
                                            this->shaderCaps(),
                                            fp,
-                                           "_output",
-                                           "_input",
+                                           output.c_str(),
+                                           input.c_str(),
                                            "_coords",
                                            coords);
-    auto name = fFS.writeProcessorFunction(&glslFP, args);
-    fFS.codeAppendf("%s = %s(%s);", output.c_str(), name.c_str(), input.c_str());
+
+    if (fp.referencesSampleCoords()) {
+        // The fp's generated code expects a _coords variable, but we're at the root so _coords
+        // is just the local coordinates produced by the primitive processor.
+        SkASSERT(fp.usesVaryingCoordsDirectly());
+
+        const GrShaderVar& varying = coordVars[0];
+        switch(varying.getType()) {
+            case kFloat2_GrSLType:
+                fFS.codeAppendf("float2 %s = %s.xy;\n",
+                                args.fSampleCoord, varying.getName().c_str());
+                break;
+            case kFloat3_GrSLType:
+                fFS.codeAppendf("float2 %s = %s.xy / %s.z;\n",
+                                args.fSampleCoord,
+                                varying.getName().c_str(),
+                                varying.getName().c_str());
+                break;
+            default:
+                SkDEBUGFAILF("Unexpected type for varying: %d named %s\n",
+                             (int) varying.getType(), varying.getName().c_str());
+                break;
+        }
+    }
+
+    glslFP.emitCode(args);
 
     // We have to check that effects and the code they emit are consistent, ie if an effect
     // asks for dst color, then the emit code needs to follow suit
     SkDEBUGCODE(verify(fp);)
 
+    fFS.codeAppend("}");
     return output;
 }