Migrate CopyConstants out of RP utils.

Nothing is landed which actually uses this yet, so it's a pretty
simple CL.

Change-Id: Ic285a4079d29af0ed02d61aab7ccd6a3e85223ae
Bug: skia:13676
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/620841
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkRasterPipelineUtils.cpp b/src/core/SkRasterPipelineUtils.cpp
index f94cf9f..2c56b89 100644
--- a/src/core/SkRasterPipelineUtils.cpp
+++ b/src/core/SkRasterPipelineUtils.cpp
@@ -8,65 +8,6 @@
 #include "src/core/SkOpts.h"
 #include "src/core/SkRasterPipelineUtils.h"
 
-void SkRasterPipelineUtils_Base::appendCopy(SkArenaAlloc* alloc,
-                                            SkRasterPipeline::Stage baseStage,
-                                            float* dst, int dstStride,
-                                            const float* src, int srcStride,
-                                            int numSlots) {
-    // TODO: remove me after migration to SkRasterPipelinerBuilder.cpp is complete
-    SkASSERT(numSlots >= 0);
-    while (numSlots > 4) {
-        this->appendCopy(alloc, baseStage, dst, dstStride, src, srcStride,  /*numSlots=*/4);
-        dst += 4 * dstStride;
-        src += 4 * srcStride;
-        numSlots -= 4;
-    }
-
-    if (numSlots > 0) {
-        SkASSERT(numSlots <= 4);
-        auto stage = (SkRasterPipeline::Stage)((int)baseStage + numSlots - 1);
-        auto* ctx = alloc->make<SkRasterPipeline_CopySlotsCtx>();
-        ctx->dst = dst;
-        ctx->src = src;
-        this->append(stage, ctx);
-    }
-}
-
-void SkRasterPipelineUtils_Base::appendCopySlotsMasked(SkArenaAlloc* alloc,
-                                                       float* dst,
-                                                       const float* src,
-                                                       int numSlots) {
-    // TODO: remove me after migration to SkRasterPipelinerBuilder.cpp is complete
-    this->appendCopy(alloc,
-                     SkRasterPipeline::copy_slot_masked,
-                     dst, /*dstStride=*/SkOpts::raster_pipeline_highp_stride,
-                     src, /*srcStride=*/SkOpts::raster_pipeline_highp_stride,
-                     numSlots);
-}
-
-void SkRasterPipelineUtils_Base::appendCopySlotsUnmasked(SkArenaAlloc* alloc,
-                                                         float* dst,
-                                                         const float* src,
-                                                         int numSlots) {
-    // TODO: remove me after migration to SkRasterPipelinerBuilder.cpp is complete
-    this->appendCopy(alloc,
-                     SkRasterPipeline::copy_slot_unmasked,
-                     dst, /*dstStride=*/SkOpts::raster_pipeline_highp_stride,
-                     src, /*srcStride=*/SkOpts::raster_pipeline_highp_stride,
-                     numSlots);
-}
-
-void SkRasterPipelineUtils_Base::appendCopyConstants(SkArenaAlloc* alloc,
-                                                     float* dst,
-                                                     const float* src,
-                                                     int numSlots) {
-    this->appendCopy(alloc,
-                     SkRasterPipeline::copy_constant,
-                     dst, /*dstStride=*/SkOpts::raster_pipeline_highp_stride,
-                     src, /*srcStride=*/1,
-                     numSlots);
-}
-
 void SkRasterPipelineUtils_Base::appendZeroSlotsUnmasked(float* dst, int numSlots) {
     SkASSERT(numSlots >= 0);
     while (numSlots > 4) {
diff --git a/src/core/SkRasterPipelineUtils.h b/src/core/SkRasterPipelineUtils.h
index a419586..bead2e0 100644
--- a/src/core/SkRasterPipelineUtils.h
+++ b/src/core/SkRasterPipelineUtils.h
@@ -16,11 +16,6 @@
     // Forwards `append` calls to a Raster Pipeline.
     virtual void append(SkRasterPipeline::Stage stage, void* ctx) = 0;
 
-    // Appends one or more `copy_n_slots_[un]masked` stages to the pipeline, based on `numSlots`.
-    void appendCopySlotsMasked(SkArenaAlloc* alloc, float* dst, const float* src, int numSlots);
-    void appendCopySlotsUnmasked(SkArenaAlloc* alloc, float* dst, const float* src, int numSlots);
-    void appendCopyConstants(SkArenaAlloc* alloc, float* dst, const float* src, int numSlots);
-
     // Appends one or more `zero_n_slots_unmasked` stages to the pipeline, based on `numSlots`.
     void appendZeroSlotsUnmasked(float* dst, int numSlots);
 
@@ -39,13 +34,6 @@
     // Appends a math operation with two inputs (dst op src) and one output (dst) to the pipeline.
     // `src` must be _immediately_ after `dst` in memory.
     void appendAdjacentSingleSlotOp(SkRasterPipeline::Stage stage, float* dst, const float* src);
-
-private:
-    void appendCopy(SkArenaAlloc* alloc,
-                    SkRasterPipeline::Stage baseStage,
-                    float* dst, int dstStride,
-                    const float* src, int srcStride,
-                    int numSlots);
 };
 
 class SkRasterPipelineUtils final : public SkRasterPipelineUtils_Base {
diff --git a/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp b/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
index f6fa497..748b544 100644
--- a/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
+++ b/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
@@ -250,6 +250,18 @@
                      numSlots);
 }
 
+void Program::appendCopyConstants(SkRasterPipeline* pipeline,
+                                  SkArenaAlloc* alloc,
+                                  float* dst,
+                                  const float* src,
+                                  int numSlots) {
+    this->appendCopy(pipeline, alloc,
+                     SkRasterPipeline::copy_constant,
+                     dst, /*dstStride=*/SkOpts::raster_pipeline_highp_stride,
+                     src, /*srcStride=*/1,
+                     numSlots);
+}
+
 template <typename T>
 [[maybe_unused]] static void* context_bit_pun(T val) {
     static_assert(sizeof(T) <= sizeof(void*));
diff --git a/src/sksl/codegen/SkSLRasterPipelineBuilder.h b/src/sksl/codegen/SkSLRasterPipelineBuilder.h
index e429e0c..3cb3f76 100644
--- a/src/sksl/codegen/SkSLRasterPipelineBuilder.h
+++ b/src/sksl/codegen/SkSLRasterPipelineBuilder.h
@@ -110,6 +110,8 @@
                                  float* dst, const float* src, int numSlots);
     void appendCopySlotsMasked(SkRasterPipeline* pipeline, SkArenaAlloc* alloc,
                                float* dst, const float* src, int numSlots);
+    void appendCopyConstants(SkRasterPipeline* pipeline, SkArenaAlloc* alloc,
+                             float* dst, const float* src, int numSlots);
 
     SkTArray<Instruction> fInstructions;
     int fNumValueSlots = 0;
diff --git a/tests/SkRasterPipelineTest.cpp b/tests/SkRasterPipelineTest.cpp
index d570b7f..6cb2097 100644
--- a/tests/SkRasterPipelineTest.cpp
+++ b/tests/SkRasterPipelineTest.cpp
@@ -595,30 +595,45 @@
 }
 
 DEF_TEST(SkRasterPipeline_CopyConstants, r) {
-    // Allocate space for 20 dest slots.
-    alignas(64) float slots[20 * SkRasterPipeline_kMaxStride_highp];
-    float constants[20];
+    // Allocate space for 5 dest slots.
+    alignas(64) float slots[5 * SkRasterPipeline_kMaxStride_highp];
+    float constants[5];
     const int N = SkOpts::raster_pipeline_highp_stride;
 
-    for (int slotCount = 0; slotCount < 20; ++slotCount) {
+    struct CopySlotsOp {
+        SkRasterPipeline::Stage stage;
+        int numSlotsAffected;
+    };
+
+    static const CopySlotsOp kCopyOps[] = {
+        {SkRasterPipeline::Stage::copy_constant,    1},
+        {SkRasterPipeline::Stage::copy_2_constants, 2},
+        {SkRasterPipeline::Stage::copy_3_constants, 3},
+        {SkRasterPipeline::Stage::copy_4_constants, 4},
+    };
+
+    for (const CopySlotsOp& op : kCopyOps) {
         // Initialize the destination slots to 1,2,3...
-        std::iota(&slots[0], &slots[20 * N], 1.0f);
+        std::iota(&slots[0], &slots[5 * N], 1.0f);
         // Initialize the constant buffer to 1000,1001,1002...
-        std::iota(&constants[0], &constants[20], 1000.0f);
+        std::iota(&constants[0], &constants[5], 1000.0f);
 
         // Run `copy_constants` over our data.
         SkArenaAlloc alloc(/*firstHeapAllocation=*/256);
         SkRasterPipeline p(&alloc);
-        SkRasterPipelineUtils(p).appendCopyConstants(&alloc, &slots[0], constants, slotCount);
-        p.run(0,0,20,1);
+        auto* ctx = alloc.make<SkRasterPipeline_CopySlotsCtx>();
+        ctx->dst = slots;
+        ctx->src = constants;
+        p.append(op.stage, ctx);
+        p.run(0,0,1,1);
 
         // Verify that our constants have been broadcast into each slot.
         float expectedUnchanged = 1.0f;
         float expectedChanged = 1000.0f;
         float* destPtr = &slots[0];
-        for (int checkSlot = 0; checkSlot < 20; ++checkSlot) {
+        for (int checkSlot = 0; checkSlot < 5; ++checkSlot) {
             for (int checkLane = 0; checkLane < N; ++checkLane) {
-                if (checkSlot < slotCount) {
+                if (checkSlot < op.numSlotsAffected) {
                     REPORTER_ASSERT(r, *destPtr == expectedChanged);
                 } else {
                     REPORTER_ASSERT(r, *destPtr == expectedUnchanged);