Add Swizzle FP, and remove swizzle logic from GrConfigConversionEffect

Trying to decompose read/writePixels into some reusable chunks.

BUG=skia:5853

Change-Id: If08b004b008e8ca7d464d9dc47068e487bae850a
Reviewed-on: https://skia-review.googlesource.com/10015
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 678add7..959a0fa 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -424,11 +424,9 @@
      * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
      * return NULL. They also can perform a swizzle as part of the draw.
      */
-    sk_sp<GrFragmentProcessor> createPMToUPMEffect(GrTexture*, const GrSwizzle&, const SkMatrix&);
-    sk_sp<GrFragmentProcessor> createPMToUPMEffect(sk_sp<GrTextureProxy>, const GrSwizzle&,
-                                                   const SkMatrix&);
-    sk_sp<GrFragmentProcessor> createUPMToPMEffect(sk_sp<GrTextureProxy>, const GrSwizzle&,
-                                                   const SkMatrix&);
+    sk_sp<GrFragmentProcessor> createPMToUPMEffect(GrTexture*, const SkMatrix&);
+    sk_sp<GrFragmentProcessor> createPMToUPMEffect(sk_sp<GrTextureProxy>, const SkMatrix&);
+    sk_sp<GrFragmentProcessor> createUPMToPMEffect(sk_sp<GrTextureProxy>, const SkMatrix&);
     /** Called before either of the above two functions to determine the appropriate fragment
         processors for conversions. */
     void testPMConversionsIfNecessary(uint32_t flags);
diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h
index faf17c1..c95c5e5 100644
--- a/include/gpu/GrFragmentProcessor.h
+++ b/include/gpu/GrFragmentProcessor.h
@@ -16,6 +16,7 @@
 class GrPipeline;
 class GrProcessorKeyBuilder;
 class GrShaderCaps;
+class GrSwizzle;
 
 /** Provides custom fragment shader code. Fragment processors receive an input color (vec4f) and
     produce an output color. They may reference textures and uniforms. They may use
@@ -68,6 +69,12 @@
     static sk_sp<GrFragmentProcessor> UnpremulOutput(sk_sp<GrFragmentProcessor>);
 
     /**
+     *  Returns a fragment processor that calls the passed in fragment processor, and then swizzles
+     *  the output.
+     */
+    static sk_sp<GrFragmentProcessor> SwizzleOutput(sk_sp<GrFragmentProcessor>, const GrSwizzle&);
+
+    /**
      * Returns a fragment processor that runs the passed in array of fragment processors in a
      * series. The original input is passed to the first, the first's output is passed to the
      * second, etc. The output of the returned processor is the output of the last processor of the
diff --git a/include/private/GrSwizzle.h b/include/private/GrSwizzle.h
index 4acf7e4..391740b 100644
--- a/include/private/GrSwizzle.h
+++ b/include/private/GrSwizzle.h
@@ -90,6 +90,25 @@
         return GrColorPackRGBA(outR, outG, outB, outA);
     }
 
+    /** Applies this swizzle to the input color and returns the swizzled color. */
+    GrColor4f applyTo(const GrColor4f& color) const {
+        int idx;
+        uint32_t key = fKey;
+        // Index of the input color that should be mapped to output r.
+        idx = (key & 3);
+        float outR = color.fRGBA[idx];
+        key >>= 2;
+        idx = (key & 3);
+        float outG = color.fRGBA[idx];
+        key >>= 2;
+        idx = (key & 3);
+        float outB = color.fRGBA[idx];
+        key >>= 2;
+        idx = (key & 3);
+        float outA = color.fRGBA[idx];
+        return GrColor4f(outR, outG, outB, outA);
+    }
+
     static GrSwizzle RGBA() { return GrSwizzle("rgba"); }
     static GrSwizzle AAAA() { return GrSwizzle("aaaa"); }
     static GrSwizzle RRRR() { return GrSwizzle("rrrr"); }
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 671376f..93fd324 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -242,6 +242,10 @@
     return true;
 }
 
+static bool valid_unpremul_config(GrPixelConfig config) {
+    return GrPixelConfigIs8888Unorm(config) || kRGBA_half_GrPixelConfig == config;
+}
+
 bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpace,
                                    int left, int top, int width, int height,
                                    GrPixelConfig srcConfig, SkColorSpace* srcColorSpace,
@@ -264,12 +268,9 @@
         return false;
     }
 
-    bool applyPremulToSrc = false;
-    if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
-        if (!GrPixelConfigIs8888Unorm(srcConfig) && kRGBA_half_GrPixelConfig != srcConfig) {
-            return false;
-        }
-        applyPremulToSrc = true;
+    bool applyPremulToSrc = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
+    if (applyPremulToSrc && !valid_unpremul_config(srcConfig)) {
+        return false;
     }
     // We don't allow conversion between integer configs and float/fixed configs.
     if (GrPixelConfigIsSint(surface->config()) != GrPixelConfigIsSint(srcConfig)) {
@@ -309,7 +310,8 @@
     if (tempProxy) {
         sk_sp<GrFragmentProcessor> fp;
         if (applyPremulToSrc) {
-            fp = this->createUPMToPMEffect(tempProxy, tempDrawInfo.fSwizzle, SkMatrix::I());
+            fp = this->createUPMToPMEffect(tempProxy, SkMatrix::I());
+            fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
             // If premultiplying was the only reason for the draw, fall back to a straight write.
             if (!fp) {
                 if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
@@ -321,10 +323,10 @@
         }
         if (tempProxy) {
             if (!fp) {
-                fp = GrConfigConversionEffect::Make(this->resourceProvider(),
-                                                    tempProxy, tempDrawInfo.fSwizzle,
-                                                    GrConfigConversionEffect::kNone_PMConversion,
-                                                    SkMatrix::I());
+                fp = GrSimpleTextureEffect::Make(this->resourceProvider(), tempProxy, nullptr,
+                                                 SkMatrix::I());
+                fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
+
                 if (!fp) {
                     return false;
                 }
@@ -422,7 +424,7 @@
     }
 
     bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
-    if (unpremul && !GrPixelConfigIs8888Unorm(dstConfig) && kRGBA_half_GrPixelConfig != dstConfig) {
+    if (unpremul && !valid_unpremul_config(dstConfig)) {
         // The unpremul flag is only allowed for 8888 and F16 configs.
         return false;
     }
@@ -469,8 +471,8 @@
             SkMatrix textureMatrix = SkMatrix::MakeTrans(SkIntToScalar(left), SkIntToScalar(top));
             sk_sp<GrFragmentProcessor> fp;
             if (unpremul) {
-                fp = this->createPMToUPMEffect(src->asTexture(), tempDrawInfo.fSwizzle,
-                                               textureMatrix);
+                fp = this->createPMToUPMEffect(src->asTexture(), textureMatrix);
+                fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
                 if (fp) {
                     unpremul = false; // we no longer need to do this on CPU after the read back.
                 } else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
@@ -480,9 +482,8 @@
                 }
             }
             if (!fp && tempRTC) {
-                fp = GrConfigConversionEffect::Make(src->asTexture(), tempDrawInfo.fSwizzle,
-                                                    GrConfigConversionEffect::kNone_PMConversion,
-                                                    textureMatrix);
+                fp = GrSimpleTextureEffect::Make(src->asTexture(), nullptr, textureMatrix);
+                fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
             }
             if (fp) {
                 GrPaint paint;
@@ -860,20 +861,18 @@
 }
 
 sk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(GrTexture* texture,
-                                                          const GrSwizzle& swizzle,
                                                           const SkMatrix& matrix) {
     ASSERT_SINGLE_OWNER
     // We should have already called this->testPMConversionsIfNecessary().
     SkASSERT(fDidTestPMConversions);
     if (kRGBA_half_GrPixelConfig == texture->config()) {
-        SkASSERT(swizzle == GrSwizzle::RGBA());
         return GrFragmentProcessor::UnpremulOutput(
                 GrSimpleTextureEffect::Make(texture, nullptr, matrix));
     } else {
         GrConfigConversionEffect::PMConversion pmToUPM =
             static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
-        if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
-            return GrConfigConversionEffect::Make(texture, swizzle, pmToUPM, matrix);
+        if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) {
+            return GrConfigConversionEffect::Make(texture, pmToUPM, matrix);
         } else {
             return nullptr;
         }
@@ -881,22 +880,20 @@
 }
 
 sk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(sk_sp<GrTextureProxy> proxy,
-                                                          const GrSwizzle& swizzle,
                                                           const SkMatrix& matrix) {
     ASSERT_SINGLE_OWNER
     // We should have already called this->testPMConversionsIfNecessary().
     SkASSERT(fDidTestPMConversions);
     if (kRGBA_half_GrPixelConfig == proxy->config()) {
-        SkASSERT(swizzle == GrSwizzle::RGBA());
         return GrFragmentProcessor::UnpremulOutput(
                 GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
                                             nullptr, matrix));
     } else {
         GrConfigConversionEffect::PMConversion pmToUPM =
             static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
-        if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
+        if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) {
             return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
-                                                  swizzle, pmToUPM, matrix);
+                                                  pmToUPM, matrix);
         } else {
             return nullptr;
         }
@@ -904,22 +901,20 @@
 }
 
 sk_sp<GrFragmentProcessor> GrContext::createUPMToPMEffect(sk_sp<GrTextureProxy> proxy,
-                                                          const GrSwizzle& swizzle,
                                                           const SkMatrix& matrix) {
     ASSERT_SINGLE_OWNER
     // We should have already called this->testPMConversionsIfNecessary().
     SkASSERT(fDidTestPMConversions);
     if (kRGBA_half_GrPixelConfig == proxy->config()) {
-        SkASSERT(swizzle == GrSwizzle::RGBA());
         return GrFragmentProcessor::PremulOutput(
                 GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
                                             nullptr, matrix));
     } else {
         GrConfigConversionEffect::PMConversion upmToPM =
             static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
-        if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
+        if (GrConfigConversionEffect::kPMConversionCnt != upmToPM) {
             return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
-                                                  swizzle, upmToPM, matrix);
+                                                  upmToPM, matrix);
         } else {
             return nullptr;
         }
@@ -932,7 +927,7 @@
     SkASSERT(fDidTestPMConversions);
     // The PM<->UPM tests fail or succeed together so we only need to check one.
     // For F16, we always allow PM/UPM conversion on the GPU, even if it doesn't round-trip.
-    return GrConfigConversionEffect::kNone_PMConversion != fPMToUPMConversion ||
+    return GrConfigConversionEffect::kPMConversionCnt != fPMToUPMConversion ||
            kRGBA_half_GrPixelConfig == config;
 }
 
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 27d0bcd..0d1bfad 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -207,6 +207,63 @@
     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
 }
 
+sk_sp<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(sk_sp<GrFragmentProcessor> fp,
+                                                              const GrSwizzle& swizzle) {
+    class SwizzleFragmentProcessor : public GrFragmentProcessor {
+    public:
+        SwizzleFragmentProcessor(const GrSwizzle& swizzle)
+                : INHERITED(kAll_OptimizationFlags)
+                , fSwizzle(swizzle) {
+            this->initClassID<SwizzleFragmentProcessor>();
+        }
+
+        const char* name() const override { return "Swizzle"; }
+        const GrSwizzle& swizzle() const { return fSwizzle; }
+
+    private:
+        GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
+            class GLFP : public GrGLSLFragmentProcessor {
+            public:
+                void emitCode(EmitArgs& args) override {
+                    const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
+                    const GrSwizzle& swizzle = sfp.swizzle();
+                    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+
+                    fragBuilder->codeAppendf("%s = %s.%s;",
+                                             args.fOutputColor, args.fInputColor, swizzle.c_str());
+                }
+            };
+            return new GLFP;
+        }
+
+        void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
+            b->add32(fSwizzle.asKey());
+        }
+
+        bool onIsEqual(const GrFragmentProcessor& other) const override {
+            const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
+            return fSwizzle == sfp.fSwizzle;
+        }
+
+        GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
+            return fSwizzle.applyTo(input);
+        }
+
+        GrSwizzle fSwizzle;
+
+        typedef GrFragmentProcessor INHERITED;
+    };
+
+    if (!fp) {
+        return nullptr;
+    }
+    if (GrSwizzle::RGBA() == swizzle) {
+        return fp;
+    }
+    sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<SwizzleFragmentProcessor>(swizzle) };
+    return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
+}
+
 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
         sk_sp<GrFragmentProcessor> fp) {
 
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index bb341dd..2c6589d 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -19,7 +19,6 @@
 public:
     void emitCode(EmitArgs& args) override {
         const GrConfigConversionEffect& cce = args.fFp.cast<GrConfigConversionEffect>();
-        const GrSwizzle& swizzle = cce.swizzle();
         GrConfigConversionEffect::PMConversion pmConversion = cce.pmConversion();
 
         // Using highp for GLES here in order to avoid some precision issues on specific GPUs.
@@ -36,46 +35,40 @@
                                          args.fTransformedCoords[0].getType());
         fragBuilder->codeAppend(";");
 
-        if (GrConfigConversionEffect::kNone_PMConversion == pmConversion) {
-            SkASSERT(GrSwizzle::RGBA() != swizzle);
-            fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
-                                     swizzle.c_str());
-        } else {
-            switch (pmConversion) {
-                case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
-                    fragBuilder->codeAppendf(
-                        "%s = vec4(ceil(%s.rgb * %s.a * 255.0) / 255.0, %s.a);",
-                        tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str());
-                    break;
-                case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion:
-                    // Add a compensation(0.001) here to avoid the side effect of the floor operation.
-                    // In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0
-                    // is less than the integer value converted from  %s.r by 1 when the %s.r is
-                    // converted from the integer value 2^n, such as 1, 2, 4, 8, etc.
-                    fragBuilder->codeAppendf(
-                        "%s = vec4(floor(%s.rgb * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
-                        tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str());
+        switch (pmConversion) {
+            case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
+                fragBuilder->codeAppendf(
+                    "%s = vec4(ceil(%s.rgb * %s.a * 255.0) / 255.0, %s.a);",
+                    tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str());
+                break;
+            case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion:
+                // Add a compensation(0.001) here to avoid the side effect of the floor operation.
+                // In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0
+                // is less than the integer value converted from  %s.r by 1 when the %s.r is
+                // converted from the integer value 2^n, such as 1, 2, 4, 8, etc.
+                fragBuilder->codeAppendf(
+                    "%s = vec4(floor(%s.rgb * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
+                    tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str());
 
-                    break;
-                case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
-                    fragBuilder->codeAppendf(
-                        "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.rgb / %s.a * 255.0) / 255.0, %s.a);",
-                        tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(),
-                        tmpVar.c_str());
-                    break;
-                case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion:
-                    fragBuilder->codeAppendf(
-                        "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.rgb / %s.a * 255.0) / 255.0, %s.a);",
-                        tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(),
-                        tmpVar.c_str());
-                    break;
-                default:
-                    SkFAIL("Unknown conversion op.");
-                    break;
-            }
-            fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
-                                     swizzle.c_str());
+                break;
+            case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
+                fragBuilder->codeAppendf(
+                    "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.rgb / %s.a * 255.0) / 255.0, %s.a);",
+                    tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(),
+                    tmpVar.c_str());
+                break;
+            case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion:
+                fragBuilder->codeAppendf(
+                    "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.rgb / %s.a * 255.0) / 255.0, %s.a);",
+                    tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(),
+                    tmpVar.c_str());
+                break;
+            default:
+                SkFAIL("Unknown conversion op.");
+                break;
         }
+        fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, tmpVar.c_str());
+
         SkString modulate;
         GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
         fragBuilder->codeAppend(modulate.c_str());
@@ -84,7 +77,7 @@
     static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&,
                               GrProcessorKeyBuilder* b) {
         const GrConfigConversionEffect& cce = processor.cast<GrConfigConversionEffect>();
-        uint32_t key = (cce.swizzle().asKey()) | (cce.pmConversion() << 16);
+        uint32_t key = cce.pmConversion();
         b->add32(key);
     }
 
@@ -95,45 +88,33 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
-                                                   const GrSwizzle& swizzle,
                                                    PMConversion pmConversion,
                                                    const SkMatrix& matrix)
         : INHERITED(texture, nullptr, matrix, kNone_OptimizationFlags)
-        , fSwizzle(swizzle)
         , fPMConversion(pmConversion) {
     this->initClassID<GrConfigConversionEffect>();
     // We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul
     // conversion.
-    SkASSERT((kRGBA_8888_GrPixelConfig == texture->config() ||
-              kBGRA_8888_GrPixelConfig == texture->config()) ||
-              kNone_PMConversion == pmConversion);
-    // Why did we pollute our texture cache instead of using a GrSingleTextureEffect?
-    SkASSERT(swizzle != GrSwizzle::RGBA() || kNone_PMConversion != pmConversion);
+    SkASSERT(kRGBA_8888_GrPixelConfig == texture->config() ||
+             kBGRA_8888_GrPixelConfig == texture->config());
 }
 
 GrConfigConversionEffect::GrConfigConversionEffect(GrResourceProvider* resourceProvider,
-                                                   sk_sp<GrTextureProxy>
-                                                           proxy,
-                                                   const GrSwizzle& swizzle,
+                                                   sk_sp<GrTextureProxy> proxy,
                                                    PMConversion pmConversion,
                                                    const SkMatrix& matrix)
         : INHERITED(resourceProvider, kNone_OptimizationFlags, proxy, nullptr, matrix)
-        , fSwizzle(swizzle)
         , fPMConversion(pmConversion) {
     this->initClassID<GrConfigConversionEffect>();
     // We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul
     // conversion.
-    SkASSERT((kRGBA_8888_GrPixelConfig == proxy->config() ||
-              kBGRA_8888_GrPixelConfig == proxy->config()) ||
-              kNone_PMConversion == pmConversion);
-    // Why did we pollute our texture cache instead of using a GrSingleTextureEffect?
-    SkASSERT(swizzle != GrSwizzle::RGBA() || kNone_PMConversion != pmConversion);
+    SkASSERT(kRGBA_8888_GrPixelConfig == proxy->config() ||
+             kBGRA_8888_GrPixelConfig == proxy->config());
 }
 
 bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& s) const {
     const GrConfigConversionEffect& other = s.cast<GrConfigConversionEffect>();
-    return other.fSwizzle == fSwizzle &&
-           other.fPMConversion == fPMConversion;
+    return other.fPMConversion == fPMConversion;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -149,14 +130,10 @@
 #if GR_TEST_UTILS
 sk_sp<GrFragmentProcessor> GrConfigConversionEffect::TestCreate(GrProcessorTestData* d) {
     PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kPMConversionCnt));
-    GrSwizzle swizzle;
-    do {
-        swizzle = GrSwizzle::CreateRandom(d->fRandom);
-    } while (pmConv == kNone_PMConversion && swizzle == GrSwizzle::RGBA());
     return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(
                             d->resourceProvider(),
                             d->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx),
-                            swizzle, pmConv, GrTest::TestMatrix(d->fRandom)));
+                            pmConv, GrTest::TestMatrix(d->fRandom)));
 }
 #endif
 
@@ -181,8 +158,8 @@
 void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context,
                                                               PMConversion* pmToUPMRule,
                                                               PMConversion* upmToPMRule) {
-    *pmToUPMRule = kNone_PMConversion;
-    *upmToPMRule = kNone_PMConversion;
+    *pmToUPMRule = kPMConversionCnt;
+    *upmToPMRule = kPMConversionCnt;
     static constexpr int kSize = 256;
     static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig;
     SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
@@ -219,8 +196,9 @@
     desc.fHeight = kSize;
     desc.fConfig = kConfig;
 
-    sk_sp<GrTextureProxy> dataProxy = GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
-                                                                   desc, SkBudgeted::kYes, data, 0);
+    GrResourceProvider* resourceProvider = context->resourceProvider();
+    sk_sp<GrTextureProxy> dataProxy = GrSurfaceProxy::MakeDeferred(resourceProvider, desc,
+                                                                   SkBudgeted::kYes, data, 0);
     if (!dataProxy) {
         return;
     }
@@ -249,14 +227,11 @@
         GrPaint paint2;
         GrPaint paint3;
         sk_sp<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect(
-                context->resourceProvider(), dataProxy, GrSwizzle::RGBA(),
-                *pmToUPMRule, SkMatrix::I()));
+                resourceProvider, dataProxy, *pmToUPMRule, SkMatrix::I()));
         sk_sp<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect(
-                context->resourceProvider(), readRTC->asTextureProxyRef(), GrSwizzle::RGBA(),
-                *upmToPMRule, SkMatrix::I()));
+                resourceProvider, readRTC->asTextureProxyRef(), *upmToPMRule, SkMatrix::I()));
         sk_sp<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect(
-                context->resourceProvider(), tempRTC->asTextureProxyRef(), GrSwizzle::RGBA(),
-                *pmToUPMRule, SkMatrix::I()));
+                resourceProvider, tempRTC->asTextureProxyRef(), *pmToUPMRule, SkMatrix::I()));
 
         paint1.addColorFragmentProcessor(std::move(pmToUPM1));
         paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
@@ -295,51 +270,33 @@
         }
     }
     if (failed) {
-        *pmToUPMRule = kNone_PMConversion;
-        *upmToPMRule = kNone_PMConversion;
+        *pmToUPMRule = kPMConversionCnt;
+        *upmToPMRule = kPMConversionCnt;
     }
 }
 
 sk_sp<GrFragmentProcessor> GrConfigConversionEffect::Make(GrTexture* texture,
-                                                          const GrSwizzle& swizzle,
                                                           PMConversion pmConversion,
                                                           const SkMatrix& matrix) {
-    if (swizzle == GrSwizzle::RGBA() && kNone_PMConversion == pmConversion) {
-        // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect
-        // then we may pollute our texture cache with redundant shaders. So in the case that no
-        // conversions were requested we instead return a GrSimpleTextureEffect.
-        return GrSimpleTextureEffect::Make(texture, nullptr, matrix);
-    } else {
-        if (kRGBA_8888_GrPixelConfig != texture->config() &&
-            kBGRA_8888_GrPixelConfig != texture->config() &&
-            kNone_PMConversion != pmConversion) {
-            // The PM conversions assume colors are 0..255
-            return nullptr;
-        }
-        return sk_sp<GrFragmentProcessor>(
-            new GrConfigConversionEffect(texture, swizzle, pmConversion, matrix));
+    if (kRGBA_8888_GrPixelConfig != texture->config() &&
+        kBGRA_8888_GrPixelConfig != texture->config()) {
+        // The PM conversions assume colors are 0..255
+        return nullptr;
     }
+    return sk_sp<GrFragmentProcessor>(
+        new GrConfigConversionEffect(texture, pmConversion, matrix));
 }
 
 sk_sp<GrFragmentProcessor> GrConfigConversionEffect::Make(GrResourceProvider* resourceProvider,
                                                           sk_sp<GrTextureProxy> proxy,
-                                                          const GrSwizzle& swizzle,
                                                           PMConversion pmConversion,
                                                           const SkMatrix& matrix) {
-    if (swizzle == GrSwizzle::RGBA() && kNone_PMConversion == pmConversion) {
-        // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect
-        // then we may pollute our texture cache with redundant shaders. So in the case that no
-        // conversions were requested we instead return a GrSimpleTextureEffect.
-        return GrSimpleTextureEffect::Make(resourceProvider, std::move(proxy), nullptr, matrix);
-    } else {
-        if (kRGBA_8888_GrPixelConfig != proxy->config() &&
-            kBGRA_8888_GrPixelConfig != proxy->config() &&
-            kNone_PMConversion != pmConversion) {
-            // The PM conversions assume colors are 0..255
-            return nullptr;
-        }
-        return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(resourceProvider,
-                                                                       std::move(proxy), swizzle,
-                                                                       pmConversion, matrix));
+    if (kRGBA_8888_GrPixelConfig != proxy->config() &&
+        kBGRA_8888_GrPixelConfig != proxy->config()) {
+        // The PM conversions assume colors are 0..255
+        return nullptr;
     }
+    return sk_sp<GrFragmentProcessor>(new GrConfigConversionEffect(resourceProvider,
+                                                                   std::move(proxy),
+                                                                   pmConversion, matrix));
 }
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index 11fbc55..d71b228 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -9,14 +9,12 @@
 #define GrConfigConversionEffect_DEFINED
 
 #include "GrSingleTextureEffect.h"
-#include "GrSwizzle.h"
 
 class GrInvariantOutput;
 
 /**
  * This class is used to perform config conversions. Clients may want to read/write data that is
- * unpremultiplied. Additionally, the channels may also be swizzled for optimal readback/upload
- * performance.
+ * unpremultiplied.
  */
 class GrConfigConversionEffect : public GrSingleTextureEffect {
 public:
@@ -24,8 +22,7 @@
      * The PM->UPM or UPM->PM conversions to apply.
      */
     enum PMConversion {
-        kNone_PMConversion = 0,
-        kMulByAlpha_RoundUp_PMConversion,
+        kMulByAlpha_RoundUp_PMConversion = 0,
         kMulByAlpha_RoundDown_PMConversion,
         kDivByAlpha_RoundUp_PMConversion,
         kDivByAlpha_RoundDown_PMConversion,
@@ -33,15 +30,13 @@
         kPMConversionCnt
     };
 
-    static sk_sp<GrFragmentProcessor> Make(GrTexture*, const GrSwizzle&, PMConversion,
-                                           const SkMatrix&);
+    static sk_sp<GrFragmentProcessor> Make(GrTexture*, PMConversion, const SkMatrix&);
 
     static sk_sp<GrFragmentProcessor> Make(GrResourceProvider*, sk_sp<GrTextureProxy>,
-                                           const GrSwizzle&, PMConversion, const SkMatrix&);
+                                           PMConversion, const SkMatrix&);
 
     const char* name() const override { return "Config Conversion"; }
 
-    const GrSwizzle& swizzle() const { return fSwizzle; }
     PMConversion  pmConversion() const { return fPMConversion; }
 
     // This function determines whether it is possible to choose PM->UPM and UPM->PM conversions
@@ -53,9 +48,9 @@
                                                PMConversion* PMToUPMRule,
                                                PMConversion* UPMToPMRule);
 private:
-    GrConfigConversionEffect(GrTexture*, const GrSwizzle&, PMConversion, const SkMatrix& matrix);
+    GrConfigConversionEffect(GrTexture*, PMConversion, const SkMatrix& matrix);
 
-    GrConfigConversionEffect(GrResourceProvider*, sk_sp<GrTextureProxy>, const GrSwizzle&,
+    GrConfigConversionEffect(GrResourceProvider*, sk_sp<GrTextureProxy>,
                              PMConversion, const SkMatrix& matrix);
 
     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -64,7 +59,6 @@
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
-    GrSwizzle       fSwizzle;
     PMConversion    fPMConversion;
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;