Use SkSpan to represent arrays in GrSkSLFP::Make.

This will allow a uniform array to be used in make_unrolled_colorizer
(or anywhere else that we might need one).

Change-Id: I9246f8d3121353b029fd36924fb874d838e67d9c
Bug: skia:8401
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/456238
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index 7fac5ee..3d3e468 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -22,6 +22,8 @@
 #include "src/gpu/GrColor.h"
 #include "src/gpu/GrDirectContextPriv.h"
 #include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/GrImageInfo.h"
+#include "src/gpu/SurfaceFillContext.h"
 #include "src/gpu/effects/GrSkSLFP.h"
 #include "tests/Test.h"
 
@@ -905,3 +907,48 @@
     SkASSERT(sGreen.key != uRed.key);
     SkASSERT(sRed.key != sGreen.key);
 }
+
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrSkSLFP_UniformArray, r, ctxInfo) {
+    // Make a fill-context to draw into.
+    GrDirectContext* directContext = ctxInfo.directContext();
+    SkImageInfo info = SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+    std::unique_ptr<skgpu::SurfaceFillContext> testCtx =
+            directContext->priv().makeSFC(info, SkBackingFit::kExact);
+
+    // Make an effect that takes a uniform array as input.
+    static constexpr std::array<float, 4> kRed  {1.0f, 0.0f, 0.0f, 1.0f};
+    static constexpr std::array<float, 4> kGreen{0.0f, 1.0f, 0.0f, 1.0f};
+    static constexpr std::array<float, 4> kBlue {0.0f, 0.0f, 1.0f, 1.0f};
+    static constexpr std::array<float, 4> kGray {0.499f, 0.499f, 0.499f, 1.0f};
+
+    for (const auto& colorArray : {kRed, kGreen, kBlue, kGray}) {
+        // Compile our runtime effect.
+        auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader, R"(
+            uniform half color[4];
+            half4 main(float2 xy) { return half4(color[0], color[1], color[2], color[3]); }
+        )");
+        // Render our shader into the fill-context with our various input colors.
+        testCtx->fillWithFP(GrSkSLFP::Make(std::move(effect), "test_fp",
+                                           /*inputFP=*/nullptr,
+                                           GrSkSLFP::OptFlags::kNone,
+                                           "color", SkMakeSpan(colorArray)));
+        // Read our color back and ensure it matches.
+        GrColor actual;
+        GrPixmap pixmap(info, &actual, sizeof(GrColor));
+        if (!testCtx->readPixels(directContext, pixmap, /*srcPt=*/{0, 0})) {
+            REPORT_FAILURE(r, "readPixels", SkString("readPixels failed"));
+            break;
+        }
+        if (actual != GrColorPackRGBA(255 * colorArray[0], 255 * colorArray[1],
+                                      255 * colorArray[2], 255 * colorArray[3])) {
+            REPORT_FAILURE(r, "Uniform array didn't match expectations",
+                           SkStringPrintf("\n"
+                                          "Expected: [ %g %g %g %g ]\n"
+                                          "Got     : [ %08x ]\n",
+                                          colorArray[0], colorArray[1],
+                                          colorArray[2], colorArray[3],
+                                          actual));
+            break;
+        }
+    }
+}