Replace more instances of sk_OutColor with explicit returns.

Change-Id: Ie6abd063e8954c004c856f555a82937ff4e6c0a8
Bug: skia:10549
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344296
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index 399a453..d1d82e9 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -121,9 +121,9 @@
     }
 
 private:
-    const char* name() const override {
-        return "VisualizeCoverageCountFP";
-    }
+    const char* name() const override { return "VisualizeCoverageCountFP"; }
+    bool usesExplicitReturn() const override { return true; }
+
     std::unique_ptr<GrFragmentProcessor> clone() const override {
         return std::unique_ptr<GrFragmentProcessor>(new VisualizeCoverageCountFP(*this));
     }
@@ -144,8 +144,7 @@
             static constexpr int kInputFPIndex = 0;
             SkString inputColor = this->invokeChild(kInputFPIndex, args);
             f->codeAppendf("half count = %s.a;", inputColor.c_str());
-            f->codeAppendf("%s = half4(clamp(-count, 0, 1), clamp(+count, 0, 1), 0, abs(count));",
-                           args.fOutputColor);
+            f->codeAppendf("return half4(saturate(-count), saturate(+count), 0, abs(count));");
         }
     };
 
diff --git a/src/effects/imagefilters/SkLightingImageFilter.cpp b/src/effects/imagefilters/SkLightingImageFilter.cpp
index 15489d3..4e34bd3 100644
--- a/src/effects/imagefilters/SkLightingImageFilter.cpp
+++ b/src/effects/imagefilters/SkLightingImageFilter.cpp
@@ -656,6 +656,7 @@
     }
 
     const char* name() const override { return "DiffuseLighting"; }
+    bool usesExplicitReturn() const override { return true; }
 
     std::unique_ptr<GrFragmentProcessor> clone() const override {
         return std::unique_ptr<GrFragmentProcessor>(new GrDiffuseLightingEffect(*this));
@@ -704,6 +705,7 @@
     }
 
     const char* name() const override { return "SpecularLighting"; }
+    bool usesExplicitReturn() const override { return true; }
 
     std::unique_ptr<GrFragmentProcessor> clone() const override {
         return std::unique_ptr<GrFragmentProcessor>(new GrSpecularLightingEffect(*this));
@@ -1475,65 +1477,65 @@
     SkString result;
     switch (mode) {
     case kTopLeft_BoundaryMode:
-        result.printf("\treturn %s(%s(0.0, 0.0, m[4], m[5], m[7], m[8], %g),\n"
-                      "\t          %s(0.0, 0.0, m[4], m[7], m[5], m[8], %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(0.0, 0.0, m[4], m[5], m[7], m[8], %g),"
+                      "          %s(0.0, 0.0, m[4], m[7], m[5], m[8], %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gTwoThirds,
                                          sobelFuncName, gTwoThirds);
         break;
     case kTop_BoundaryMode:
-        result.printf("\treturn %s(%s(0.0, 0.0, m[3], m[5], m[6], m[8], %g),\n"
-                      "\t          %s(0.0, 0.0, m[4], m[7], m[5], m[8], %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(0.0, 0.0, m[3], m[5], m[6], m[8], %g),"
+                      "          %s(0.0, 0.0, m[4], m[7], m[5], m[8], %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gOneThird,
                                          sobelFuncName, gOneHalf);
         break;
     case kTopRight_BoundaryMode:
-        result.printf("\treturn %s(%s( 0.0,  0.0, m[3], m[4], m[6], m[7], %g),\n"
-                      "\t          %s(m[3], m[6], m[4], m[7],  0.0,  0.0, %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s( 0.0,  0.0, m[3], m[4], m[6], m[7], %g),"
+                      "          %s(m[3], m[6], m[4], m[7],  0.0,  0.0, %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gTwoThirds,
                                          sobelFuncName, gTwoThirds);
         break;
     case kLeft_BoundaryMode:
-        result.printf("\treturn %s(%s(m[1], m[2], m[4], m[5], m[7], m[8], %g),\n"
-                      "\t          %s( 0.0,  0.0, m[1], m[7], m[2], m[8], %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(m[1], m[2], m[4], m[5], m[7], m[8], %g),"
+                      "          %s( 0.0,  0.0, m[1], m[7], m[2], m[8], %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gOneHalf,
                                          sobelFuncName, gOneThird);
         break;
     case kInterior_BoundaryMode:
-        result.printf("\treturn %s(%s(m[0], m[2], m[3], m[5], m[6], m[8], %g),\n"
-                      "\t          %s(m[0], m[6], m[1], m[7], m[2], m[8], %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(m[0], m[2], m[3], m[5], m[6], m[8], %g),"
+                      "          %s(m[0], m[6], m[1], m[7], m[2], m[8], %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gOneQuarter,
                                          sobelFuncName, gOneQuarter);
         break;
     case kRight_BoundaryMode:
-        result.printf("\treturn %s(%s(m[0], m[1], m[3], m[4], m[6], m[7], %g),\n"
-                      "\t          %s(m[0], m[6], m[1], m[7],  0.0,  0.0, %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(m[0], m[1], m[3], m[4], m[6], m[7], %g),"
+                      "          %s(m[0], m[6], m[1], m[7],  0.0,  0.0, %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gOneHalf,
                                          sobelFuncName, gOneThird);
         break;
     case kBottomLeft_BoundaryMode:
-        result.printf("\treturn %s(%s(m[1], m[2], m[4], m[5],  0.0,  0.0, %g),\n"
-                      "\t          %s( 0.0,  0.0, m[1], m[4], m[2], m[5], %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(m[1], m[2], m[4], m[5],  0.0,  0.0, %g),"
+                      "          %s( 0.0,  0.0, m[1], m[4], m[2], m[5], %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gTwoThirds,
                                          sobelFuncName, gTwoThirds);
         break;
     case kBottom_BoundaryMode:
-        result.printf("\treturn %s(%s(m[0], m[2], m[3], m[5],  0.0,  0.0, %g),\n"
-                      "\t          %s(m[0], m[3], m[1], m[4], m[2], m[5], %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(m[0], m[2], m[3], m[5],  0.0,  0.0, %g),"
+                      "          %s(m[0], m[3], m[1], m[4], m[2], m[5], %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gOneThird,
                                          sobelFuncName, gOneHalf);
         break;
     case kBottomRight_BoundaryMode:
-        result.printf("\treturn %s(%s(m[0], m[1], m[3], m[4],  0.0,  0.0, %g),\n"
-                      "\t          %s(m[0], m[3], m[1], m[4],  0.0,  0.0, %g),\n"
-                      "\t          surfaceScale);\n",
+        result.printf("return %s(%s(m[0], m[1], m[3], m[4],  0.0,  0.0, %g),"
+                      "          %s(m[0], m[3], m[1], m[4],  0.0,  0.0, %g),"
+                      "          surfaceScale);",
                       pointToNormalName, sobelFuncName, gTwoThirds,
                                          sobelFuncName, gTwoThirds);
         break;
@@ -1769,7 +1771,7 @@
     fragBuilder->emitFunction(kHalf_GrSLType,
                               sobelFuncName.c_str(),
                               {gSobelArgs, SK_ARRAY_COUNT(gSobelArgs)},
-                              "\treturn (-a + b - 2.0 * c + 2.0 * d -e + f) * scale;\n");
+                              "return (-a + b - 2.0 * c + 2.0 * d -e + f) * scale;");
     const GrShaderVar gPointToNormalArgs[] = {
         GrShaderVar("x", kHalf_GrSLType),
         GrShaderVar("y", kHalf_GrSLType),
@@ -1779,7 +1781,7 @@
     fragBuilder->emitFunction(kHalf3_GrSLType,
                               pointToNormalName.c_str(),
                               {gPointToNormalArgs, SK_ARRAY_COUNT(gPointToNormalArgs)},
-                              "\treturn normalize(half3(-x * scale, -y * scale, 1));\n");
+                              "return normalize(half3(-x * scale, -y * scale, 1));");
 
     const GrShaderVar gInteriorNormalArgs[] = {
         GrShaderVar("m", kHalf_GrSLType, 9),
@@ -1794,8 +1796,8 @@
                               {gInteriorNormalArgs, SK_ARRAY_COUNT(gInteriorNormalArgs)},
                               normalBody.c_str());
 
-    fragBuilder->codeAppendf("\t\tfloat2 coord = %s;\n", args.fSampleCoord);
-    fragBuilder->codeAppend("\t\thalf m[9];\n");
+    fragBuilder->codeAppendf("float2 coord = %s;", args.fSampleCoord);
+    fragBuilder->codeAppend("half m[9];");
 
     const char* surfScale = uniformHandler->getUniformCStr(fSurfaceScaleUni);
 
@@ -1809,15 +1811,15 @@
             index++;
         }
     }
-    fragBuilder->codeAppend("\t\thalf3 surfaceToLight = ");
+    fragBuilder->codeAppend("half3 surfaceToLight = ");
     SkString arg;
     arg.appendf("%s * m[4]", surfScale);
     fLight->emitSurfaceToLight(&le, uniformHandler, fragBuilder, arg.c_str());
-    fragBuilder->codeAppend(";\n");
-    fragBuilder->codeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ",
-                             args.fOutputColor, lightFunc.c_str(), normalName.c_str(), surfScale);
+    fragBuilder->codeAppend(";");
+    fragBuilder->codeAppendf("return %s(%s(m, %s), surfaceToLight, ",
+                             lightFunc.c_str(), normalName.c_str(), surfScale);
     fLight->emitLightColor(&le, uniformHandler, fragBuilder, "surfaceToLight");
-    fragBuilder->codeAppend(");\n");
+    fragBuilder->codeAppend(");");
 }
 
 void GrGLLightingEffect::GenKey(const GrProcessor& proc,
@@ -1856,8 +1858,8 @@
         GrShaderVar("lightColor", kHalf3_GrSLType)
     };
     SkString lightBody;
-    lightBody.appendf("\thalf colorScale = %s * dot(normal, surfaceToLight);\n", kd);
-    lightBody.appendf("\treturn half4(lightColor * saturate(colorScale), 1.0);\n");
+    lightBody.appendf("half colorScale = %s * dot(normal, surfaceToLight);", kd);
+    lightBody.appendf("return half4(lightColor * saturate(colorScale), 1.0);");
     *funcName = fragBuilder->getMangledFunctionName("light");
     fragBuilder->emitFunction(kHalf4_GrSLType,
                               funcName->c_str(),
@@ -1961,11 +1963,11 @@
         GrShaderVar("lightColor", kHalf3_GrSLType)
     };
     SkString lightBody;
-    lightBody.appendf("\thalf3 halfDir = half3(normalize(surfaceToLight + half3(0, 0, 1)));\n");
-    lightBody.appendf("\thalf colorScale = half(%s * pow(dot(normal, halfDir), %s));\n",
+    lightBody.appendf("half3 halfDir = half3(normalize(surfaceToLight + half3(0, 0, 1)));");
+    lightBody.appendf("half colorScale = half(%s * pow(dot(normal, halfDir), %s));",
                       ks, shininess);
-    lightBody.appendf("\thalf3 color = lightColor * saturate(colorScale);\n");
-    lightBody.appendf("\treturn half4(color, max(max(color.r, color.g), color.b));\n");
+    lightBody.appendf("half3 color = lightColor * saturate(colorScale);");
+    lightBody.appendf("return half4(color, max(max(color.r, color.g), color.b));");
     *funcName = fragBuilder->getMangledFunctionName("light");
     fragBuilder->emitFunction(kHalf4_GrSLType,
                               funcName->c_str(),
@@ -2097,16 +2099,16 @@
         GrShaderVar("surfaceToLight", kHalf3_GrSLType)
     };
     SkString lightColorBody;
-    lightColorBody.appendf("\thalf cosAngle = -dot(surfaceToLight, %s);\n", s);
-    lightColorBody.appendf("\tif (cosAngle < %s) {\n", cosOuter);
-    lightColorBody.appendf("\t\treturn half3(0);\n");
-    lightColorBody.appendf("\t}\n");
-    lightColorBody.appendf("\thalf scale = pow(cosAngle, %s);\n", exponent);
-    lightColorBody.appendf("\tif (cosAngle < %s) {\n", cosInner);
-    lightColorBody.appendf("\t\treturn %s * scale * (cosAngle - %s) * %s;\n",
+    lightColorBody.appendf("half cosAngle = -dot(surfaceToLight, %s);", s);
+    lightColorBody.appendf("if (cosAngle < %s) {", cosOuter);
+    lightColorBody.appendf("return half3(0);");
+    lightColorBody.appendf("}");
+    lightColorBody.appendf("half scale = pow(cosAngle, %s);", exponent);
+    lightColorBody.appendf("if (cosAngle < %s) {", cosInner);
+    lightColorBody.appendf("return %s * scale * (cosAngle - %s) * %s;",
                            color, cosOuter, coneScale);
-    lightColorBody.appendf("\t}\n");
-    lightColorBody.appendf("\treturn %s;\n", color);
+    lightColorBody.appendf("}");
+    lightColorBody.appendf("return %s;", color);
     fLightColorFunc = fragBuilder->getMangledFunctionName("lightColor");
     fragBuilder->emitFunction(kHalf3_GrSLType,
                               fLightColorFunc.c_str(),
diff --git a/src/gpu/ccpr/GrCCClipProcessor.cpp b/src/gpu/ccpr/GrCCClipProcessor.cpp
index fe194e5..5dbe89e 100644
--- a/src/gpu/ccpr/GrCCClipProcessor.cpp
+++ b/src/gpu/ccpr/GrCCClipProcessor.cpp
@@ -77,8 +77,8 @@
             fPathIBoundsUniform = uniHandler->addUniform(&proc, kFragment_GrShaderFlag,
                                                          kFloat4_GrSLType, "path_ibounds",
                                                          &pathIBounds);
-            f->codeAppendf("if (all(greaterThan(float4(sk_FragCoord.xy, %s.zw), "
-                                               "float4(%s.xy, sk_FragCoord.xy)))) {",
+            f->codeAppendf("if (all(greaterThan(float4(sk_FragCoord.xy, %s.RB), "
+                                               "float4(%s.LT, sk_FragCoord.xy)))) {",
                                                pathIBounds, pathIBounds);
         }
 
@@ -116,7 +116,7 @@
         constexpr int kInputFPIndex = 1;
         SkString inputColor = this->invokeChild(kInputFPIndex, args);
 
-        f->codeAppendf("%s = %s * coverage;", args.fOutputColor, inputColor.c_str());
+        f->codeAppendf("return %s * coverage;", inputColor.c_str());
     }
 
     void onSetData(const GrGLSLProgramDataManager& pdman,
diff --git a/src/gpu/ccpr/GrCCClipProcessor.h b/src/gpu/ccpr/GrCCClipProcessor.h
index cb28f34..12466f9 100644
--- a/src/gpu/ccpr/GrCCClipProcessor.h
+++ b/src/gpu/ccpr/GrCCClipProcessor.h
@@ -28,6 +28,7 @@
                       IsCoverageCount, MustCheckBounds);
 
     const char* name() const override { return "GrCCClipProcessor"; }
+    bool usesExplicitReturn() const override { return true; }
     std::unique_ptr<GrFragmentProcessor> clone() const override;
     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
     bool onIsEqual(const GrFragmentProcessor&) const override;
diff --git a/src/gpu/effects/GrConfigConversionEffect.fp b/src/gpu/effects/GrConfigConversionEffect.fp
index 87dd6e4..a9c8154 100644
--- a/src/gpu/effects/GrConfigConversionEffect.fp
+++ b/src/gpu/effects/GrConfigConversionEffect.fp
@@ -140,22 +140,24 @@
     fragBuilder->forceHighPrecision();
 }
 
-void main() {
+half4 main() {
     // Aggressively round to the nearest exact (N / 255) floating point value. This lets us find a
     // round-trip preserving pair on some GPUs that do odd byte to float conversion.
-    sk_OutColor = floor(sample(inputFP) * 255 + 0.5) / 255;
+    half4 color = floor(sample(inputFP) * 255 + 0.5) / 255;
 
     @switch (pmConversion) {
         case PMConversion::kToPremul:
-            sk_OutColor.rgb = floor(sk_OutColor.rgb * sk_OutColor.a * 255 + 0.5) / 255;
+            color.rgb = floor(color.rgb * color.a * 255 + 0.5) / 255;
             break;
 
         case PMConversion::kToUnpremul:
-            sk_OutColor.rgb = sk_OutColor.a <= 0.0
-                                      ? half3(0)
-                                      : floor(sk_OutColor.rgb / sk_OutColor.a * 255 + 0.5) / 255;
+            color.rgb = color.a <= 0.0
+                            ? half3(0)
+                            : floor(color.rgb / color.a * 255 + 0.5) / 255;
             break;
     }
+
+    return color;
 }
 
 @test(data) {
diff --git a/src/gpu/effects/GrHSLToRGBFilterEffect.fp b/src/gpu/effects/GrHSLToRGBFilterEffect.fp
index acbc2dc..58aae52 100644
--- a/src/gpu/effects/GrHSLToRGBFilterEffect.fp
+++ b/src/gpu/effects/GrHSLToRGBFilterEffect.fp
@@ -15,17 +15,18 @@
 
 in fragmentProcessor? inputFP;
 
-void main() {
-    half4   inputColor = sample(inputFP);
-    half3   hsl = inputColor.rgb;
+half4 main() {
+    half4 color = sample(inputFP);
+    half3   hsl = color.rgb;
 
     half      C = (1 - abs(2 * hsl.z - 1)) * hsl.y;
     half3     p = hsl.xxx + half3(0, 2/3.0, 1/3.0);
     half3     q = saturate(abs(fract(p) * 6 - 3) - 1);
     half3   rgb = (q - 0.5) * C + hsl.z;
 
-    sk_OutColor = saturate(half4(rgb, inputColor.a));
-    sk_OutColor.rgb *= sk_OutColor.a;
+    color = saturate(half4(rgb, color.a));
+    color.rgb *= color.a;
+    return color;
 }
 
 @optimizationFlags {
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index ff207de..2a69b58 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -179,18 +179,15 @@
     fragBuilder->codeAppend("half2 sourceOffset;");
     if (mce.kernelIsSampled()) {
         const char* kernelBias = uniformHandler->getUniformCStr(fKernelBiasUni);
-        SkString kernelCoord = SkStringPrintf("float2(float(i) + 0.5, 0.5)");
-        SkString kernelSample = this->invokeChild(1, args, kernelCoord.c_str());
+        SkString kernelSample = this->invokeChild(1, args, "float2(float(i) + 0.5, 0.5)");
         fragBuilder->codeAppendf("k = %s.w + %s;", kernelSample.c_str(), kernelBias);
         fragBuilder->codeAppendf("sourceOffset.y = floor(i / %d);", kernelWidth);
         fragBuilder->codeAppendf("sourceOffset.x = i - sourceOffset.y * %d;", kernelWidth);
     } else {
         fragBuilder->codeAppendf("sourceOffset = half2(%d, %d);", loc.x(), loc.y());
         int offset = loc.y() * kernelWidth + loc.x();
-        static constexpr const char kVecSuffix[][4] = { ".x", ".y", ".z", ".w" };
         const char* kernel = uniformHandler->getUniformCStr(fKernelUni);
-        fragBuilder->codeAppendf("k = %s[%d]%s;", kernel, offset / 4,
-                                 kVecSuffix[offset & 0x3]);
+        fragBuilder->codeAppendf("k = %s[%d][%d];", kernel, offset / 4, offset & 0x3);
     }
 
     auto sample = this->invokeChild(0, args, "coord + sourceOffset");
@@ -242,18 +239,19 @@
         }
     }
 
+    fragBuilder->codeAppendf("half4 color;");
     if (mce.convolveAlpha()) {
-        fragBuilder->codeAppendf("%s = sum * %s + %s;", args.fOutputColor, gain, bias);
-        fragBuilder->codeAppendf("%s.a = saturate(%s.a);", args.fOutputColor, args.fOutputColor);
-        fragBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
-                                 args.fOutputColor, args.fOutputColor, args.fOutputColor);
+        fragBuilder->codeAppendf("color = sum * %s + %s;", gain, bias);
+        fragBuilder->codeAppendf("color.a = saturate(color.a);");
+        fragBuilder->codeAppendf("color.rgb = clamp(color.rgb, 0.0, color.a);");
     } else {
         auto sample = this->invokeChild(0, args);
         fragBuilder->codeAppendf("half4 c = %s;", sample.c_str());
-        fragBuilder->codeAppendf("%s.a = c.a;", args.fOutputColor);
-        fragBuilder->codeAppendf("%s.rgb = saturate(sum.rgb * %s + %s);", args.fOutputColor, gain, bias);
-        fragBuilder->codeAppendf("%s.rgb *= %s.a;", args.fOutputColor, args.fOutputColor);
+        fragBuilder->codeAppendf("color.a = c.a;");
+        fragBuilder->codeAppendf("color.rgb = saturate(sum.rgb * %s + %s);", gain, bias);
+        fragBuilder->codeAppendf("color.rgb *= color.a;");
     }
+    fragBuilder->codeAppendf("return color;");
 }
 
 void GrGLMatrixConvolutionEffect::GenKey(const GrProcessor& processor,
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
index 3a1b733..7c1cdcd 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.h
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -43,6 +43,7 @@
     bool convolveAlpha() const { return fConvolveAlpha; }
 
     const char* name() const override { return "MatrixConvolution"; }
+    bool usesExplicitReturn() const override { return true; }
 
     std::unique_ptr<GrFragmentProcessor> clone() const override;
 
diff --git a/src/gpu/effects/generated/GrConfigConversionEffect.cpp b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
index 283e5d1..8d13168 100644
--- a/src/gpu/effects/generated/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
@@ -30,19 +30,18 @@
         fragBuilder->forceHighPrecision();
         SkString _sample0 = this->invokeChild(0, args);
         fragBuilder->codeAppendf(
-                R"SkSL(%s = floor(%s * 255.0 + 0.5) / 255.0;
+                R"SkSL(half4 color = floor(%s * 255.0 + 0.5) / 255.0;
 @switch (%d) {
     case 0:
-        %s.xyz = floor((%s.xyz * %s.w) * 255.0 + 0.5) / 255.0;
+        color.xyz = floor((color.xyz * color.w) * 255.0 + 0.5) / 255.0;
         break;
     case 1:
-        %s.xyz = %s.w <= 0.0 ? half3(0.0) : floor((%s.xyz / %s.w) * 255.0 + 0.5) / 255.0;
+        color.xyz = color.w <= 0.0 ? half3(0.0) : floor((color.xyz / color.w) * 255.0 + 0.5) / 255.0;
         break;
 }
+return color;
 )SkSL",
-                args.fOutputColor, _sample0.c_str(), (int)_outer.pmConversion, args.fOutputColor,
-                args.fOutputColor, args.fOutputColor, args.fOutputColor, args.fOutputColor,
-                args.fOutputColor, args.fOutputColor);
+                _sample0.c_str(), (int)_outer.pmConversion);
     }
 
 private:
@@ -62,7 +61,7 @@
     if (pmConversion != that.pmConversion) return false;
     return true;
 }
-bool GrConfigConversionEffect::usesExplicitReturn() const { return false; }
+bool GrConfigConversionEffect::usesExplicitReturn() const { return true; }
 GrConfigConversionEffect::GrConfigConversionEffect(const GrConfigConversionEffect& src)
         : INHERITED(kGrConfigConversionEffect_ClassID, src.optimizationFlags())
         , pmConversion(src.pmConversion) {
diff --git a/src/gpu/effects/generated/GrHSLToRGBFilterEffect.cpp b/src/gpu/effects/generated/GrHSLToRGBFilterEffect.cpp
index 8505c52..72af658 100644
--- a/src/gpu/effects/generated/GrHSLToRGBFilterEffect.cpp
+++ b/src/gpu/effects/generated/GrHSLToRGBFilterEffect.cpp
@@ -26,16 +26,17 @@
         (void)_outer;
         SkString _sample0 = this->invokeChild(0, args);
         fragBuilder->codeAppendf(
-                R"SkSL(half4 inputColor = %s;
-half3 hsl = inputColor.xyz;
+                R"SkSL(half4 color = %s;
+half3 hsl = color.xyz;
 half C = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;
 half3 p = hsl.xxx + half3(0.0, 0.66666668653488159, 0.3333333432674408);
 half3 q = clamp(abs(fract(p) * 6.0 - 3.0) - 1.0, 0.0, 1.0);
 half3 rgb = (q - 0.5) * C + hsl.z;
-%s = clamp(half4(rgb, inputColor.w), 0.0, 1.0);
-%s.xyz *= %s.w;
+color = clamp(half4(rgb, color.w), 0.0, 1.0);
+color.xyz *= color.w;
+return color;
 )SkSL",
-                _sample0.c_str(), args.fOutputColor, args.fOutputColor, args.fOutputColor);
+                _sample0.c_str());
     }
 
 private:
@@ -52,7 +53,7 @@
     (void)that;
     return true;
 }
-bool GrHSLToRGBFilterEffect::usesExplicitReturn() const { return false; }
+bool GrHSLToRGBFilterEffect::usesExplicitReturn() const { return true; }
 GrHSLToRGBFilterEffect::GrHSLToRGBFilterEffect(const GrHSLToRGBFilterEffect& src)
         : INHERITED(kGrHSLToRGBFilterEffect_ClassID, src.optimizationFlags()) {
     this->cloneAndRegisterAllChildProcessors(src);
diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp
index e00195e..30c0195 100644
--- a/src/shaders/SkPerlinNoiseShader.cpp
+++ b/src/shaders/SkPerlinNoiseShader.cpp
@@ -744,6 +744,7 @@
     }
 
     const char* name() const override { return "PerlinNoise"; }
+    bool usesExplicitReturn() const override { return true; }
 
     std::unique_ptr<GrFragmentProcessor> clone() const override {
         return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect(*this));
@@ -960,7 +961,7 @@
                              args.fSampleCoord, baseFrequencyUni);
 
     // Clear the color accumulator
-    fragBuilder->codeAppendf("%s = half4(0.0);", args.fOutputColor);
+    fragBuilder->codeAppendf("half4 color = half4(0);");
 
     if (pne.stitchTiles()) {
         // Set up TurbulenceInitial stitch values.
@@ -971,7 +972,7 @@
 
     // Loop over all octaves
     fragBuilder->codeAppendf("for (int octave = 0; octave < %d; ++octave) {", pne.numOctaves());
-    fragBuilder->codeAppendf("    %s += ", args.fOutputColor);
+    fragBuilder->codeAppendf("    color += ");
     if (pne.type() != SkPerlinNoiseShaderImpl::kFractalNoise_Type) {
         fragBuilder->codeAppend("abs(");
     }
@@ -1014,17 +1015,14 @@
     if (pne.type() == SkPerlinNoiseShaderImpl::kFractalNoise_Type) {
         // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
         // by fractalNoise and (turbulenceFunctionResult) by turbulence.
-        fragBuilder->codeAppendf("%s = %s * half4(0.5) + half4(0.5);",
-                                 args.fOutputColor, args.fOutputColor);
+        fragBuilder->codeAppendf("color = color * half4(0.5) + half4(0.5);");
     }
 
     // Clamp values
-    fragBuilder->codeAppendf("%s = saturate(%s);", args.fOutputColor, args.fOutputColor);
+    fragBuilder->codeAppendf("color = saturate(color);");
 
     // Pre-multiply the result
-    fragBuilder->codeAppendf("%s = half4(%s.rgb * %s.aaa, %s.a);\n",
-                             args.fOutputColor, args.fOutputColor,
-                             args.fOutputColor, args.fOutputColor);
+    fragBuilder->codeAppendf("return half4(color.rgb * color.aaa, color.a);");
 }
 
 void GrGLPerlinNoise::GenKey(const GrProcessor& processor, const GrShaderCaps&,
@@ -1115,6 +1113,7 @@
     }
 
     const char* name() const override { return "ImprovedPerlinNoise"; }
+    bool usesExplicitReturn() const override { return true; }
 
     std::unique_ptr<GrFragmentProcessor> clone() const override {
         return std::unique_ptr<GrFragmentProcessor>(new GrImprovedPerlinNoiseEffect(*this));
@@ -1314,15 +1313,12 @@
                              noiseOctavesFuncName.c_str(), zUni);
     fragBuilder->codeAppendf("half a = %s(half3(coords, %s + 0000.0));",
                              noiseOctavesFuncName.c_str(), zUni);
-    fragBuilder->codeAppendf("%s = half4(r, g, b, a);", args.fOutputColor);
 
     // Clamp values
-    fragBuilder->codeAppendf("%s = saturate(%s);", args.fOutputColor, args.fOutputColor);
+    fragBuilder->codeAppendf("half4 color = saturate(half4(r, g, b, a));");
 
     // Pre-multiply the result
-    fragBuilder->codeAppendf("\n\t\t%s = half4(%s.rgb * %s.aaa, %s.a);\n",
-                             args.fOutputColor, args.fOutputColor,
-                             args.fOutputColor, args.fOutputColor);
+    fragBuilder->codeAppendf("return half4(color.rgb * color.aaa, color.a);");
 }
 
 void GrGLImprovedPerlinNoise::GenKey(const GrProcessor& processor, const GrShaderCaps&,
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index 7006c10..c1f7ede 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -98,6 +98,7 @@
     }
 
     const char* name() const override { return "test"; }
+    bool usesExplicitReturn() const override { return true; }
 
     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
         static std::atomic<int32_t> nextKey{0};
@@ -130,7 +131,7 @@
         public:
             TestGLSLFP() {}
             void emitCode(EmitArgs& args) override {
-                args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputColor);
+                args.fFragBuilder->codeAppendf("return half4(1);");
             }
 
         private:
diff --git a/tests/SkSLCross.cpp b/tests/SkSLCross.cpp
index 88a10c6..791d860 100644
--- a/tests/SkSLCross.cpp
+++ b/tests/SkSLCross.cpp
@@ -45,6 +45,7 @@
 
 private:
     const char* name() const override { return "VisualizeCrossProductSignFP"; }
+    bool usesExplicitReturn() const override { return true; }
     std::unique_ptr<GrFragmentProcessor> clone() const override {
         return std::unique_ptr<GrFragmentProcessor>(new VisualizeCrossProductSignFP(fA, fB));
     }
@@ -63,7 +64,7 @@
                     float crossProduct = cross(%s, %s);
                     float2 visualization = clamp(float2(-sign(crossProduct), sign(crossProduct)),
                                                  float2(0), float2(1));
-                    %s = half4(half2(visualization), 0, 1);)", a, b, args.fOutputColor);
+                    return half2(visualization).xy01;)", a, b);
         }
         void onSetData(const GrGLSLProgramDataManager& pdman,
                        const GrFragmentProcessor& processor) override {
diff --git a/tests/SkSLFPTestbed.cpp b/tests/SkSLFPTestbed.cpp
index d4eecbc..41d361e 100644
--- a/tests/SkSLFPTestbed.cpp
+++ b/tests/SkSLFPTestbed.cpp
@@ -43,8 +43,8 @@
     test(r,
          *SkSL::ShaderCapsFactory::Default(),
          R"__SkSL__(
-             void main(float2 coord) {
-                 sk_OutColor = half4(0);
+             half4 main(float2 coord) {
+                 return half4(0);
              }
          )__SkSL__");
 }