Remove a usage of GrPixelConfig in SkGpuBlurUtils::GaussianBlur

Bug: skia:6718
Change-Id: Ia8a96cf6907ffaafd989f1e5bb1443d1ef51b9e6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/242142
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/core/SkBlurMF.cpp b/src/core/SkBlurMF.cpp
index 8a6abe7..bcb6f79 100644
--- a/src/core/SkBlurMF.cpp
+++ b/src/core/SkBlurMF.cpp
@@ -881,14 +881,15 @@
     bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle);
     auto renderTargetContext = SkGpuBlurUtils::GaussianBlur(context,
                                                             srcProxy,
+                                                            GrColorType::kAlpha_8,
+                                                            kPremul_SkAlphaType,
                                                             SkIPoint::Make(0, 0),
                                                             nullptr,
                                                             clipRect,
                                                             SkIRect::EmptyIRect(),
                                                             xformedSigma,
                                                             xformedSigma,
-                                                            GrTextureDomain::kIgnore_Mode,
-                                                            kPremul_SkAlphaType);
+                                                            GrTextureDomain::kIgnore_Mode);
     if (!renderTargetContext) {
         return nullptr;
     }
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index 038ab9c..d80647a 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -92,21 +92,9 @@
                                                  SkRect::Make(dstRect), localMatrix);
 }
 
-static GrColorType get_blur_color_type(GrTextureProxy* proxy) {
-    GrPixelConfig config = proxy->config();
-
-    SkASSERT(kBGRA_8888_GrPixelConfig == config || kRGBA_8888_GrPixelConfig == config ||
-             kRGB_888_GrPixelConfig == config || kRGBA_4444_GrPixelConfig == config ||
-             kRGB_565_GrPixelConfig == config || kSRGBA_8888_GrPixelConfig == config ||
-             kRGBA_half_GrPixelConfig == config || kAlpha_8_GrPixelConfig == config ||
-             kAlpha_8_as_Alpha_GrPixelConfig == config || kAlpha_8_as_Red_GrPixelConfig == config ||
-             kRGBA_1010102_GrPixelConfig == config || kRGBA_half_Clamped_GrPixelConfig == config);
-
-    return GrPixelConfigToColorType(config);
-}
-
 static std::unique_ptr<GrRenderTargetContext> convolve_gaussian_2d(GrRecordingContext* context,
-                                                                   sk_sp<GrTextureProxy> proxy,
+                                                                   sk_sp<GrTextureProxy> srcProxy,
+                                                                   GrColorType srcColorType,
                                                                    const SkIRect& srcBounds,
                                                                    const SkIPoint& srcOffset,
                                                                    int radiusX,
@@ -118,21 +106,19 @@
                                                                    int finalH,
                                                                    sk_sp<SkColorSpace> finalCS,
                                                                    SkBackingFit dstFit) {
-    // TODO: Once GrPixelConfig is gone, we need will need the source's color type.
-    GrColorType colorType = get_blur_color_type(proxy.get());
 
     auto renderTargetContext = context->priv().makeDeferredRenderTargetContext(
             dstFit,
             finalW,
             finalH,
-            colorType,
+            srcColorType,
             std::move(finalCS),
             1,
             GrMipMapped::kNo,
-            proxy->origin(),
+            srcProxy->origin(),
             nullptr,
             SkBudgeted::kYes,
-            proxy->isProtected() ? GrProtected::kYes : GrProtected::kNo);
+            srcProxy->isProtected() ? GrProtected::kYes : GrProtected::kNo);
     if (!renderTargetContext) {
         return nullptr;
     }
@@ -142,8 +128,9 @@
     SkISize size = SkISize::Make(2 * radiusX + 1,  2 * radiusY + 1);
     SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
     GrPaint paint;
-    auto conv = GrMatrixConvolutionEffect::MakeGaussian(std::move(proxy), srcBounds, size, 1.0, 0.0,
-                                                        kernelOffset, mode, true, sigmaX, sigmaY);
+    auto conv = GrMatrixConvolutionEffect::MakeGaussian(std::move(srcProxy), srcBounds, size,
+                                                        1.0, 0.0, kernelOffset, mode, true,
+                                                        sigmaX, sigmaY);
     paint.addColorFragmentProcessor(std::move(conv));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     GrFixedClip clip(SkIRect::MakeWH(finalW, finalH));
@@ -162,7 +149,8 @@
 // geometry they submit or before calling convolve_gaussian_1d.
 
 static std::unique_ptr<GrRenderTargetContext> convolve_gaussian(GrRecordingContext* context,
-                                                                sk_sp<GrTextureProxy> proxy,
+                                                                sk_sp<GrTextureProxy> srcProxy,
+                                                                GrColorType srcColorType,
                                                                 const SkIPoint& proxyOffset,
                                                                 const SkIRect& srcRect,
                                                                 const SkIPoint& srcOffset,
@@ -177,21 +165,18 @@
                                                                 SkBackingFit fit) {
     SkASSERT(srcRect.width() <= finalW && srcRect.height() <= finalH);
 
-    // TODO: Once GrPixelConfig is gone we'll need the source's color type here.
-    GrColorType colorType = get_blur_color_type(proxy.get());
-
     auto dstRenderTargetContext = context->priv().makeDeferredRenderTargetContext(
             fit,
             srcRect.width(),
             srcRect.height(),
-            colorType,
+            srcColorType,
             std::move(finalCS),
             1,
             GrMipMapped::kNo,
-            proxy->origin(),
+            srcProxy->origin(),
             nullptr,
             SkBudgeted::kYes,
-            proxy->isProtected() ? GrProtected::kYes : GrProtected::kNo);
+            srcProxy->isProtected() ? GrProtected::kYes : GrProtected::kNo);
     if (!dstRenderTargetContext) {
         return nullptr;
     }
@@ -204,7 +189,7 @@
     if (GrTextureDomain::kIgnore_Mode == mode) {
         *contentRect = dstRect;
         convolve_gaussian_1d(dstRenderTargetContext.get(), clip, dstRect, netOffset,
-                             std::move(proxy), direction, radius, sigma,
+                             std::move(srcProxy), direction, radius, sigma,
                              GrTextureDomain::kIgnore_Mode, bounds);
         return dstRenderTargetContext;
     }
@@ -259,15 +244,15 @@
     if (midRect.isEmpty()) {
         // Blur radius covers srcBounds; use bounds over entire draw
         convolve_gaussian_1d(dstRenderTargetContext.get(), clip, dstRect, netOffset,
-                             std::move(proxy), direction, radius, sigma, mode, bounds);
+                             std::move(srcProxy), direction, radius, sigma, mode, bounds);
     } else {
         // Draw right and left margins with bounds; middle without.
         convolve_gaussian_1d(dstRenderTargetContext.get(), clip, leftRect, netOffset,
-                             proxy, direction, radius, sigma, mode, bounds);
+                             srcProxy, direction, radius, sigma, mode, bounds);
         convolve_gaussian_1d(dstRenderTargetContext.get(), clip, rightRect, netOffset,
-                             proxy, direction, radius, sigma, mode, bounds);
+                             srcProxy, direction, radius, sigma, mode, bounds);
         convolve_gaussian_1d(dstRenderTargetContext.get(), clip, midRect, netOffset,
-                             std::move(proxy), direction, radius, sigma,
+                             std::move(srcProxy), direction, radius, sigma,
                              GrTextureDomain::kIgnore_Mode, bounds);
     }
 
@@ -276,7 +261,8 @@
 
 // Note: despite its name this function does not kill every tenth legionnaire.
 static sk_sp<GrTextureProxy> decimate(GrRecordingContext* context,
-                                      sk_sp<GrTextureProxy> src,
+                                      sk_sp<GrTextureProxy> srcProxy,
+                                      GrColorType srcColorType,
                                       const SkIPoint& proxyOffset,
                                       SkIPoint* srcOffset,
                                       SkIRect* contentRect,
@@ -290,9 +276,6 @@
     SkASSERT(SkIsPow2(scaleFactorX) && SkIsPow2(scaleFactorY));
     SkASSERT(scaleFactorX > 1 || scaleFactorY > 1);
 
-    // TODO: Once GrPixelConfig is gone we'll need the source's color type here.
-    GrColorType colorType = get_blur_color_type(src.get());
-
     SkIRect srcRect;
     if (GrTextureDomain::kIgnore_Mode == mode) {
         srcRect = SkIRect::MakeWH(finalW, finalH);
@@ -319,14 +302,14 @@
                 SkBackingFit::kApprox,
                 dstRect.fRight,
                 dstRect.fBottom,
-                colorType,
+                srcColorType,
                 finalCS,
                 1,
                 GrMipMapped::kNo,
-                src->origin(),
+                srcProxy->origin(),
                 nullptr,
                 SkBudgeted::kYes,
-                src->isProtected() ? GrProtected::kYes : GrProtected::kNo);
+                srcProxy->isProtected() ? GrProtected::kYes : GrProtected::kNo);
         if (!dstRenderTargetContext) {
             return nullptr;
         }
@@ -349,7 +332,7 @@
                 domain.fTop = domain.fBottom = SkScalarAve(domain.fTop, domain.fBottom);
             }
             domain.offset(proxyOffset.x(), proxyOffset.y());
-            auto fp = GrTextureDomainEffect::Make(std::move(src),
+            auto fp = GrTextureDomainEffect::Make(std::move(srcProxy),
                                                   SkMatrix::I(),
                                                   domain,
                                                   modeForScaling,
@@ -360,7 +343,7 @@
             // back in GaussianBlur
             srcOffset->set(0, 0);
         } else {
-            paint.addColorTextureProcessor(std::move(src), SkMatrix::I(),
+            paint.addColorTextureProcessor(std::move(srcProxy), SkMatrix::I(),
                                            GrSamplerState::ClampBilerp());
         }
         paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
@@ -369,8 +352,8 @@
                                                SkMatrix::I(), SkRect::Make(dstRect),
                                                SkRect::Make(srcRect));
 
-        src = dstRenderTargetContext->asTextureProxyRef();
-        if (!src) {
+        srcProxy = dstRenderTargetContext->asTextureProxyRef();
+        if (!srcProxy) {
             return nullptr;
         }
         srcRect = dstRect;
@@ -421,13 +404,12 @@
         return nullptr;
     }
 
+    GrColorType srcColorType = srcRenderTargetContext->colorSpaceInfo().colorType();
+
     srcRenderTargetContext = nullptr; // no longer needed
 
-    // TODO: Once GrPixelConfig is gone we'll need the source's color type here.
-    GrColorType colorType = get_blur_color_type(srcProxy.get());
-
     auto dstRenderTargetContext = context->priv().makeDeferredRenderTargetContext(
-            fit, finalW, finalH, colorType, std::move(finalCS), 1, GrMipMapped::kNo,
+            fit, finalW, finalH, srcColorType, std::move(finalCS), 1, GrMipMapped::kNo,
             srcProxy->origin());
     if (!dstRenderTargetContext) {
         return nullptr;
@@ -457,6 +439,8 @@
 
 std::unique_ptr<GrRenderTargetContext> GaussianBlur(GrRecordingContext* context,
                                                     sk_sp<GrTextureProxy> srcProxy,
+                                                    GrColorType srcColorType,
+                                                    SkAlphaType srcAT,
                                                     const SkIPoint& proxyOffset,
                                                     sk_sp<SkColorSpace> colorSpace,
                                                     const SkIRect& dstBounds,
@@ -464,7 +448,6 @@
                                                     float sigmaX,
                                                     float sigmaY,
                                                     GrTextureDomain::Mode mode,
-                                                    SkAlphaType at,
                                                     SkBackingFit fit) {
     SkASSERT(context);
 
@@ -493,9 +476,9 @@
         // Apply the proxy offset to src bounds and offset directly
         srcOffset -= proxyOffset;
         localSrcBounds.offset(proxyOffset);
-        return convolve_gaussian_2d(context, std::move(srcProxy), localSrcBounds, srcOffset,
-                                    radiusX, radiusY, sigmaX, sigmaY, mode, finalW, finalH,
-                                    colorSpace, fit);
+        return convolve_gaussian_2d(context, std::move(srcProxy), srcColorType, localSrcBounds,
+                                    srcOffset, radiusX, radiusY, sigmaX, sigmaY, mode,
+                                    finalW, finalH, colorSpace, fit);
     }
 
     // Only the last rendered renderTargetContext needs to match the supplied 'fit'
@@ -507,9 +490,10 @@
     }
 
     if (scaleFactorX > 1 || scaleFactorY > 1) {
-        srcProxy = decimate(context, std::move(srcProxy), localProxyOffset, &srcOffset,
-                            &localSrcBounds, scaleFactorX, scaleFactorY, sigmaX > 0.0f,
-                            sigmaY > 0.0f, radiusX, radiusY, mode, finalW, finalH, colorSpace);
+        srcProxy = decimate(context, std::move(srcProxy), srcColorType, localProxyOffset,
+                            &srcOffset, &localSrcBounds, scaleFactorX, scaleFactorY,
+                            sigmaX > 0.0f, sigmaY > 0.0f, radiusX, radiusY, mode,
+                            finalW, finalH, colorSpace);
         localProxyOffset.set(0, 0);
         if (!srcProxy) {
             return nullptr;
@@ -522,8 +506,9 @@
     scale_irect_roundout(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
     if (sigmaX > 0.0f) {
         dstRenderTargetContext = convolve_gaussian(
-                context, std::move(srcProxy), localProxyOffset, srcRect, srcOffset, Direction::kX,
-                radiusX, sigmaX, &localSrcBounds, mode, finalW, finalH, colorSpace, xFit);
+                context, std::move(srcProxy), srcColorType, localProxyOffset, srcRect, srcOffset,
+                Direction::kX, radiusX, sigmaX, &localSrcBounds, mode,
+                finalW, finalH, colorSpace, xFit);
         if (!dstRenderTargetContext) {
             return nullptr;
         }
@@ -548,8 +533,9 @@
 
     if (sigmaY > 0.0f) {
         dstRenderTargetContext = convolve_gaussian(
-                context, std::move(srcProxy), localProxyOffset, srcRect, srcOffset, Direction::kY,
-                radiusY, sigmaY, &localSrcBounds, mode, finalW, finalH, colorSpace, yFit);
+                context, std::move(srcProxy), srcColorType, localProxyOffset, srcRect, srcOffset,
+                Direction::kY, radiusY, sigmaY, &localSrcBounds, mode,
+                finalW, finalH, colorSpace, yFit);
         if (!dstRenderTargetContext) {
             return nullptr;
         }
diff --git a/src/core/SkGpuBlurUtils.h b/src/core/SkGpuBlurUtils.h
index 2184f02..9143518 100644
--- a/src/core/SkGpuBlurUtils.h
+++ b/src/core/SkGpuBlurUtils.h
@@ -20,7 +20,7 @@
 namespace SkGpuBlurUtils {
   /**
     * Applies a 2D Gaussian blur to a given texture. The blurred result is returned
-    * as a renderTargetContext in case the caller wishes to future draw into the result.
+    * as a renderTargetContext in case the caller wishes to draw into the result.
     *
     * The 'proxyOffset' is kept separate form 'srcBounds' because they exist in different
     * coordinate spaces. 'srcBounds' exists in the content space of the special image, and
@@ -28,9 +28,11 @@
     *
     * Note: one of sigmaX and sigmaY should be non-zero!
     * @param context         The GPU context
-    * @param src             The source to be blurred.
-    * @param proxyOffset     The offset from the top-left corner to valid texels in 'src', which
-    *                        should come from the subset of the owning SkSpecialImage.
+    * @param srcProxy        The source to be blurred.
+    * @param srcColorType    The colorType of srcProxy
+    * @param srcAlphaType    The alphaType of srcProxy
+    * @param proxyOffset     The offset from the top-left corner to valid texels in 'srcProxy',
+                             which should come from the subset of the owning SkSpecialImage.
     * @param colorSpace      Color space of the source (used for the renderTargetContext result,
     *                        too).
     * @param dstBounds       The destination bounds, relative to the source texture.
@@ -43,7 +45,9 @@
     * @return                The renderTargetContext containing the blurred result.
     */
 std::unique_ptr<GrRenderTargetContext> GaussianBlur(GrRecordingContext* context,
-                                                    sk_sp<GrTextureProxy> src,
+                                                    sk_sp<GrTextureProxy> srcProxy,
+                                                    GrColorType srcColorType,
+                                                    SkAlphaType srcAlphaType,
                                                     const SkIPoint& proxyOffset,
                                                     sk_sp<SkColorSpace> colorSpace,
                                                     const SkIRect& dstBounds,
@@ -51,7 +55,6 @@
                                                     float sigmaX,
                                                     float sigmaY,
                                                     GrTextureDomain::Mode mode,
-                                                    SkAlphaType at,
                                                     SkBackingFit fit = SkBackingFit::kApprox);
 };
 
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index e5d7f18..0dbceb2 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -463,6 +463,7 @@
     return SkSpecialImage::MakeDeferredFromGpu(
             context, dstIRect, kNeedNewImageUniqueID_SpecialImage,
             renderTargetContext->asTextureProxyRef(),
+            renderTargetContext->colorSpaceInfo().colorType(),
             renderTargetContext->colorSpaceInfo().refColorSpace());
 }
 
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index a957d9f..393ec13 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -124,6 +124,7 @@
                                                rect,
                                                this->uniqueID(),
                                                std::move(proxy),
+                                               SkColorTypeToGrColorType(bmp.colorType()),
                                                sk_ref_sp(this->getColorSpace()),
                                                &this->props(),
                                                this->alphaType());
@@ -211,6 +212,7 @@
         }
 
         return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(proxy),
+                                   SkColorTypeToGrColorType(image->colorType()),
                                    image->refColorSpace(), props);
     } else
 #endif
@@ -237,6 +239,8 @@
 
     SkAlphaType alphaType() const override { return fBitmap.alphaType(); }
 
+    SkColorType colorType() const override { return fBitmap.colorType(); }
+
     size_t getSize() const override { return fBitmap.computeByteSize(); }
 
     void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override {
@@ -374,11 +378,12 @@
 class SkSpecialImage_Gpu : public SkSpecialImage_Base {
 public:
     SkSpecialImage_Gpu(GrRecordingContext* context, const SkIRect& subset,
-                       uint32_t uniqueID, sk_sp<GrTextureProxy> proxy, SkAlphaType at,
-                       sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* props)
+                       uint32_t uniqueID, sk_sp<GrTextureProxy> proxy, GrColorType ct,
+                       SkAlphaType at, sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* props)
         : INHERITED(subset, uniqueID, props)
         , fContext(context)
         , fTextureProxy(std::move(proxy))
+        , fColorType(ct)
         , fAlphaType(at)
         , fColorSpace(std::move(colorSpace))
         , fAddedRasterVersionToCache(false) {
@@ -392,6 +397,8 @@
 
     SkAlphaType alphaType() const override { return fAlphaType; }
 
+    SkColorType colorType() const override { return GrColorTypeToSkColorType(fColorType); }
+
     size_t getSize() const override { return fTextureProxy->gpuMemorySize(); }
 
     void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override {
@@ -472,6 +479,7 @@
                                                    subset,
                                                    this->uniqueID(),
                                                    fTextureProxy,
+                                                   fColorType,
                                                    fColorSpace,
                                                    &this->props(),
                                                    fAlphaType);
@@ -525,6 +533,7 @@
 private:
     GrRecordingContext*       fContext;
     sk_sp<GrTextureProxy>     fTextureProxy;
+    const GrColorType         fColorType;
     const SkAlphaType         fAlphaType;
     sk_sp<SkColorSpace>       fColorSpace;
     mutable std::atomic<bool> fAddedRasterVersionToCache;
@@ -536,6 +545,7 @@
                                                           const SkIRect& subset,
                                                           uint32_t uniqueID,
                                                           sk_sp<GrTextureProxy> proxy,
+                                                          GrColorType colorType,
                                                           sk_sp<SkColorSpace> colorSpace,
                                                           const SkSurfaceProps* props,
                                                           SkAlphaType at) {
@@ -543,7 +553,7 @@
         return nullptr;
     }
     SkASSERT_RELEASE(rect_fits(subset, proxy->width(), proxy->height()));
-    return sk_make_sp<SkSpecialImage_Gpu>(context, subset, uniqueID, std::move(proxy), at,
-                                          std::move(colorSpace), props);
+    return sk_make_sp<SkSpecialImage_Gpu>(context, subset, uniqueID, std::move(proxy), colorType,
+                                          at, std::move(colorSpace), props);
 }
 #endif
diff --git a/src/core/SkSpecialImage.h b/src/core/SkSpecialImage.h
index 753a317..d68b966 100644
--- a/src/core/SkSpecialImage.h
+++ b/src/core/SkSpecialImage.h
@@ -13,6 +13,10 @@
 #include "include/core/SkSurfaceProps.h"
 #include "src/core/SkNextID.h"
 
+#if SK_SUPPORT_GPU
+#include "include/private/GrTypesPriv.h"
+#endif
+
 class GrRecordingContext;
 class GrTextureProxy;
 class SkBitmap;
@@ -53,6 +57,7 @@
 
     uint32_t uniqueID() const { return fUniqueID; }
     virtual SkAlphaType alphaType() const = 0;
+    virtual SkColorType colorType() const = 0;
     virtual size_t getSize() const = 0;
 
     /**
@@ -82,6 +87,7 @@
                                                      const SkIRect& subset,
                                                      uint32_t uniqueID,
                                                      sk_sp<GrTextureProxy>,
+                                                     GrColorType,
                                                      sk_sp<SkColorSpace>,
                                                      const SkSurfaceProps* = nullptr,
                                                      SkAlphaType at = kPremul_SkAlphaType);
diff --git a/src/core/SkSpecialSurface.cpp b/src/core/SkSpecialSurface.cpp
index 2f6076f..2f34fa0 100644
--- a/src/core/SkSpecialSurface.cpp
+++ b/src/core/SkSpecialSurface.cpp
@@ -147,10 +147,12 @@
         if (!fProxy) {
             return nullptr;
         }
+        GrColorType ct = SkColorTypeToGrColorType(fCanvas->imageInfo().colorType());
+
         return SkSpecialImage::MakeDeferredFromGpu(fCanvas->getGrContext(),
                                                    this->subset(),
                                                    kNeedNewImageUniqueID_SpecialImage,
-                                                   std::move(fProxy),
+                                                   std::move(fProxy), ct,
                                                    fCanvas->imageInfo().refColorSpace(),
                                                    &this->props());
     }
diff --git a/src/effects/imagefilters/SkArithmeticImageFilter.cpp b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
index f473294..d08d5b7 100644
--- a/src/effects/imagefilters/SkArithmeticImageFilter.cpp
+++ b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
@@ -427,6 +427,7 @@
             SkIRect::MakeWH(bounds.width(), bounds.height()),
             kNeedNewImageUniqueID_SpecialImage,
             renderTargetContext->asTextureProxyRef(),
+            renderTargetContext->colorSpaceInfo().colorType(),
             renderTargetContext->colorSpaceInfo().refColorSpace());
 }
 #endif
diff --git a/src/effects/imagefilters/SkBlurImageFilter.cpp b/src/effects/imagefilters/SkBlurImageFilter.cpp
index df058c1..ccc91c5 100644
--- a/src/effects/imagefilters/SkBlurImageFilter.cpp
+++ b/src/effects/imagefilters/SkBlurImageFilter.cpp
@@ -652,14 +652,15 @@
     auto renderTargetContext = SkGpuBlurUtils::GaussianBlur(
             context,
             std::move(inputTexture),
+            SkColorTypeToGrColorType(input->colorType()),
+            input->alphaType(),
             input->subset().topLeft(),
             ctx.colorSpace() ? sk_ref_sp(input->getColorSpace()) : nullptr,
             dstBounds,
             inputBounds,
             sigma.x(),
             sigma.y(),
-            to_texture_domain_mode(fTileMode),
-            input->alphaType());
+            to_texture_domain_mode(fTileMode));
     if (!renderTargetContext) {
         return nullptr;
     }
@@ -669,6 +670,7 @@
             SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
             kNeedNewImageUniqueID_SpecialImage,
             renderTargetContext->asTextureProxyRef(),
+            renderTargetContext->colorSpaceInfo().colorType(),
             sk_ref_sp(input->getColorSpace()),
             ctx.surfaceProps());
 }
diff --git a/src/effects/imagefilters/SkDisplacementMapEffect.cpp b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
index cad1cbd..9a6ce26 100644
--- a/src/effects/imagefilters/SkDisplacementMapEffect.cpp
+++ b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
@@ -389,6 +389,7 @@
                 SkIRect::MakeWH(bounds.width(), bounds.height()),
                 kNeedNewImageUniqueID_SpecialImage,
                 renderTargetContext->asTextureProxyRef(),
+                renderTargetContext->colorSpaceInfo().colorType(),
                 renderTargetContext->colorSpaceInfo().refColorSpace());
     }
 #endif
diff --git a/src/effects/imagefilters/SkLightingImageFilter.cpp b/src/effects/imagefilters/SkLightingImageFilter.cpp
index f6db850..8828c10 100644
--- a/src/effects/imagefilters/SkLightingImageFilter.cpp
+++ b/src/effects/imagefilters/SkLightingImageFilter.cpp
@@ -538,6 +538,7 @@
             SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height()),
             kNeedNewImageUniqueID_SpecialImage,
             renderTargetContext->asTextureProxyRef(),
+            renderTargetContext->colorSpaceInfo().colorType(),
             renderTargetContext->colorSpaceInfo().refColorSpace());
 }
 #endif
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index 0009c0a..d934d02 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -613,8 +613,8 @@
     return SkSpecialImage::MakeDeferredFromGpu(context,
                                                SkIRect::MakeWH(rect.width(), rect.height()),
                                                kNeedNewImageUniqueID_SpecialImage,
-                                               std::move(srcTexture), std::move(colorSpace),
-                                               &input->props());
+                                               std::move(srcTexture), colorType,
+                                               std::move(colorSpace), &input->props());
 }
 #endif
 
diff --git a/src/effects/imagefilters/SkXfermodeImageFilter.cpp b/src/effects/imagefilters/SkXfermodeImageFilter.cpp
index 24ecf58..13ec99a 100644
--- a/src/effects/imagefilters/SkXfermodeImageFilter.cpp
+++ b/src/effects/imagefilters/SkXfermodeImageFilter.cpp
@@ -322,6 +322,7 @@
             SkIRect::MakeWH(bounds.width(), bounds.height()),
             kNeedNewImageUniqueID_SpecialImage,
             renderTargetContext->asTextureProxyRef(),
+            renderTargetContext->colorSpaceInfo().colorType(),
             renderTargetContext->colorSpaceInfo().refColorSpace());
 }
 
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b77fe5b..0ef9383 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1204,6 +1204,7 @@
                                                rect,
                                                bitmap.getGenerationID(),
                                                std::move(proxy),
+                                               SkColorTypeToGrColorType(bitmap.colorType()),
                                                bitmap.refColorSpace(),
                                                &this->surfaceProps());
 }
@@ -1217,6 +1218,7 @@
                                                    SkIRect::MakeWH(image->width(), image->height()),
                                                    image->uniqueID(),
                                                    std::move(proxy),
+                                                   SkColorTypeToGrColorType(image->colorType()),
                                                    image->refColorSpace(),
                                                    &this->surfaceProps());
     } else if (image->peekPixels(&pm)) {
@@ -1262,10 +1264,13 @@
         finalSubset = SkIRect::MakeSize(proxy->isize());
     }
 
+    GrColorType ct = SkColorTypeToGrColorType(this->imageInfo().colorType());
+
     return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
                                                finalSubset,
                                                kNeedNewImageUniqueID_SpecialImage,
                                                std::move(proxy),
+                                               ct,
                                                this->imageInfo().refColorSpace(),
                                                &this->surfaceProps());
 }
diff --git a/src/gpu/effects/GrRRectBlurEffect.fp b/src/gpu/effects/GrRRectBlurEffect.fp
index 6a39777..74ad750 100644
--- a/src/gpu/effects/GrRRectBlurEffect.fp
+++ b/src/gpu/effects/GrRRectBlurEffect.fp
@@ -76,6 +76,8 @@
             auto rtc2 =
                       SkGpuBlurUtils::GaussianBlur(context,
                                                    std::move(srcProxy),
+                                                   GrColorType::kAlpha_8,
+                                                   kPremul_SkAlphaType,
                                                    SkIPoint::Make(0, 0),
                                                    nullptr,
                                                    SkIRect::MakeWH(size.fWidth, size.fHeight),
@@ -83,7 +85,6 @@
                                                    xformedSigma,
                                                    xformedSigma,
                                                    GrTextureDomain::kIgnore_Mode,
-                                                   kPremul_SkAlphaType,
                                                    SkBackingFit::kExact);
             if (!rtc2) {
                 return nullptr;
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.h b/src/gpu/effects/generated/GrRRectBlurEffect.h
index aaff4d3..8b48489 100644
--- a/src/gpu/effects/generated/GrRRectBlurEffect.h
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.h
@@ -75,6 +75,8 @@
             }
             auto rtc2 = SkGpuBlurUtils::GaussianBlur(context,
                                                      std::move(srcProxy),
+                                                     GrColorType::kAlpha_8,
+                                                     kPremul_SkAlphaType,
                                                      SkIPoint::Make(0, 0),
                                                      nullptr,
                                                      SkIRect::MakeWH(size.fWidth, size.fHeight),
@@ -82,7 +84,6 @@
                                                      xformedSigma,
                                                      xformedSigma,
                                                      GrTextureDomain::kIgnore_Mode,
-                                                     kPremul_SkAlphaType,
                                                      SkBackingFit::kExact);
             if (!rtc2) {
                 return nullptr;