Support specializing uniforms in runtime FPs

http://go/rteffect-uniform-enhancements

Change-Id: Icb69b87049488a3baf234d45fe1e6a3c96a16d5e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/417856
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index dea6c42..5e889ac 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -17,6 +17,7 @@
 #include "src/core/SkRuntimeEffectPriv.h"
 #include "src/core/SkTLazy.h"
 #include "src/gpu/GrColor.h"
+#include "src/gpu/GrDirectContextPriv.h"
 #include "src/gpu/GrFragmentProcessor.h"
 #include "src/gpu/effects/GrSkSLFP.h"
 #include "tests/Test.h"
@@ -632,3 +633,39 @@
     test("half4 helper(float2 xy) { return sample(child, xy); }"
          "half4 main(float2 xy) { return helper(xy); }", true, true);
 }
+
+DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSkSLFP_Specialized, r, ctxInfo) {
+    struct FpAndKey {
+        std::unique_ptr<GrFragmentProcessor> fp;
+        SkTArray<uint32_t, true>             key;
+    };
+
+    // Constant color, but with a similar option to GrOverrideInputFragmentProcessor
+    // specialize decides if the color is inserted in the SkSL as a literal, or left as a uniform
+    auto make_color_fp = [&](SkPMColor4f color, bool specialize) {
+        auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader, R"(
+            uniform half4 color;
+            half4 main(float2 xy) { return color; }
+        )");
+        FpAndKey result;
+        result.fp = GrSkSLFP::Make(
+                std::move(effect), "color_fp", "color", GrSkSLFP::SpecializeIf(specialize, color));
+        GrProcessorKeyBuilder builder(&result.key);
+        result.fp->getGLSLProcessorKey(*ctxInfo.directContext()->priv().caps()->shaderCaps(),
+                                       &builder);
+        builder.flush();
+        return result;
+    };
+
+    FpAndKey uRed   = make_color_fp({1, 0, 0, 1}, false),
+             uGreen = make_color_fp({0, 1, 0, 1}, false),
+             sRed   = make_color_fp({1, 0, 0, 1}, true),
+             sGreen = make_color_fp({0, 1, 0, 1}, true);
+
+    // uRed and uGreen should have the same key - they just have different uniforms
+    SkASSERT(uRed.key == uGreen.key);
+    // sRed and sGreen should have keys that are different from the uniform case, and each other
+    SkASSERT(sRed.key != uRed.key);
+    SkASSERT(sGreen.key != uRed.key);
+    SkASSERT(sRed.key != sGreen.key);
+}