Convert the remaining FP tests to golden outputs.

(Removed one test, SkSLFPSwitchWithMultipleReturnsInside, because it was
redundant with existing tests.)

Change-Id: I1bfc069babdb5eb0cc515f195c3a2e307bb5871a
Bug: skia:10694
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319029
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index c7620b8..4bb4bcd 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -16,13 +16,30 @@
   "$_tests/sksl/errors/GrNoFragmentProcessorLocals.fp",
   "$_tests/sksl/errors/GrNoFragmentProcessorParams.fp",
   "$_tests/sksl/errors/GrNoFragmentProcessorReturn.fp",
+  "$_tests/sksl/fp/GrChildProcessorAndGlobal.fp",
+  "$_tests/sksl/fp/GrChildProcessorFieldAccess.fp",
+  "$_tests/sksl/fp/GrChildProcessorInlineFieldAccess.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleCoords.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleMatrixAndCoords.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleMatrixConstant.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleMatrixConstantAndCoords.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleMatrixMultipleUniforms.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleMatrixSingleInUniform.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniform.fp",
+  "$_tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniformExpr.fp",
+  "$_tests/sksl/fp/GrChildProcessorWithInputExpression.fp",
+  "$_tests/sksl/fp/GrChildProcessors.fp",
+  "$_tests/sksl/fp/GrChildProcessorsWithInput.fp",
   "$_tests/sksl/fp/GrConditionalInUniform.fp",
   "$_tests/sksl/fp/GrFunction.fp",
+  "$_tests/sksl/fp/GrGrSLTypesAreSupported.fp",
   "$_tests/sksl/fp/GrHelloWorld.fp",
   "$_tests/sksl/fp/GrInUniform.fp",
   "$_tests/sksl/fp/GrInUniformCType.fp",
   "$_tests/sksl/fp/GrInlinedFunction.fp",
   "$_tests/sksl/fp/GrKeyIn.fp",
+  "$_tests/sksl/fp/GrLayoutWhen.fp",
+  "$_tests/sksl/fp/GrMainCoords.fp",
   "$_tests/sksl/fp/GrNestedChildProcessors.fp",
   "$_tests/sksl/fp/GrNonInlinedInUniform.fp",
   "$_tests/sksl/fp/GrNullableChildProcessor.fp",
@@ -40,6 +57,7 @@
   "$_tests/sksl/fp/GrSectionTest.fp",
   "$_tests/sksl/fp/GrTrackedInUniform.fp",
   "$_tests/sksl/fp/GrUniform.fp",
+  "$_tests/sksl/fp/GrUniformArrays.fp",
   "$_tests/sksl/fp/GrUseExplicitReturn.fp",
 ]
 
diff --git a/gn/tests.gni b/gn/tests.gni
index 65423b1..7d06c5c 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -261,7 +261,6 @@
   "$_tests/SkRemoteGlyphCacheTest.cpp",
   "$_tests/SkResourceCacheTest.cpp",
   "$_tests/SkRuntimeEffectTest.cpp",
-  "$_tests/SkSLFPTest.cpp",
   "$_tests/SkSLInterpreterTest.cpp",
   "$_tests/SkSLMemoryLayoutTest.cpp",
   "$_tests/SkSLMetalTest.cpp",
diff --git a/tests/SkSLFPTest.cpp b/tests/SkSLFPTest.cpp
deleted file mode 100644
index 2fa8431..0000000
--- a/tests/SkSLFPTest.cpp
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/sksl/SkSLCompiler.h"
-#include "src/sksl/SkSLStringStream.h"
-
-#include "tests/Test.h"
-
-static void test(skiatest::Reporter* r, const GrShaderCaps& caps, const char* src,
-                 std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
-    SkSL::Program::Settings settings;
-    settings.fCaps = &caps;
-    settings.fRemoveDeadFunctions = false;
-    SkSL::Compiler compiler;
-    SkSL::StringStream output;
-    std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
-                                                             SkSL::Program::kFragmentProcessor_Kind,
-                                                             SkSL::String(src),
-                                                             settings);
-    if (!program) {
-        SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
-        return;
-    }
-    REPORTER_ASSERT(r, program);
-    bool success = compiler.toH(*program, "Test", output);
-    if (!success) {
-        SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
-    }
-    REPORTER_ASSERT(r, success);
-    if (success) {
-        for (const char* expected : expectedH) {
-            bool found = strstr(output.str().c_str(), expected);
-            if (!found) {
-                SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\n"
-                         "header expected:\n'%s'\n\n"
-                         "header received:\n'%s'",
-                         src, expected, output.str().c_str());
-            }
-            REPORTER_ASSERT(r, found);
-        }
-    }
-    output.reset();
-    success = compiler.toCPP(*program, "Test", output);
-    if (!success) {
-        SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
-    }
-    REPORTER_ASSERT(r, success);
-    if (success) {
-        for (const char* expected : expectedCPP) {
-            bool found = strstr(output.str().c_str(), expected);
-            if (!found) {
-                SkDebugf("CPP MISMATCH:\nsource:\n%s\n\n"
-                         "cpp expected:\n'%s'\n\n"
-                         "cpp received:\n'%s'",
-                         src, expected, output.str().c_str());
-            }
-            REPORTER_ASSERT(r, found);
-        }
-    }
-}
-
-DEF_TEST(SkSLFPMainCoords, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             void main(float2 coord) {
-                 sk_OutColor = half4(coord, coord);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             "this->setUsesSampleCoordsDirectly();"
-         },
-         /*expectedCPP=*/{
-            "fragBuilder->codeAppendf(\n"
-            "R\"SkSL(%s = half4(%s, %s);\n"
-            ")SkSL\"\n"
-            ", args.fOutputColor, args.fSampleCoord, args.fSampleCoord);"
-         });
-}
-
-DEF_TEST(SkSLFPLayoutWhen, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-            layout(when=someExpression(someOtherExpression())) uniform half sometimes;
-            void main() {
-            }
-         )__SkSL__",
-         /*expectedH=*/{},
-         /*expectedCPP=*/{
-            "if (someExpression(someOtherExpression())) {\n"
-            "            sometimesVar = args.fUniformHandler->addUniform"
-         });
-}
-
-DEF_TEST(SkSLFPChildProcessors, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor child1;
-             in fragmentProcessor child2;
-             void main() {
-                 sk_OutColor = sample(child1) * sample(child2);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-            "this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());",
-            "this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());"
-         },
-         /*expectedCPP=*/{
-            "SkString _sample149 = this->invokeChild(0, args);\n",
-            "SkString _sample166 = this->invokeChild(1, args);\n",
-            "fragBuilder->codeAppendf(\n"
-            "R\"SkSL(%s = %s * %s;\n"
-            ")SkSL\"\n"
-            ", args.fOutputColor, _sample149.c_str(), _sample166.c_str());",
-            "this->cloneAndRegisterAllChildProcessors(src);",
-         });
-}
-
-DEF_TEST(SkSLFPChildProcessorsWithInput, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             uniform half4 color;
-             in fragmentProcessor child1;
-             in fragmentProcessor child2;
-             void main() {
-                 half4 childIn = color;
-                 half4 childOut1 = sample(child1, childIn);
-                 half4 childOut2 = sample(child2, childOut1);
-                 sk_OutColor = childOut2;
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-            "this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());",
-            "this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());"
-         },
-         /*expectedCPP=*/{
-            "this->cloneAndRegisterAllChildProcessors(src);",
-            R"__Cpp__(
-        SkString _input227("childIn");
-        SkString _sample227 = this->invokeChild(0, _input227.c_str(), args);
-        fragBuilder->codeAppendf(
-R"SkSL(
-half4 childOut1 = %s;)SkSL"
-, _sample227.c_str());
-        SkString _input287("childOut1");
-        SkString _sample287 = this->invokeChild(1, _input287.c_str(), args);
-        fragBuilder->codeAppendf(
-R"SkSL(
-half4 childOut2 = %s;
-%s = childOut2;
-)SkSL"
-, _sample287.c_str(), args.fOutputColor);
-)__Cpp__"});
-}
-
-DEF_TEST(SkSLFPChildProcessorWithInputExpression, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             uniform half4 color;
-             in fragmentProcessor child;
-             void main() {
-                 sk_OutColor = sample(child, color * half4(0.5));
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-            "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());",
-         },
-         /*expectedCPP=*/{
-            "this->cloneAndRegisterAllChildProcessors(src);",
-            R"__Cpp__(
-        SkString _input140 = SkStringPrintf("%s * half4(0.5)", args.fUniformHandler->getUniformCStr(colorVar));
-        SkString _sample140 = this->invokeChild(0, _input140.c_str(), args);
-        fragBuilder->codeAppendf(
-R"SkSL(%s = %s;
-)SkSL"
-, args.fOutputColor, _sample140.c_str());
-)__Cpp__"});
-}
-
-DEF_TEST(SkSLFPChildFPAndGlobal, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor child;
-             bool hasCap = sk_Caps.externalTextureSupport;
-             void main() {
-                 if (hasCap) {
-                     sk_OutColor = sample(child);
-                 } else {
-                     sk_OutColor = half4(1);
-                 }
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-            "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());"
-         },
-         /*expectedCPP=*/{
-            "this->cloneAndRegisterAllChildProcessors(src);",
-            R"__Cpp__(
-hasCap = sk_Caps.externalTextureSupport;
-        fragBuilder->codeAppendf(
-R"SkSL(bool hasCap = %s;
-if (hasCap) {)SkSL"
-, (hasCap ? "true" : "false"));
-        SkString _sample200 = this->invokeChild(0, args);
-        fragBuilder->codeAppendf(
-R"SkSL(
-    %s = %s;
-} else {
-    %s = half4(1.0);
-}
-)SkSL"
-, args.fOutputColor, _sample200.c_str(), args.fOutputColor);
-)__Cpp__"});
-}
-
-DEF_TEST(SkSLFPChildProcessorInlineFieldAccess, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor child;
-             void main() {
-                 if (child.preservesOpaqueInput) {
-                     sk_OutColor = sample(child);
-                 } else {
-                     sk_OutColor = half4(1);
-                 }
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-            "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());"
-         },
-         /*expectedCPP=*/{
-            "this->cloneAndRegisterAllChildProcessors(src);",
-            R"__Cpp__(
-        fragBuilder->codeAppendf(
-R"SkSL(if (%s) {)SkSL"
-, (_outer.childProcessor(0)->preservesOpaqueInput() ? "true" : "false"));
-        SkString _sample161 = this->invokeChild(0, args);
-        fragBuilder->codeAppendf(
-R"SkSL(
-    %s = %s;
-} else {
-    %s = half4(1.0);
-}
-)SkSL"
-, args.fOutputColor, _sample161.c_str(), args.fOutputColor);
-)__Cpp__"});
-}
-
-DEF_TEST(SkSLFPChildProcessorFieldAccess, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor child;
-             bool opaque = child.preservesOpaqueInput;
-             void main() {
-                 if (opaque) {
-                     sk_OutColor = sample(child);
-                 } else {
-                     sk_OutColor = half4(0.5);
-                 }
-         }
-         )__SkSL__",
-         /*expectedH=*/{
-            "this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());"
-         },
-         /*expectedCPP=*/{
-            "opaque = _outer.childProcessor(0)->preservesOpaqueInput();",
-            "fragBuilder->codeAppendf(\n"
-            "R\"SkSL(bool opaque = %s;\n"
-            "if (opaque) {)SkSL\"\n"
-            ", (opaque ? \"true\" : \"false\"));",
-            "SkString _sample196 = this->invokeChild(0, args);",
-            "fragBuilder->codeAppendf(\n"
-            "R\"SkSL(\n"
-            "    %s = %s;\n"
-            "} else {\n"
-            "    %s = half4(0.5);\n"
-            "}\n"
-            ")SkSL\"\n"
-            ", args.fOutputColor, _sample196.c_str(), args.fOutputColor);",
-            "this->cloneAndRegisterAllChildProcessors(src);",
-         });
-}
-
-DEF_TEST(SkSLFPSampleCoords, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor child;
-             void main(float2 coord) {
-                 sk_OutColor = sample(child) + sample(child, coord / 2);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             "this->registerChild(std::move(child), SkSL::SampleUsage(SkSL::SampleUsage::Kind::kNone, \"\", false, true, true));",
-             "this->setUsesSampleCoordsDirectly();"
-         },
-         /*expectedCPP=*/{
-            "SkString _sample118 = this->invokeChild(0, args);\n",
-            "SkString _coords134 = SkStringPrintf(\"%s / 2.0\", args.fSampleCoord);\n",
-            "SkString _sample134 = this->invokeChild(0, args, _coords134.c_str());\n",
-            "fragBuilder->codeAppendf(\n"
-            "R\"SkSL(%s = %s + %s;\n"
-            ")SkSL\"\n"
-            ", args.fOutputColor, _sample118.c_str(), _sample134.c_str());"
-        });
-}
-
-DEF_TEST(SkSLFPSwitchWithMultipleReturnsInside, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             uniform half4 color;
-             half4 switchy(half4 c) {
-                 switch (int(c.x)) {
-                     case 0: return c.yyyy;
-                     default: return c.zzzz;
-                 }
-             }
-             void main() {
-                 sk_OutColor = switchy(color);
-             }
-         )__SkSL__",
-         /*expectedH=*/{},
-         /*expectedCPP=*/{
-         R"__Cpp__(fragBuilder->emitFunction(kHalf4_GrSLType, "switchy", 1, switchy_args,
-R"SkSL(switch (int(c.x)) {
-    case 0:
-        return c.yyyy;
-    default:
-        return c.zzzz;
-}
-)SkSL", &switchy_name);
-        fragBuilder->codeAppendf(
-R"SkSL(%s = %s(%s);
-)SkSL"
-, args.fOutputColor, switchy_name.c_str(), args.fUniformHandler->getUniformCStr(colorVar));
-)__Cpp__"});
-}
-
-DEF_TEST(SkSLFPGrSLTypesAreSupported, r) {
-    // We thwart the optimizer by wrapping our return statement in a loop, which prevents inlining.
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             int test(int a) { for (;;) { return a; } }
-             void main() { sk_OutColor = test(1).xxxx; }
-         )__SkSL__",
-         /*expectedH=*/{},
-         /*expectedCPP=*/{
-            R"__Cpp__(const GrShaderVar test_args[] = { GrShaderVar("a", kInt_GrSLType)};)__Cpp__",
-            R"__Cpp__(fragBuilder->emitFunction(kInt_GrSLType, "test", 1, test_args,)__Cpp__",
-         });
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             int2 test(int2 a) { for (;;) { return a; } }
-             void main() { sk_OutColor = test(int2(1)).xyxy; }
-         )__SkSL__",
-         /*expectedH=*/{},
-         /*expectedCPP=*/{
-            R"__Cpp__(const GrShaderVar test_args[] = { GrShaderVar("a", kInt2_GrSLType)};)__Cpp__",
-            R"__Cpp__(fragBuilder->emitFunction(kInt2_GrSLType, "test", 1, test_args,)__Cpp__",
-         });
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             int3 test(int3 a) { for (;;) { return a; } }
-             void main() { sk_OutColor = test(int3(1)).xyzx; }
-         )__SkSL__",
-         /*expectedH=*/{},
-         /*expectedCPP=*/{
-            R"__Cpp__(const GrShaderVar test_args[] = { GrShaderVar("a", kInt3_GrSLType)};)__Cpp__",
-            R"__Cpp__(fragBuilder->emitFunction(kInt3_GrSLType, "test", 1, test_args,)__Cpp__",
-         });
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             int4 test(int4 a) { for (;;) { return a; } }
-             void main() { sk_OutColor = test(int4(1)); }
-         )__SkSL__",
-         /*expectedH=*/{},
-         /*expectedCPP=*/{
-            R"__Cpp__(const GrShaderVar test_args[] = { GrShaderVar("a", kInt4_GrSLType)};)__Cpp__",
-            R"__Cpp__(fragBuilder->emitFunction(kInt4_GrSLType, "test", 1, test_args,)__Cpp__",
-         });
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             half3x4 test(float3x4 a) { for (;;) { return half3x4(a); } }
-             void main() { sk_OutColor = test(float3x4(0))[0]; }
-         )__SkSL__",
-         /*expectedH=*/{},
-         /*expectedCPP=*/{
-            R"__Cpp__(const GrShaderVar test_args[] = { GrShaderVar("a", kFloat3x4_GrSLType)};)__Cpp__",
-            R"__Cpp__(fragBuilder->emitFunction(kHalf3x4_GrSLType, "test", 1, test_args,)__Cpp__",
-         });
-}
-
-DEF_TEST(SkSLFPMatrixSampleConstant, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor? child;
-             void main() {
-                 sk_OutColor = sample(child, float3x3(2));
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             "this->registerChild(std::move(child), "
-                    "SkSL::SampleUsage::UniformMatrix(\"float3x3(2.0)\", true));"
-         },
-         /*expectedCPP=*/{
-             "this->invokeChildWithMatrix(0, args)"
-         });
-}
-
-DEF_TEST(SkSLFPMatrixSampleUniform, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor? child;
-             uniform float3x3 matrix;
-             void main() {
-                 sk_OutColor = sample(child, matrix);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             // Since 'matrix' is just a uniform, the generated code can't determine perspective.
-             "this->registerChild(std::move(child), "
-                    "SkSL::SampleUsage::UniformMatrix(\"matrix\", true));"
-         },
-         /*expectedCPP=*/{
-             "this->invokeChildWithMatrix(0, args)"
-         });
-}
-
-DEF_TEST(SkSLFPMatrixSampleInUniform, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor? child;
-             in uniform float3x3 matrix;
-             void main() {
-                 sk_OutColor = sample(child, matrix);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             // Since 'matrix' is marked 'in', we can detect perspective at runtime
-             "this->registerChild(std::move(child), "
-                    "SkSL::SampleUsage::UniformMatrix(\"matrix\", matrix.hasPerspective()));"
-         },
-         /*expectedCPP=*/{
-             "this->invokeChildWithMatrix(0, args)"
-         });
-}
-
-DEF_TEST(SkSLFPMatrixSampleMultipleInUniforms, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor? child;
-             in uniform float3x3 matrixA;
-             in uniform float3x3 matrixB;
-             void main() {
-                 sk_OutColor = sample(child, matrixA);
-                 sk_OutColor += sample(child, matrixB);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             // FIXME it would be nice if codegen can produce
-             // (matrixA.hasPerspective() || matrixB.hasPerspective()) even though it's variable.
-             "this->registerChild(std::move(child), "
-                    "SkSL::SampleUsage::VariableMatrix(true));"
-         },
-         /*expectedCPP=*/{
-             "SkString _matrix191(args.fUniformHandler->getUniformCStr(matrixAVar));",
-             "this->invokeChildWithMatrix(0, args, _matrix191.c_str());",
-             "SkString _matrix247(args.fUniformHandler->getUniformCStr(matrixBVar));",
-             "this->invokeChildWithMatrix(0, args, _matrix247.c_str());"
-         });
-}
-
-DEF_TEST(SkSLFPMatrixSampleConstUniformExpression, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor? child;
-             uniform float3x3 matrix;
-             void main() {
-                 sk_OutColor = sample(child, 0.5 * matrix);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             // FIXME: "0.5 * matrix" is a uniform expression and could be lifted to the vertex
-             // shader, once downstream code is able to properly map 'matrix' within the expression.
-             "this->registerChild(std::move(child), "
-                    "SkSL::SampleUsage::VariableMatrix(true));"
-         },
-         /*expectedCPP=*/{
-            "SkString _matrix145 = SkStringPrintf(\"0.5 * %s\", "
-                    "args.fUniformHandler->getUniformCStr(matrixVar));",
-             "this->invokeChildWithMatrix(0, args, _matrix145.c_str());"
-         });
-}
-
-DEF_TEST(SkSLFPMatrixSampleConstantAndExplicitly, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in fragmentProcessor? child;
-             void main(float2 coord) {
-                 sk_OutColor = sample(child, float3x3(0.5));
-                 sk_OutColor = sample(child, coord / 2);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             "this->registerChild(std::move(child), "
-                    "SkSL::SampleUsage(SkSL::SampleUsage::Kind::kUniform, \"float3x3(0.5)\", true, true, false));"
-         },
-         /*expectedCPP=*/{
-             "this->invokeChildWithMatrix(0, args)",
-             "SkString _coords180 = SkStringPrintf(\"%s / 2.0\", args.fSampleCoord);",
-             "this->invokeChild(0, args, _coords180.c_str())",
-         });
-}
-
-DEF_TEST(SkSLFPMatrixSampleVariableAndExplicitly, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             uniform half4 color;
-             in fragmentProcessor? child;
-             void main(float2 coord) {
-                 float3x3 matrix = float3x3(color.a);
-                 sk_OutColor = sample(child, matrix);
-                 sk_OutColor = sample(child, coord / 2);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             "this->registerChild(std::move(child), "
-                    "SkSL::SampleUsage(SkSL::SampleUsage::Kind::kVariable, \"\", true, true, false));"
-         },
-         /*expectedCPP=*/{
-             R"__Cpp__(
-        colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kHalf4_GrSLType, "color");
-        fragBuilder->codeAppendf(
-R"SkSL(float3x3 matrix = float3x3(float(%s.w));)SkSL"
-, args.fUniformHandler->getUniformCStr(colorVar));
-        SkString _matrix207("matrix");
-        SkString _sample207 = this->invokeChildWithMatrix(0, args, _matrix207.c_str());
-        fragBuilder->codeAppendf(
-R"SkSL(
-%s = %s;)SkSL"
-, args.fOutputColor, _sample207.c_str());
-        SkString _coords261 = SkStringPrintf("%s / 2.0", args.fSampleCoord);
-        SkString _sample261 = this->invokeChild(0, args, _coords261.c_str());
-        fragBuilder->codeAppendf(
-R"SkSL(
-%s = %s;
-)SkSL"
-, args.fOutputColor, _sample261.c_str());
-)__Cpp__"
-         });
-}
-
-DEF_TEST(SkSLUniformArrays, r) {
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             uniform half scalarArray[4];
-             uniform half2 pointArray[2];
-             void main() {
-                sk_OutColor = half4(scalarArray[0] * pointArray[0].x +
-                                    scalarArray[1] * pointArray[0].y +
-                                    scalarArray[2] * pointArray[1].x +
-                                    scalarArray[3] * pointArray[1].y);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             "Make()",
-         },
-         /*expectedCPP=*/{
-             "void onSetData(const GrGLSLProgramDataManager& pdman, "
-             "const GrFragmentProcessor& _proc) override {\n    }"
-         });
-    test(r,
-         *SkSL::ShaderCapsFactory::Default(),
-         R"__SkSL__(
-             in uniform half scalarArray[4];
-             in uniform half2 pointArray[2];
-             void main() {
-                sk_OutColor = half4(scalarArray[0] * pointArray[0].x +
-                                    scalarArray[1] * pointArray[0].y +
-                                    scalarArray[2] * pointArray[1].x +
-                                    scalarArray[3] * pointArray[1].y);
-             }
-         )__SkSL__",
-         /*expectedH=*/{
-             "Make(std::array<float> scalarArray, std::array<SkPoint> pointArray)",
-             "std::array<float> scalarArray;",
-             "std::array<SkPoint> pointArray;",
-         },
-         /*expectedCPP=*/{
-             "pdman.set1fv(scalarArrayVar, 4, &(_outer.scalarArray)[0]);",
-             "pdman.set2fv(pointArrayVar, 2, &pointArrayValue[0].fX);",
-         });
-}
diff --git a/tests/sksl/fp/GrChildProcessorAndGlobal.fp b/tests/sksl/fp/GrChildProcessorAndGlobal.fp
new file mode 100644
index 0000000..3247733
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorAndGlobal.fp
@@ -0,0 +1,10 @@
+in fragmentProcessor child;
+bool hasCap = sk_Caps.externalTextureSupport;
+
+void main() {
+    if (hasCap) {
+        sk_OutColor = sample(child);
+    } else {
+        sk_OutColor = half4(1);
+    }
+}
diff --git a/tests/sksl/fp/GrChildProcessorFieldAccess.fp b/tests/sksl/fp/GrChildProcessorFieldAccess.fp
new file mode 100644
index 0000000..70aa670
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorFieldAccess.fp
@@ -0,0 +1,10 @@
+in fragmentProcessor child;
+bool opaque = child.preservesOpaqueInput;
+
+void main() {
+    if (opaque) {
+        sk_OutColor = sample(child);
+    } else {
+        sk_OutColor = half4(0.5);
+    }
+}
diff --git a/tests/sksl/fp/GrChildProcessorInlineFieldAccess.fp b/tests/sksl/fp/GrChildProcessorInlineFieldAccess.fp
new file mode 100644
index 0000000..be5f938
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorInlineFieldAccess.fp
@@ -0,0 +1,9 @@
+in fragmentProcessor child;
+
+void main() {
+    if (child.preservesOpaqueInput) {
+        sk_OutColor = sample(child);
+    } else {
+        sk_OutColor = half4(1);
+    }
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleCoords.fp b/tests/sksl/fp/GrChildProcessorSampleCoords.fp
new file mode 100644
index 0000000..051cd4d
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleCoords.fp
@@ -0,0 +1,5 @@
+in fragmentProcessor child;
+
+void main(float2 coord) {
+    sk_OutColor = sample(child) + sample(child, coord / 2);
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleMatrixAndCoords.fp b/tests/sksl/fp/GrChildProcessorSampleMatrixAndCoords.fp
new file mode 100644
index 0000000..cddf1ef
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleMatrixAndCoords.fp
@@ -0,0 +1,8 @@
+uniform half4 color;
+in fragmentProcessor? child;
+
+void main(float2 coord) {
+    float3x3 matrix = float3x3(color.a);
+    sk_OutColor = sample(child, matrix);
+    sk_OutColor = sample(child, coord / 2);
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleMatrixConstant.fp b/tests/sksl/fp/GrChildProcessorSampleMatrixConstant.fp
new file mode 100644
index 0000000..b328bcb
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleMatrixConstant.fp
@@ -0,0 +1,5 @@
+in fragmentProcessor? child;
+
+void main() {
+    sk_OutColor = sample(child, float3x3(2));
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleMatrixConstantAndCoords.fp b/tests/sksl/fp/GrChildProcessorSampleMatrixConstantAndCoords.fp
new file mode 100644
index 0000000..2bc1443
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleMatrixConstantAndCoords.fp
@@ -0,0 +1,6 @@
+in fragmentProcessor? child;
+
+void main(float2 coord) {
+    sk_OutColor = sample(child, float3x3(0.5));
+    sk_OutColor = sample(child, coord / 2);
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleMatrixMultipleUniforms.fp b/tests/sksl/fp/GrChildProcessorSampleMatrixMultipleUniforms.fp
new file mode 100644
index 0000000..bad0feb
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleMatrixMultipleUniforms.fp
@@ -0,0 +1,8 @@
+in fragmentProcessor? child;
+in uniform float3x3 matrixA;
+in uniform float3x3 matrixB;
+
+void main() {
+    sk_OutColor = sample(child, matrixA);
+    sk_OutColor += sample(child, matrixB);
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleMatrixSingleInUniform.fp b/tests/sksl/fp/GrChildProcessorSampleMatrixSingleInUniform.fp
new file mode 100644
index 0000000..050ea65
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleMatrixSingleInUniform.fp
@@ -0,0 +1,6 @@
+in fragmentProcessor? child;
+in uniform float3x3 matrix;
+
+void main() {
+    sk_OutColor = sample(child, matrix);
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniform.fp b/tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniform.fp
new file mode 100644
index 0000000..a331cd3
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniform.fp
@@ -0,0 +1,6 @@
+in fragmentProcessor? child;
+uniform float3x3 matrix;
+
+void main() {
+    sk_OutColor = sample(child, matrix);
+}
diff --git a/tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniformExpr.fp b/tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniformExpr.fp
new file mode 100644
index 0000000..058f4c3
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorSampleMatrixSingleUniformExpr.fp
@@ -0,0 +1,6 @@
+in fragmentProcessor? child;
+uniform float3x3 matrix;
+
+void main() {
+    sk_OutColor = sample(child, 0.5 * matrix);
+}
diff --git a/tests/sksl/fp/GrChildProcessorWithInputExpression.fp b/tests/sksl/fp/GrChildProcessorWithInputExpression.fp
new file mode 100644
index 0000000..bd09c72
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorWithInputExpression.fp
@@ -0,0 +1,7 @@
+uniform half4 color;
+
+in fragmentProcessor child;
+
+void main() {
+    sk_OutColor = sample(child, color * half4(0.5));
+}
diff --git a/tests/sksl/fp/GrChildProcessors.fp b/tests/sksl/fp/GrChildProcessors.fp
new file mode 100644
index 0000000..4c90fd4
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessors.fp
@@ -0,0 +1,6 @@
+in fragmentProcessor child1;
+in fragmentProcessor child2;
+
+void main() {
+    sk_OutColor = sample(child1) * sample(child2);
+}
diff --git a/tests/sksl/fp/GrChildProcessorsWithInput.fp b/tests/sksl/fp/GrChildProcessorsWithInput.fp
new file mode 100644
index 0000000..f9fdf43
--- /dev/null
+++ b/tests/sksl/fp/GrChildProcessorsWithInput.fp
@@ -0,0 +1,11 @@
+uniform half4 color;
+
+in fragmentProcessor child1;
+in fragmentProcessor child2;
+
+void main() {
+    half4 childIn = color;
+    half4 childOut1 = sample(child1, childIn);
+    half4 childOut2 = sample(child2, childOut1);
+    sk_OutColor = childOut2;
+}
diff --git a/tests/sksl/fp/GrGrSLTypesAreSupported.fp b/tests/sksl/fp/GrGrSLTypesAreSupported.fp
new file mode 100644
index 0000000..9385a63
--- /dev/null
+++ b/tests/sksl/fp/GrGrSLTypesAreSupported.fp
@@ -0,0 +1,15 @@
+ int      test_i (int  a)       { for (;;) { return a; } }
+ int2     test_i2(int2 a)       { for (;;) { return a; } }
+ int3     test_i3(int3 a)       { for (;;) { return a; } }
+ int4     test_i4(int4 a)       { for (;;) { return a; } }
+ half3x4  test_h3x4(half3x4 a)  { for (;;) { return a; } }
+ float2x4 test_f2x4(float2x4 a) { for (;;) { return a; } }
+
+ void main() {
+    sk_OutColor = test_i(1).xxxx;
+    sk_OutColor = test_i2(int2(1)).xxxx;
+    sk_OutColor = test_i3(int3(1)).xxxx;
+    sk_OutColor = test_i4(int4(1)).xxxx;
+    sk_OutColor = test_h3x4(half3x4(1))[0];
+    sk_OutColor = half4(test_f2x4(float2x4(1))[0]);
+}
diff --git a/tests/sksl/fp/GrLayoutWhen.fp b/tests/sksl/fp/GrLayoutWhen.fp
new file mode 100644
index 0000000..f397a0b
--- /dev/null
+++ b/tests/sksl/fp/GrLayoutWhen.fp
@@ -0,0 +1,3 @@
+layout(when=someExpression(someOtherExpression())) uniform half sometimes;
+
+void main() {}
diff --git a/tests/sksl/fp/GrMainCoords.fp b/tests/sksl/fp/GrMainCoords.fp
new file mode 100644
index 0000000..9e73c36
--- /dev/null
+++ b/tests/sksl/fp/GrMainCoords.fp
@@ -0,0 +1,3 @@
+void main(float2 coord) {
+    sk_OutColor = half4(coord, coord);
+}
diff --git a/tests/sksl/fp/GrUniformArrays.fp b/tests/sksl/fp/GrUniformArrays.fp
new file mode 100644
index 0000000..37893f5
--- /dev/null
+++ b/tests/sksl/fp/GrUniformArrays.fp
@@ -0,0 +1,9 @@
+uniform half scalarArray[4];
+uniform half2 pointArray[2];
+
+void main() {
+   sk_OutColor = half4(scalarArray[0] * pointArray[0].x +
+                       scalarArray[1] * pointArray[0].y +
+                       scalarArray[2] * pointArray[1].x +
+                       scalarArray[3] * pointArray[1].y);
+}
diff --git a/tests/sksl/fp/golden/GrChildProcessorAndGlobal.cpp b/tests/sksl/fp/golden/GrChildProcessorAndGlobal.cpp
new file mode 100644
index 0000000..8f0279c
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorAndGlobal.cpp
@@ -0,0 +1,66 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorAndGlobal.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorAndGlobal.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorAndGlobal : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorAndGlobal() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorAndGlobal& _outer = args.fFp.cast<GrChildProcessorAndGlobal>();
+        (void) _outer;
+hasCap = sk_Caps.externalTextureSupport;
+        fragBuilder->codeAppendf(
+R"SkSL(bool hasCap = %s;
+if (hasCap) {)SkSL"
+, (hasCap ? "true" : "false"));
+        SkString _sample135 = this->invokeChild(0, args);
+        fragBuilder->codeAppendf(
+R"SkSL(
+    %s = %s;
+} else {
+    %s = half4(1.0);
+}
+)SkSL"
+, args.fOutputColor, _sample135.c_str(), args.fOutputColor);
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+bool hasCap = false;
+};
+GrGLSLFragmentProcessor* GrChildProcessorAndGlobal::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorAndGlobal();
+}
+void GrChildProcessorAndGlobal::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorAndGlobal::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorAndGlobal& that = other.cast<GrChildProcessorAndGlobal>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorAndGlobal::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorAndGlobal::GrChildProcessorAndGlobal(const GrChildProcessorAndGlobal& src)
+: INHERITED(kGrChildProcessorAndGlobal_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorAndGlobal::clone() const {
+    return std::make_unique<GrChildProcessorAndGlobal>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorAndGlobal::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorAndGlobal.h b/tests/sksl/fp/golden/GrChildProcessorAndGlobal.h
new file mode 100644
index 0000000..7c9bd61
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorAndGlobal.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorAndGlobal.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorAndGlobal_DEFINED
+#define GrChildProcessorAndGlobal_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorAndGlobal : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorAndGlobal(std::move(child)));
+    }
+    GrChildProcessorAndGlobal(const GrChildProcessorAndGlobal& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorAndGlobal"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorAndGlobal(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorAndGlobal_ClassID, kNone_OptimizationFlags) {
+        SkASSERT(child);        this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorFieldAccess.cpp b/tests/sksl/fp/golden/GrChildProcessorFieldAccess.cpp
new file mode 100644
index 0000000..0da9c23
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorFieldAccess.cpp
@@ -0,0 +1,66 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorFieldAccess.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorFieldAccess.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorFieldAccess : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorFieldAccess() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorFieldAccess& _outer = args.fFp.cast<GrChildProcessorFieldAccess>();
+        (void) _outer;
+opaque = _outer.childProcessor(0)->preservesOpaqueInput();
+        fragBuilder->codeAppendf(
+R"SkSL(bool opaque = %s;
+if (opaque) {)SkSL"
+, (opaque ? "true" : "false"));
+        SkString _sample131 = this->invokeChild(0, args);
+        fragBuilder->codeAppendf(
+R"SkSL(
+    %s = %s;
+} else {
+    %s = half4(0.5);
+}
+)SkSL"
+, args.fOutputColor, _sample131.c_str(), args.fOutputColor);
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+bool opaque = false;
+};
+GrGLSLFragmentProcessor* GrChildProcessorFieldAccess::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorFieldAccess();
+}
+void GrChildProcessorFieldAccess::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorFieldAccess::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorFieldAccess& that = other.cast<GrChildProcessorFieldAccess>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorFieldAccess::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorFieldAccess::GrChildProcessorFieldAccess(const GrChildProcessorFieldAccess& src)
+: INHERITED(kGrChildProcessorFieldAccess_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorFieldAccess::clone() const {
+    return std::make_unique<GrChildProcessorFieldAccess>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorFieldAccess::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorFieldAccess.h b/tests/sksl/fp/golden/GrChildProcessorFieldAccess.h
new file mode 100644
index 0000000..f78f137
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorFieldAccess.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorFieldAccess.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorFieldAccess_DEFINED
+#define GrChildProcessorFieldAccess_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorFieldAccess : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorFieldAccess(std::move(child)));
+    }
+    GrChildProcessorFieldAccess(const GrChildProcessorFieldAccess& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorFieldAccess"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorFieldAccess(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorFieldAccess_ClassID, kNone_OptimizationFlags) {
+        SkASSERT(child);        this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorInlineFieldAccess.cpp b/tests/sksl/fp/golden/GrChildProcessorInlineFieldAccess.cpp
new file mode 100644
index 0000000..b884eab
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorInlineFieldAccess.cpp
@@ -0,0 +1,63 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorInlineFieldAccess.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorInlineFieldAccess.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorInlineFieldAccess : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorInlineFieldAccess() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorInlineFieldAccess& _outer = args.fFp.cast<GrChildProcessorInlineFieldAccess>();
+        (void) _outer;
+        fragBuilder->codeAppendf(
+R"SkSL(if (%s) {)SkSL"
+, (_outer.childProcessor(0)->preservesOpaqueInput() ? "true" : "false"));
+        SkString _sample109 = this->invokeChild(0, args);
+        fragBuilder->codeAppendf(
+R"SkSL(
+    %s = %s;
+} else {
+    %s = half4(1.0);
+}
+)SkSL"
+, args.fOutputColor, _sample109.c_str(), args.fOutputColor);
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrChildProcessorInlineFieldAccess::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorInlineFieldAccess();
+}
+void GrChildProcessorInlineFieldAccess::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorInlineFieldAccess::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorInlineFieldAccess& that = other.cast<GrChildProcessorInlineFieldAccess>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorInlineFieldAccess::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorInlineFieldAccess::GrChildProcessorInlineFieldAccess(const GrChildProcessorInlineFieldAccess& src)
+: INHERITED(kGrChildProcessorInlineFieldAccess_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorInlineFieldAccess::clone() const {
+    return std::make_unique<GrChildProcessorInlineFieldAccess>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorInlineFieldAccess::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorInlineFieldAccess.h b/tests/sksl/fp/golden/GrChildProcessorInlineFieldAccess.h
new file mode 100644
index 0000000..5ca964e
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorInlineFieldAccess.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorInlineFieldAccess.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorInlineFieldAccess_DEFINED
+#define GrChildProcessorInlineFieldAccess_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorInlineFieldAccess : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorInlineFieldAccess(std::move(child)));
+    }
+    GrChildProcessorInlineFieldAccess(const GrChildProcessorInlineFieldAccess& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorInlineFieldAccess"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorInlineFieldAccess(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorInlineFieldAccess_ClassID, kNone_OptimizationFlags) {
+        SkASSERT(child);        this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleCoords.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleCoords.cpp
new file mode 100644
index 0000000..4aee218
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleCoords.cpp
@@ -0,0 +1,59 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleCoords.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleCoords.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleCoords : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleCoords() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleCoords& _outer = args.fFp.cast<GrChildProcessorSampleCoords>();
+        (void) _outer;
+        SkString _sample79 = this->invokeChild(0, args);
+        SkString _coords95 = SkStringPrintf("%s / 2.0", args.fSampleCoord);
+        SkString _sample95 = this->invokeChild(0, args, _coords95.c_str());
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s + %s;
+)SkSL"
+, args.fOutputColor, _sample79.c_str(), _sample95.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleCoords::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleCoords();
+}
+void GrChildProcessorSampleCoords::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleCoords::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleCoords& that = other.cast<GrChildProcessorSampleCoords>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorSampleCoords::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleCoords::GrChildProcessorSampleCoords(const GrChildProcessorSampleCoords& src)
+: INHERITED(kGrChildProcessorSampleCoords_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+    this->setUsesSampleCoordsDirectly();
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleCoords::clone() const {
+    return std::make_unique<GrChildProcessorSampleCoords>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleCoords::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleCoords.h b/tests/sksl/fp/golden/GrChildProcessorSampleCoords.h
new file mode 100644
index 0000000..3d50633
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleCoords.h
@@ -0,0 +1,38 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleCoords.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleCoords_DEFINED
+#define GrChildProcessorSampleCoords_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleCoords : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleCoords(std::move(child)));
+    }
+    GrChildProcessorSampleCoords(const GrChildProcessorSampleCoords& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleCoords"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorSampleCoords(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorSampleCoords_ClassID, kNone_OptimizationFlags) {
+        this->setUsesSampleCoordsDirectly();
+        SkASSERT(child);        this->registerChild(std::move(child), SkSL::SampleUsage(SkSL::SampleUsage::Kind::kNone, "", false, true, true));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixAndCoords.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixAndCoords.cpp
new file mode 100644
index 0000000..6473935
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixAndCoords.cpp
@@ -0,0 +1,70 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixAndCoords.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleMatrixAndCoords.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleMatrixAndCoords : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleMatrixAndCoords() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleMatrixAndCoords& _outer = args.fFp.cast<GrChildProcessorSampleMatrixAndCoords>();
+        (void) _outer;
+        colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kHalf4_GrSLType, "color");
+        fragBuilder->codeAppendf(
+R"SkSL(float3x3 matrix = float3x3(float(%s.w));)SkSL"
+, args.fUniformHandler->getUniformCStr(colorVar));
+        SkString _matrix142("matrix");
+        SkString _sample142 = this->invokeChildWithMatrix(0, args, _matrix142.c_str());
+        fragBuilder->codeAppendf(
+R"SkSL(
+%s = %s;)SkSL"
+, args.fOutputColor, _sample142.c_str());
+        SkString _coords183 = SkStringPrintf("%s / 2.0", args.fSampleCoord);
+        SkString _sample183 = this->invokeChild(0, args, _coords183.c_str());
+        fragBuilder->codeAppendf(
+R"SkSL(
+%s = %s;
+)SkSL"
+, args.fOutputColor, _sample183.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+    UniformHandle colorVar;
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleMatrixAndCoords::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleMatrixAndCoords();
+}
+void GrChildProcessorSampleMatrixAndCoords::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleMatrixAndCoords::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleMatrixAndCoords& that = other.cast<GrChildProcessorSampleMatrixAndCoords>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorSampleMatrixAndCoords::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleMatrixAndCoords::GrChildProcessorSampleMatrixAndCoords(const GrChildProcessorSampleMatrixAndCoords& src)
+: INHERITED(kGrChildProcessorSampleMatrixAndCoords_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+    this->setUsesSampleCoordsDirectly();
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleMatrixAndCoords::clone() const {
+    return std::make_unique<GrChildProcessorSampleMatrixAndCoords>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleMatrixAndCoords::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixAndCoords.h b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixAndCoords.h
new file mode 100644
index 0000000..e342ce8
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixAndCoords.h
@@ -0,0 +1,38 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixAndCoords.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleMatrixAndCoords_DEFINED
+#define GrChildProcessorSampleMatrixAndCoords_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleMatrixAndCoords : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleMatrixAndCoords(std::move(child)));
+    }
+    GrChildProcessorSampleMatrixAndCoords(const GrChildProcessorSampleMatrixAndCoords& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleMatrixAndCoords"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorSampleMatrixAndCoords(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorSampleMatrixAndCoords_ClassID, kNone_OptimizationFlags) {
+        this->setUsesSampleCoordsDirectly();
+        this->registerChild(std::move(child), SkSL::SampleUsage(SkSL::SampleUsage::Kind::kVariable, "", true, true, false));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstant.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstant.cpp
new file mode 100644
index 0000000..ee72bec
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstant.cpp
@@ -0,0 +1,56 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixConstant.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleMatrixConstant.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleMatrixConstant : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleMatrixConstant() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleMatrixConstant& _outer = args.fFp.cast<GrChildProcessorSampleMatrixConstant>();
+        (void) _outer;
+        SkString _sample68 = this->invokeChildWithMatrix(0, args);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s;
+)SkSL"
+, args.fOutputColor, _sample68.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleMatrixConstant::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleMatrixConstant();
+}
+void GrChildProcessorSampleMatrixConstant::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleMatrixConstant::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleMatrixConstant& that = other.cast<GrChildProcessorSampleMatrixConstant>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorSampleMatrixConstant::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleMatrixConstant::GrChildProcessorSampleMatrixConstant(const GrChildProcessorSampleMatrixConstant& src)
+: INHERITED(kGrChildProcessorSampleMatrixConstant_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleMatrixConstant::clone() const {
+    return std::make_unique<GrChildProcessorSampleMatrixConstant>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleMatrixConstant::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstant.h b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstant.h
new file mode 100644
index 0000000..a69cf112
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstant.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixConstant.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleMatrixConstant_DEFINED
+#define GrChildProcessorSampleMatrixConstant_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleMatrixConstant : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleMatrixConstant(std::move(child)));
+    }
+    GrChildProcessorSampleMatrixConstant(const GrChildProcessorSampleMatrixConstant& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleMatrixConstant"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorSampleMatrixConstant(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorSampleMatrixConstant_ClassID, kNone_OptimizationFlags) {
+        this->registerChild(std::move(child), SkSL::SampleUsage::UniformMatrix("float3x3(2.0)", true));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstantAndCoords.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstantAndCoords.cpp
new file mode 100644
index 0000000..a74b82b
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstantAndCoords.cpp
@@ -0,0 +1,63 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixConstantAndCoords.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleMatrixConstantAndCoords.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleMatrixConstantAndCoords : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleMatrixConstantAndCoords() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleMatrixConstantAndCoords& _outer = args.fFp.cast<GrChildProcessorSampleMatrixConstantAndCoords>();
+        (void) _outer;
+        SkString _sample80 = this->invokeChildWithMatrix(0, args);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s;)SkSL"
+, args.fOutputColor, _sample80.c_str());
+        SkString _coords128 = SkStringPrintf("%s / 2.0", args.fSampleCoord);
+        SkString _sample128 = this->invokeChild(0, args, _coords128.c_str());
+        fragBuilder->codeAppendf(
+R"SkSL(
+%s = %s;
+)SkSL"
+, args.fOutputColor, _sample128.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleMatrixConstantAndCoords::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleMatrixConstantAndCoords();
+}
+void GrChildProcessorSampleMatrixConstantAndCoords::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleMatrixConstantAndCoords::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleMatrixConstantAndCoords& that = other.cast<GrChildProcessorSampleMatrixConstantAndCoords>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorSampleMatrixConstantAndCoords::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleMatrixConstantAndCoords::GrChildProcessorSampleMatrixConstantAndCoords(const GrChildProcessorSampleMatrixConstantAndCoords& src)
+: INHERITED(kGrChildProcessorSampleMatrixConstantAndCoords_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+    this->setUsesSampleCoordsDirectly();
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleMatrixConstantAndCoords::clone() const {
+    return std::make_unique<GrChildProcessorSampleMatrixConstantAndCoords>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleMatrixConstantAndCoords::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstantAndCoords.h b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstantAndCoords.h
new file mode 100644
index 0000000..0df774b
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixConstantAndCoords.h
@@ -0,0 +1,38 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixConstantAndCoords.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleMatrixConstantAndCoords_DEFINED
+#define GrChildProcessorSampleMatrixConstantAndCoords_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleMatrixConstantAndCoords : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleMatrixConstantAndCoords(std::move(child)));
+    }
+    GrChildProcessorSampleMatrixConstantAndCoords(const GrChildProcessorSampleMatrixConstantAndCoords& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleMatrixConstantAndCoords"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorSampleMatrixConstantAndCoords(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorSampleMatrixConstantAndCoords_ClassID, kNone_OptimizationFlags) {
+        this->setUsesSampleCoordsDirectly();
+        this->registerChild(std::move(child), SkSL::SampleUsage(SkSL::SampleUsage::Kind::kUniform, "float3x3(0.5)", true, true, false));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixMultipleUniforms.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixMultipleUniforms.cpp
new file mode 100644
index 0000000..d2afb73
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixMultipleUniforms.cpp
@@ -0,0 +1,80 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixMultipleUniforms.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleMatrixMultipleUniforms.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleMatrixMultipleUniforms : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleMatrixMultipleUniforms() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleMatrixMultipleUniforms& _outer = args.fFp.cast<GrChildProcessorSampleMatrixMultipleUniforms>();
+        (void) _outer;
+        auto matrixA = _outer.matrixA;
+        (void) matrixA;
+        auto matrixB = _outer.matrixB;
+        (void) matrixB;
+        matrixAVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kFloat3x3_GrSLType, "matrixA");
+        matrixBVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kFloat3x3_GrSLType, "matrixB");
+        SkString _matrix126(args.fUniformHandler->getUniformCStr(matrixAVar));
+        SkString _sample126 = this->invokeChildWithMatrix(0, args, _matrix126.c_str());
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s;)SkSL"
+, args.fOutputColor, _sample126.c_str());
+        SkString _matrix169(args.fUniformHandler->getUniformCStr(matrixBVar));
+        SkString _sample169 = this->invokeChildWithMatrix(0, args, _matrix169.c_str());
+        fragBuilder->codeAppendf(
+R"SkSL(
+%s += %s;
+)SkSL"
+, args.fOutputColor, _sample169.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+        const GrChildProcessorSampleMatrixMultipleUniforms& _outer = _proc.cast<GrChildProcessorSampleMatrixMultipleUniforms>();
+        {
+        static_assert(1 == 1); pdman.setSkMatrix(matrixAVar, (_outer.matrixA));
+        static_assert(1 == 1); pdman.setSkMatrix(matrixBVar, (_outer.matrixB));
+        }
+    }
+    UniformHandle matrixAVar;
+    UniformHandle matrixBVar;
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleMatrixMultipleUniforms::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleMatrixMultipleUniforms();
+}
+void GrChildProcessorSampleMatrixMultipleUniforms::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleMatrixMultipleUniforms::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleMatrixMultipleUniforms& that = other.cast<GrChildProcessorSampleMatrixMultipleUniforms>();
+    (void) that;
+    if (matrixA != that.matrixA) return false;
+    if (matrixB != that.matrixB) return false;
+    return true;
+}
+bool GrChildProcessorSampleMatrixMultipleUniforms::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleMatrixMultipleUniforms::GrChildProcessorSampleMatrixMultipleUniforms(const GrChildProcessorSampleMatrixMultipleUniforms& src)
+: INHERITED(kGrChildProcessorSampleMatrixMultipleUniforms_ClassID, src.optimizationFlags())
+, matrixA(src.matrixA)
+, matrixB(src.matrixB) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleMatrixMultipleUniforms::clone() const {
+    return std::make_unique<GrChildProcessorSampleMatrixMultipleUniforms>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleMatrixMultipleUniforms::onDumpInfo() const {
+    return SkStringPrintf("(matrixA=float3x3(%f, %f, %f, %f, %f, %f, %f, %f, %f), matrixB=float3x3(%f, %f, %f, %f, %f, %f, %f, %f, %f))", matrixA.rc(0, 0), matrixA.rc(1, 0), matrixA.rc(2, 0), matrixA.rc(0, 1), matrixA.rc(1, 1), matrixA.rc(2, 1), matrixA.rc(0, 2), matrixA.rc(1, 2), matrixA.rc(2, 2), matrixB.rc(0, 0), matrixB.rc(1, 0), matrixB.rc(2, 0), matrixB.rc(0, 1), matrixB.rc(1, 1), matrixB.rc(2, 1), matrixB.rc(0, 2), matrixB.rc(1, 2), matrixB.rc(2, 2));
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixMultipleUniforms.h b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixMultipleUniforms.h
new file mode 100644
index 0000000..1855354
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixMultipleUniforms.h
@@ -0,0 +1,41 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixMultipleUniforms.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleMatrixMultipleUniforms_DEFINED
+#define GrChildProcessorSampleMatrixMultipleUniforms_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleMatrixMultipleUniforms : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child, SkMatrix matrixA, SkMatrix matrixB) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleMatrixMultipleUniforms(std::move(child), matrixA, matrixB));
+    }
+    GrChildProcessorSampleMatrixMultipleUniforms(const GrChildProcessorSampleMatrixMultipleUniforms& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleMatrixMultipleUniforms"; }
+    bool usesExplicitReturn() const override;
+    SkMatrix matrixA;
+    SkMatrix matrixB;
+private:
+    GrChildProcessorSampleMatrixMultipleUniforms(std::unique_ptr<GrFragmentProcessor> child, SkMatrix matrixA, SkMatrix matrixB)
+    : INHERITED(kGrChildProcessorSampleMatrixMultipleUniforms_ClassID, kNone_OptimizationFlags)
+    , matrixA(matrixA)
+    , matrixB(matrixB) {
+        this->registerChild(std::move(child), SkSL::SampleUsage::VariableMatrix(true));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleInUniform.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleInUniform.cpp
new file mode 100644
index 0000000..11040c2
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleInUniform.cpp
@@ -0,0 +1,66 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixSingleInUniform.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleMatrixSingleInUniform.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleMatrixSingleInUniform : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleMatrixSingleInUniform() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleMatrixSingleInUniform& _outer = args.fFp.cast<GrChildProcessorSampleMatrixSingleInUniform>();
+        (void) _outer;
+        auto matrix = _outer.matrix;
+        (void) matrix;
+        matrixVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kFloat3x3_GrSLType, "matrix");
+        SkString _sample96 = this->invokeChildWithMatrix(0, args);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s;
+)SkSL"
+, args.fOutputColor, _sample96.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+        const GrChildProcessorSampleMatrixSingleInUniform& _outer = _proc.cast<GrChildProcessorSampleMatrixSingleInUniform>();
+        {
+        static_assert(1 == 1); pdman.setSkMatrix(matrixVar, (_outer.matrix));
+        }
+    }
+    UniformHandle matrixVar;
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleMatrixSingleInUniform::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleMatrixSingleInUniform();
+}
+void GrChildProcessorSampleMatrixSingleInUniform::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleMatrixSingleInUniform::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleMatrixSingleInUniform& that = other.cast<GrChildProcessorSampleMatrixSingleInUniform>();
+    (void) that;
+    if (matrix != that.matrix) return false;
+    return true;
+}
+bool GrChildProcessorSampleMatrixSingleInUniform::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleMatrixSingleInUniform::GrChildProcessorSampleMatrixSingleInUniform(const GrChildProcessorSampleMatrixSingleInUniform& src)
+: INHERITED(kGrChildProcessorSampleMatrixSingleInUniform_ClassID, src.optimizationFlags())
+, matrix(src.matrix) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleMatrixSingleInUniform::clone() const {
+    return std::make_unique<GrChildProcessorSampleMatrixSingleInUniform>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleMatrixSingleInUniform::onDumpInfo() const {
+    return SkStringPrintf("(matrix=float3x3(%f, %f, %f, %f, %f, %f, %f, %f, %f))", matrix.rc(0, 0), matrix.rc(1, 0), matrix.rc(2, 0), matrix.rc(0, 1), matrix.rc(1, 1), matrix.rc(2, 1), matrix.rc(0, 2), matrix.rc(1, 2), matrix.rc(2, 2));
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleInUniform.h b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleInUniform.h
new file mode 100644
index 0000000..98a2790
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleInUniform.h
@@ -0,0 +1,39 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixSingleInUniform.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleMatrixSingleInUniform_DEFINED
+#define GrChildProcessorSampleMatrixSingleInUniform_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleMatrixSingleInUniform : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child, SkMatrix matrix) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleMatrixSingleInUniform(std::move(child), matrix));
+    }
+    GrChildProcessorSampleMatrixSingleInUniform(const GrChildProcessorSampleMatrixSingleInUniform& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleMatrixSingleInUniform"; }
+    bool usesExplicitReturn() const override;
+    SkMatrix matrix;
+private:
+    GrChildProcessorSampleMatrixSingleInUniform(std::unique_ptr<GrFragmentProcessor> child, SkMatrix matrix)
+    : INHERITED(kGrChildProcessorSampleMatrixSingleInUniform_ClassID, kNone_OptimizationFlags)
+    , matrix(matrix) {
+        this->registerChild(std::move(child), SkSL::SampleUsage::UniformMatrix("matrix", matrix.hasPerspective()));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniform.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniform.cpp
new file mode 100644
index 0000000..6f48548
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniform.cpp
@@ -0,0 +1,58 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixSingleUniform.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleMatrixSingleUniform.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleMatrixSingleUniform : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleMatrixSingleUniform() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleMatrixSingleUniform& _outer = args.fFp.cast<GrChildProcessorSampleMatrixSingleUniform>();
+        (void) _outer;
+        matrixVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kFloat3x3_GrSLType, "matrix");
+        SkString _sample93 = this->invokeChildWithMatrix(0, args);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s;
+)SkSL"
+, args.fOutputColor, _sample93.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+    UniformHandle matrixVar;
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleMatrixSingleUniform::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleMatrixSingleUniform();
+}
+void GrChildProcessorSampleMatrixSingleUniform::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleMatrixSingleUniform::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleMatrixSingleUniform& that = other.cast<GrChildProcessorSampleMatrixSingleUniform>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorSampleMatrixSingleUniform::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleMatrixSingleUniform::GrChildProcessorSampleMatrixSingleUniform(const GrChildProcessorSampleMatrixSingleUniform& src)
+: INHERITED(kGrChildProcessorSampleMatrixSingleUniform_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleMatrixSingleUniform::clone() const {
+    return std::make_unique<GrChildProcessorSampleMatrixSingleUniform>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleMatrixSingleUniform::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniform.h b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniform.h
new file mode 100644
index 0000000..6af5795
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniform.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixSingleUniform.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleMatrixSingleUniform_DEFINED
+#define GrChildProcessorSampleMatrixSingleUniform_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleMatrixSingleUniform : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleMatrixSingleUniform(std::move(child)));
+    }
+    GrChildProcessorSampleMatrixSingleUniform(const GrChildProcessorSampleMatrixSingleUniform& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleMatrixSingleUniform"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorSampleMatrixSingleUniform(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorSampleMatrixSingleUniform_ClassID, kNone_OptimizationFlags) {
+        this->registerChild(std::move(child), SkSL::SampleUsage::UniformMatrix("matrix", true));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniformExpr.cpp b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniformExpr.cpp
new file mode 100644
index 0000000..708de81
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniformExpr.cpp
@@ -0,0 +1,59 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixSingleUniformExpr.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorSampleMatrixSingleUniformExpr.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorSampleMatrixSingleUniformExpr : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorSampleMatrixSingleUniformExpr() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorSampleMatrixSingleUniformExpr& _outer = args.fFp.cast<GrChildProcessorSampleMatrixSingleUniformExpr>();
+        (void) _outer;
+        matrixVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kFloat3x3_GrSLType, "matrix");
+        SkString _matrix93 = SkStringPrintf("0.5 * %s", args.fUniformHandler->getUniformCStr(matrixVar));
+        SkString _sample93 = this->invokeChildWithMatrix(0, args, _matrix93.c_str());
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s;
+)SkSL"
+, args.fOutputColor, _sample93.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+    UniformHandle matrixVar;
+};
+GrGLSLFragmentProcessor* GrChildProcessorSampleMatrixSingleUniformExpr::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorSampleMatrixSingleUniformExpr();
+}
+void GrChildProcessorSampleMatrixSingleUniformExpr::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorSampleMatrixSingleUniformExpr::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorSampleMatrixSingleUniformExpr& that = other.cast<GrChildProcessorSampleMatrixSingleUniformExpr>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorSampleMatrixSingleUniformExpr::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorSampleMatrixSingleUniformExpr::GrChildProcessorSampleMatrixSingleUniformExpr(const GrChildProcessorSampleMatrixSingleUniformExpr& src)
+: INHERITED(kGrChildProcessorSampleMatrixSingleUniformExpr_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorSampleMatrixSingleUniformExpr::clone() const {
+    return std::make_unique<GrChildProcessorSampleMatrixSingleUniformExpr>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorSampleMatrixSingleUniformExpr::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniformExpr.h b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniformExpr.h
new file mode 100644
index 0000000..1d71be1
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorSampleMatrixSingleUniformExpr.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorSampleMatrixSingleUniformExpr.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorSampleMatrixSingleUniformExpr_DEFINED
+#define GrChildProcessorSampleMatrixSingleUniformExpr_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorSampleMatrixSingleUniformExpr : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorSampleMatrixSingleUniformExpr(std::move(child)));
+    }
+    GrChildProcessorSampleMatrixSingleUniformExpr(const GrChildProcessorSampleMatrixSingleUniformExpr& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorSampleMatrixSingleUniformExpr"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorSampleMatrixSingleUniformExpr(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorSampleMatrixSingleUniformExpr_ClassID, kNone_OptimizationFlags) {
+        this->registerChild(std::move(child), SkSL::SampleUsage::VariableMatrix(true));    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorWithInputExpression.cpp b/tests/sksl/fp/golden/GrChildProcessorWithInputExpression.cpp
new file mode 100644
index 0000000..904ff16
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorWithInputExpression.cpp
@@ -0,0 +1,59 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorWithInputExpression.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorWithInputExpression.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorWithInputExpression : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorWithInputExpression() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorWithInputExpression& _outer = args.fFp.cast<GrChildProcessorWithInputExpression>();
+        (void) _outer;
+        colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kHalf4_GrSLType, "color");
+        SkString _input89 = SkStringPrintf("%s * half4(0.5)", args.fUniformHandler->getUniformCStr(colorVar));
+        SkString _sample89 = this->invokeChild(0, _input89.c_str(), args);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s;
+)SkSL"
+, args.fOutputColor, _sample89.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+    UniformHandle colorVar;
+};
+GrGLSLFragmentProcessor* GrChildProcessorWithInputExpression::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorWithInputExpression();
+}
+void GrChildProcessorWithInputExpression::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorWithInputExpression::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorWithInputExpression& that = other.cast<GrChildProcessorWithInputExpression>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorWithInputExpression::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorWithInputExpression::GrChildProcessorWithInputExpression(const GrChildProcessorWithInputExpression& src)
+: INHERITED(kGrChildProcessorWithInputExpression_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorWithInputExpression::clone() const {
+    return std::make_unique<GrChildProcessorWithInputExpression>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorWithInputExpression::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorWithInputExpression.h b/tests/sksl/fp/golden/GrChildProcessorWithInputExpression.h
new file mode 100644
index 0000000..f5c4e92
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorWithInputExpression.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorWithInputExpression.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorWithInputExpression_DEFINED
+#define GrChildProcessorWithInputExpression_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorWithInputExpression : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorWithInputExpression(std::move(child)));
+    }
+    GrChildProcessorWithInputExpression(const GrChildProcessorWithInputExpression& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorWithInputExpression"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorWithInputExpression(std::unique_ptr<GrFragmentProcessor> child)
+    : INHERITED(kGrChildProcessorWithInputExpression_ClassID, kNone_OptimizationFlags) {
+        SkASSERT(child);        this->registerChild(std::move(child), SkSL::SampleUsage::PassThrough());    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessors.cpp b/tests/sksl/fp/golden/GrChildProcessors.cpp
new file mode 100644
index 0000000..4cdff0d
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessors.cpp
@@ -0,0 +1,57 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessors.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessors.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessors : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessors() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessors& _outer = args.fFp.cast<GrChildProcessors>();
+        (void) _outer;
+        SkString _sample97 = this->invokeChild(0, args);
+        SkString _sample114 = this->invokeChild(1, args);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = %s * %s;
+)SkSL"
+, args.fOutputColor, _sample97.c_str(), _sample114.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrChildProcessors::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessors();
+}
+void GrChildProcessors::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessors::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessors& that = other.cast<GrChildProcessors>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessors::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessors::GrChildProcessors(const GrChildProcessors& src)
+: INHERITED(kGrChildProcessors_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessors::clone() const {
+    return std::make_unique<GrChildProcessors>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessors::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessors.h b/tests/sksl/fp/golden/GrChildProcessors.h
new file mode 100644
index 0000000..7c5566c
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessors.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessors.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessors_DEFINED
+#define GrChildProcessors_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessors : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child1, std::unique_ptr<GrFragmentProcessor> child2) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessors(std::move(child1), std::move(child2)));
+    }
+    GrChildProcessors(const GrChildProcessors& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessors"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessors(std::unique_ptr<GrFragmentProcessor> child1, std::unique_ptr<GrFragmentProcessor> child2)
+    : INHERITED(kGrChildProcessors_ClassID, kNone_OptimizationFlags) {
+        SkASSERT(child1);        this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());        SkASSERT(child2);        this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorsWithInput.cpp b/tests/sksl/fp/golden/GrChildProcessorsWithInput.cpp
new file mode 100644
index 0000000..9d394bd
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorsWithInput.cpp
@@ -0,0 +1,70 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorsWithInput.fp; do not modify.
+ **************************************************************************************************/
+#include "GrChildProcessorsWithInput.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLChildProcessorsWithInput : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLChildProcessorsWithInput() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrChildProcessorsWithInput& _outer = args.fFp.cast<GrChildProcessorsWithInput>();
+        (void) _outer;
+        colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kHalf4_GrSLType, "color");
+        fragBuilder->codeAppendf(
+R"SkSL(half4 childIn = %s;)SkSL"
+, args.fUniformHandler->getUniformCStr(colorVar));
+        SkString _input150("childIn");
+        SkString _sample150 = this->invokeChild(0, _input150.c_str(), args);
+        fragBuilder->codeAppendf(
+R"SkSL(
+half4 childOut1 = %s;)SkSL"
+, _sample150.c_str());
+        SkString _input197("childOut1");
+        SkString _sample197 = this->invokeChild(1, _input197.c_str(), args);
+        fragBuilder->codeAppendf(
+R"SkSL(
+half4 childOut2 = %s;
+%s = childOut2;
+)SkSL"
+, _sample197.c_str(), args.fOutputColor);
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+    UniformHandle colorVar;
+};
+GrGLSLFragmentProcessor* GrChildProcessorsWithInput::onCreateGLSLInstance() const {
+    return new GrGLSLChildProcessorsWithInput();
+}
+void GrChildProcessorsWithInput::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrChildProcessorsWithInput::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrChildProcessorsWithInput& that = other.cast<GrChildProcessorsWithInput>();
+    (void) that;
+    return true;
+}
+bool GrChildProcessorsWithInput::usesExplicitReturn() const {
+    return false;
+}
+GrChildProcessorsWithInput::GrChildProcessorsWithInput(const GrChildProcessorsWithInput& src)
+: INHERITED(kGrChildProcessorsWithInput_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrChildProcessorsWithInput::clone() const {
+    return std::make_unique<GrChildProcessorsWithInput>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrChildProcessorsWithInput::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrChildProcessorsWithInput.h b/tests/sksl/fp/golden/GrChildProcessorsWithInput.h
new file mode 100644
index 0000000..34251dd
--- /dev/null
+++ b/tests/sksl/fp/golden/GrChildProcessorsWithInput.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrChildProcessorsWithInput.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrChildProcessorsWithInput_DEFINED
+#define GrChildProcessorsWithInput_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrChildProcessorsWithInput : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child1, std::unique_ptr<GrFragmentProcessor> child2) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrChildProcessorsWithInput(std::move(child1), std::move(child2)));
+    }
+    GrChildProcessorsWithInput(const GrChildProcessorsWithInput& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "ChildProcessorsWithInput"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrChildProcessorsWithInput(std::unique_ptr<GrFragmentProcessor> child1, std::unique_ptr<GrFragmentProcessor> child2)
+    : INHERITED(kGrChildProcessorsWithInput_ClassID, kNone_OptimizationFlags) {
+        SkASSERT(child1);        this->registerChild(std::move(child1), SkSL::SampleUsage::PassThrough());        SkASSERT(child2);        this->registerChild(std::move(child2), SkSL::SampleUsage::PassThrough());    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrGrSLTypesAreSupported.cpp b/tests/sksl/fp/golden/GrGrSLTypesAreSupported.cpp
new file mode 100644
index 0000000..8bf4eff
--- /dev/null
+++ b/tests/sksl/fp/golden/GrGrSLTypesAreSupported.cpp
@@ -0,0 +1,102 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrGrSLTypesAreSupported.fp; do not modify.
+ **************************************************************************************************/
+#include "GrGrSLTypesAreSupported.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLGrSLTypesAreSupported : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLGrSLTypesAreSupported() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrGrSLTypesAreSupported& _outer = args.fFp.cast<GrGrSLTypesAreSupported>();
+        (void) _outer;
+        SkString test_i_name;
+        const GrShaderVar test_i_args[] = { GrShaderVar("a", kInt_GrSLType)};
+        fragBuilder->emitFunction(kInt_GrSLType, "test_i", 1, test_i_args,
+R"SkSL(for (; ; ) {
+    return a;
+}
+)SkSL", &test_i_name);
+        SkString test_i2_name;
+        const GrShaderVar test_i2_args[] = { GrShaderVar("a", kInt2_GrSLType)};
+        fragBuilder->emitFunction(kInt2_GrSLType, "test_i2", 1, test_i2_args,
+R"SkSL(for (; ; ) {
+    return a;
+}
+)SkSL", &test_i2_name);
+        SkString test_i3_name;
+        const GrShaderVar test_i3_args[] = { GrShaderVar("a", kInt3_GrSLType)};
+        fragBuilder->emitFunction(kInt3_GrSLType, "test_i3", 1, test_i3_args,
+R"SkSL(for (; ; ) {
+    return a;
+}
+)SkSL", &test_i3_name);
+        SkString test_i4_name;
+        const GrShaderVar test_i4_args[] = { GrShaderVar("a", kInt4_GrSLType)};
+        fragBuilder->emitFunction(kInt4_GrSLType, "test_i4", 1, test_i4_args,
+R"SkSL(for (; ; ) {
+    return a;
+}
+)SkSL", &test_i4_name);
+        SkString test_h3x4_name;
+        const GrShaderVar test_h3x4_args[] = { GrShaderVar("a", kHalf3x4_GrSLType)};
+        fragBuilder->emitFunction(kHalf3x4_GrSLType, "test_h3x4", 1, test_h3x4_args,
+R"SkSL(for (; ; ) {
+    return a;
+}
+)SkSL", &test_h3x4_name);
+        SkString test_f2x4_name;
+        const GrShaderVar test_f2x4_args[] = { GrShaderVar("a", kFloat2x4_GrSLType)};
+        fragBuilder->emitFunction(kFloat2x4_GrSLType, "test_f2x4", 1, test_f2x4_args,
+R"SkSL(for (; ; ) {
+    return a;
+}
+)SkSL", &test_f2x4_name);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = half4(int4(%s(1)));
+%s = half4(%s(int2(1)).xxxx);
+%s = half4(%s(int3(1)).xxxx);
+%s = half4(%s(int4(1)).xxxx);
+%s = %s(half3x4(1.0))[0];
+%s = half4(%s(float2x4(1.0))[0]);
+)SkSL"
+, args.fOutputColor, test_i_name.c_str(), args.fOutputColor, test_i2_name.c_str(), args.fOutputColor, test_i3_name.c_str(), args.fOutputColor, test_i4_name.c_str(), args.fOutputColor, test_h3x4_name.c_str(), args.fOutputColor, test_f2x4_name.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrGrSLTypesAreSupported::onCreateGLSLInstance() const {
+    return new GrGLSLGrSLTypesAreSupported();
+}
+void GrGrSLTypesAreSupported::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrGrSLTypesAreSupported::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrGrSLTypesAreSupported& that = other.cast<GrGrSLTypesAreSupported>();
+    (void) that;
+    return true;
+}
+bool GrGrSLTypesAreSupported::usesExplicitReturn() const {
+    return false;
+}
+GrGrSLTypesAreSupported::GrGrSLTypesAreSupported(const GrGrSLTypesAreSupported& src)
+: INHERITED(kGrGrSLTypesAreSupported_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrGrSLTypesAreSupported::clone() const {
+    return std::make_unique<GrGrSLTypesAreSupported>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrGrSLTypesAreSupported::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrGrSLTypesAreSupported.h b/tests/sksl/fp/golden/GrGrSLTypesAreSupported.h
new file mode 100644
index 0000000..884e022
--- /dev/null
+++ b/tests/sksl/fp/golden/GrGrSLTypesAreSupported.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrGrSLTypesAreSupported.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrGrSLTypesAreSupported_DEFINED
+#define GrGrSLTypesAreSupported_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrGrSLTypesAreSupported : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make() {
+        return std::unique_ptr<GrFragmentProcessor>(new GrGrSLTypesAreSupported());
+    }
+    GrGrSLTypesAreSupported(const GrGrSLTypesAreSupported& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "GrSLTypesAreSupported"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrGrSLTypesAreSupported()
+    : INHERITED(kGrGrSLTypesAreSupported_ClassID, kNone_OptimizationFlags) {
+    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrLayoutWhen.cpp b/tests/sksl/fp/golden/GrLayoutWhen.cpp
new file mode 100644
index 0000000..cf37be4
--- /dev/null
+++ b/tests/sksl/fp/golden/GrLayoutWhen.cpp
@@ -0,0 +1,55 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrLayoutWhen.fp; do not modify.
+ **************************************************************************************************/
+#include "GrLayoutWhen.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLLayoutWhen : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLLayoutWhen() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrLayoutWhen& _outer = args.fFp.cast<GrLayoutWhen>();
+        (void) _outer;
+        if (someExpression(someOtherExpression())) {
+            sometimesVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kHalf_GrSLType, "sometimes");
+        }
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+    UniformHandle sometimesVar;
+};
+GrGLSLFragmentProcessor* GrLayoutWhen::onCreateGLSLInstance() const {
+    return new GrGLSLLayoutWhen();
+}
+void GrLayoutWhen::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrLayoutWhen::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrLayoutWhen& that = other.cast<GrLayoutWhen>();
+    (void) that;
+    return true;
+}
+bool GrLayoutWhen::usesExplicitReturn() const {
+    return false;
+}
+GrLayoutWhen::GrLayoutWhen(const GrLayoutWhen& src)
+: INHERITED(kGrLayoutWhen_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrLayoutWhen::clone() const {
+    return std::make_unique<GrLayoutWhen>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrLayoutWhen::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrLayoutWhen.h b/tests/sksl/fp/golden/GrLayoutWhen.h
new file mode 100644
index 0000000..5f27438
--- /dev/null
+++ b/tests/sksl/fp/golden/GrLayoutWhen.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrLayoutWhen.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrLayoutWhen_DEFINED
+#define GrLayoutWhen_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrLayoutWhen : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make() {
+        return std::unique_ptr<GrFragmentProcessor>(new GrLayoutWhen());
+    }
+    GrLayoutWhen(const GrLayoutWhen& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "LayoutWhen"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrLayoutWhen()
+    : INHERITED(kGrLayoutWhen_ClassID, kNone_OptimizationFlags) {
+    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrMainCoords.cpp b/tests/sksl/fp/golden/GrMainCoords.cpp
new file mode 100644
index 0000000..bcc4eed
--- /dev/null
+++ b/tests/sksl/fp/golden/GrMainCoords.cpp
@@ -0,0 +1,56 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrMainCoords.fp; do not modify.
+ **************************************************************************************************/
+#include "GrMainCoords.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLMainCoords : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLMainCoords() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrMainCoords& _outer = args.fFp.cast<GrMainCoords>();
+        (void) _outer;
+        fragBuilder->codeAppendf(
+R"SkSL(%s = half4(%s, %s);
+)SkSL"
+, args.fOutputColor, args.fSampleCoord, args.fSampleCoord);
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrMainCoords::onCreateGLSLInstance() const {
+    return new GrGLSLMainCoords();
+}
+void GrMainCoords::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrMainCoords::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrMainCoords& that = other.cast<GrMainCoords>();
+    (void) that;
+    return true;
+}
+bool GrMainCoords::usesExplicitReturn() const {
+    return false;
+}
+GrMainCoords::GrMainCoords(const GrMainCoords& src)
+: INHERITED(kGrMainCoords_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+    this->setUsesSampleCoordsDirectly();
+}
+std::unique_ptr<GrFragmentProcessor> GrMainCoords::clone() const {
+    return std::make_unique<GrMainCoords>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrMainCoords::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrMainCoords.h b/tests/sksl/fp/golden/GrMainCoords.h
new file mode 100644
index 0000000..36ae3bd
--- /dev/null
+++ b/tests/sksl/fp/golden/GrMainCoords.h
@@ -0,0 +1,38 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrMainCoords.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrMainCoords_DEFINED
+#define GrMainCoords_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrMainCoords : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make() {
+        return std::unique_ptr<GrFragmentProcessor>(new GrMainCoords());
+    }
+    GrMainCoords(const GrMainCoords& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "MainCoords"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrMainCoords()
+    : INHERITED(kGrMainCoords_ClassID, kNone_OptimizationFlags) {
+        this->setUsesSampleCoordsDirectly();
+    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif
diff --git a/tests/sksl/fp/golden/GrUniformArrays.cpp b/tests/sksl/fp/golden/GrUniformArrays.cpp
new file mode 100644
index 0000000..aa3070a
--- /dev/null
+++ b/tests/sksl/fp/golden/GrUniformArrays.cpp
@@ -0,0 +1,59 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrUniformArrays.fp; do not modify.
+ **************************************************************************************************/
+#include "GrUniformArrays.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLUniformArrays : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLUniformArrays() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrUniformArrays& _outer = args.fFp.cast<GrUniformArrays>();
+        (void) _outer;
+        scalarArrayVar = args.fUniformHandler->addUniformArray(&_outer, kFragment_GrShaderFlag, kHalf_GrSLType, "scalarArray", 4);
+        pointArrayVar = args.fUniformHandler->addUniformArray(&_outer, kFragment_GrShaderFlag, kHalf2_GrSLType, "pointArray", 2);
+        fragBuilder->codeAppendf(
+R"SkSL(%s = half4(((%s[0] * %s[0].x + %s[1] * %s[0].y) + %s[2] * %s[1].x) + %s[3] * %s[1].y);
+)SkSL"
+, args.fOutputColor, args.fUniformHandler->getUniformCStr(scalarArrayVar), args.fUniformHandler->getUniformCStr(pointArrayVar), args.fUniformHandler->getUniformCStr(scalarArrayVar), args.fUniformHandler->getUniformCStr(pointArrayVar), args.fUniformHandler->getUniformCStr(scalarArrayVar), args.fUniformHandler->getUniformCStr(pointArrayVar), args.fUniformHandler->getUniformCStr(scalarArrayVar), args.fUniformHandler->getUniformCStr(pointArrayVar));
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+    UniformHandle scalarArrayVar;
+    UniformHandle pointArrayVar;
+};
+GrGLSLFragmentProcessor* GrUniformArrays::onCreateGLSLInstance() const {
+    return new GrGLSLUniformArrays();
+}
+void GrUniformArrays::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrUniformArrays::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrUniformArrays& that = other.cast<GrUniformArrays>();
+    (void) that;
+    return true;
+}
+bool GrUniformArrays::usesExplicitReturn() const {
+    return false;
+}
+GrUniformArrays::GrUniformArrays(const GrUniformArrays& src)
+: INHERITED(kGrUniformArrays_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrUniformArrays::clone() const {
+    return std::make_unique<GrUniformArrays>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrUniformArrays::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/fp/golden/GrUniformArrays.h b/tests/sksl/fp/golden/GrUniformArrays.h
new file mode 100644
index 0000000..9aa905f
--- /dev/null
+++ b/tests/sksl/fp/golden/GrUniformArrays.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrUniformArrays.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrUniformArrays_DEFINED
+#define GrUniformArrays_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrUniformArrays : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make() {
+        return std::unique_ptr<GrFragmentProcessor>(new GrUniformArrays());
+    }
+    GrUniformArrays(const GrUniformArrays& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "UniformArrays"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrUniformArrays()
+    : INHERITED(kGrUniformArrays_ClassID, kNone_OptimizationFlags) {
+    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif