In GrConvertPixels, hoist pipeline creation out of the loop

This only impacts the case where we're doing a Y-flip, but there's no
reason to rebuild the pipeline for each row.

Change-Id: I64a231bbdb83819b1c22d2d3946035e832032bbd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/572524
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ganesh/GrDataUtils.cpp b/src/gpu/ganesh/GrDataUtils.cpp
index d03fb81..433d4d9 100644
--- a/src/gpu/ganesh/GrDataUtils.cpp
+++ b/src/gpu/ganesh/GrDataUtils.cpp
@@ -656,47 +656,49 @@
 
     hasConversion = hasConversion || srcIsSRGB || dstIsSRGB;
 
-    for (int i = 0; i < cnt; ++i) {
-        SkRasterPipeline_<256> pipeline;
-        pipeline.append(load, &srcCtx);
-        if (hasConversion) {
-            loadSwizzle.apply(&pipeline);
-            if (srcIsSRGB) {
-                pipeline.append_transfer_function(*skcms_sRGB_TransferFunction());
-            }
-            if (alphaOrCSConversion) {
-                steps->apply(&pipeline);
-            }
-            if (clampGamut) {
-                append_clamp_gamut(&pipeline);
-            }
-            switch (lumMode) {
-                case LumMode::kNone:
-                    break;
-                case LumMode::kToRGB:
-                    pipeline.append(SkRasterPipeline::StockStage::bt709_luminance_or_luma_to_rgb);
-                    break;
-                case LumMode::kToAlpha:
-                    pipeline.append(SkRasterPipeline::StockStage::bt709_luminance_or_luma_to_alpha);
-                    // If we ever need to store srgb-encoded gray (e.g. GL_SLUMINANCE8) then we
-                    // should use ToRGB and then a swizzle stage rather than ToAlpha. The subsequent
-                    // transfer function stage ignores the alpha channel (where we just stashed the
-                    // gray).
-                    SkASSERT(!dstIsSRGB);
-                    break;
-            }
-            if (dstIsSRGB) {
-                pipeline.append_transfer_function(*skcms_sRGB_Inverse_TransferFunction());
-            }
-            storeSwizzle.apply(&pipeline);
-        } else {
-            loadStoreSwizzle.apply(&pipeline);
+    SkRasterPipeline_<256> pipeline;
+    pipeline.append(load, &srcCtx);
+    if (hasConversion) {
+        loadSwizzle.apply(&pipeline);
+        if (srcIsSRGB) {
+            pipeline.append_transfer_function(*skcms_sRGB_TransferFunction());
         }
-        pipeline.append(store, &dstCtx);
-        pipeline.run(0, 0, src.width(), height);
+        if (alphaOrCSConversion) {
+            steps->apply(&pipeline);
+        }
+        if (clampGamut) {
+            append_clamp_gamut(&pipeline);
+        }
+        switch (lumMode) {
+            case LumMode::kNone:
+                break;
+            case LumMode::kToRGB:
+                pipeline.append(SkRasterPipeline::StockStage::bt709_luminance_or_luma_to_rgb);
+                break;
+            case LumMode::kToAlpha:
+                pipeline.append(SkRasterPipeline::StockStage::bt709_luminance_or_luma_to_alpha);
+                // If we ever need to store srgb-encoded gray (e.g. GL_SLUMINANCE8) then we
+                // should use ToRGB and then a swizzle stage rather than ToAlpha. The subsequent
+                // transfer function stage ignores the alpha channel (where we just stashed the
+                // gray).
+                SkASSERT(!dstIsSRGB);
+                break;
+        }
+        if (dstIsSRGB) {
+            pipeline.append_transfer_function(*skcms_sRGB_Inverse_TransferFunction());
+        }
+        storeSwizzle.apply(&pipeline);
+    } else {
+        loadStoreSwizzle.apply(&pipeline);
+    }
+    pipeline.append(store, &dstCtx);
+    auto pipelineFn = pipeline.compile();
+    for (int i = 0; i < cnt; ++i) {
+        pipelineFn(0, 0, src.width(), height);
         srcCtx.pixels = static_cast<char*>(srcCtx.pixels) - src.rowBytes();
         dstCtx.pixels = static_cast<char*>(dstCtx.pixels) + dst.rowBytes();
     }
+
     return true;
 }