Reland "Have a GrBackendFormat be stored on gpu proxies."

This reverts commit 919c9e77c3492af766ff5982acda76ee49da3168.

Reason for revert: Flutter change has landed and fixed memory issue.

Original change's description:
> Revert "Have a GrBackendFormat be stored on gpu proxies."
>
> This reverts commit 51b1c12bbc2fa3f8d4faa29ad19c6f3cb34837ce.
>
> Reason for revert: reverting till flutter gets to 1.1 to fix build issues.
>
> Original change's description:
> > Have a GrBackendFormat be stored on gpu proxies.
> >
> > Bug: skia:
> > Change-Id: Iaf1fb24ab29a61d44e5fa59a5e0867ed02dcda90
> > Reviewed-on: https://skia-review.googlesource.com/c/168021
> > Reviewed-by: Brian Osman <brianosman@google.com>
> > Commit-Queue: Greg Daniel <egdaniel@google.com>
>
> TBR=egdaniel@google.com,bsalomon@google.com,brianosman@google.com
>
> Change-Id: I574fdc084ef5994596c51fb0d60423b5dc01b885
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: chromium:903701 chromium:903756
> Reviewed-on: https://skia-review.googlesource.com/c/169835
> Commit-Queue: Greg Daniel <egdaniel@google.com>
> Reviewed-by: Greg Daniel <egdaniel@google.com>

TBR=egdaniel@google.com,bsalomon@google.com,brianosman@google.com

Change-Id: Ifd9b6b8e194af9fb9258fa626644e76e6ecf090d
Bug: chromium:903701 chromium:903756
Reviewed-on: https://skia-review.googlesource.com/c/170104
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/bench/VertexColorSpaceBench.cpp b/bench/VertexColorSpaceBench.cpp
index b8f5472..129d0ff 100644
--- a/bench/VertexColorSpaceBench.cpp
+++ b/bench/VertexColorSpaceBench.cpp
@@ -265,10 +265,12 @@
         SkRandom r;
         const int kDrawsPerLoop = 32;
 
+        const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
         for (int i = 0; i < loops; ++i) {
             sk_sp<GrRenderTargetContext> rtc(
-                    context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kApprox,
-                    100, 100, kRGBA_8888_GrPixelConfig, p3));
+                    context->contextPriv().makeDeferredRenderTargetContext(
+                            format, SkBackingFit::kApprox, 100, 100, kRGBA_8888_GrPixelConfig, p3));
             SkASSERT(rtc);
 
             for (int j = 0; j < kDrawsPerLoop; ++j) {
diff --git a/gm/clockwise.cpp b/gm/clockwise.cpp
index 40b2abc..354541d 100644
--- a/gm/clockwise.cpp
+++ b/gm/clockwise.cpp
@@ -155,9 +155,9 @@
 
     // Draw the test to an off-screen, top-down render target.
     if (auto topLeftRTC = ctx->contextPriv().makeDeferredRenderTargetContext(
-                    SkBackingFit::kExact, 100, 200, rtc->asSurfaceProxy()->config(),
-                    nullptr, 1, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin, nullptr,
-                    SkBudgeted::kYes)) {
+            rtc->asSurfaceProxy()->backendFormat(), SkBackingFit::kExact, 100, 200,
+            rtc->asSurfaceProxy()->config(), nullptr, 1, GrMipMapped::kNo,
+            kTopLeft_GrSurfaceOrigin, nullptr, SkBudgeted::kYes)) {
         topLeftRTC->clear(nullptr, SK_PMColor4fTRANSPARENT,
                           GrRenderTargetContext::CanClearFullscreen::kYes);
         topLeftRTC->priv().testingOnly_addDrawOp(ClockwiseTestOp::Make(ctx, false, 0));
@@ -171,9 +171,9 @@
 
     // Draw the test to an off-screen, bottom-up render target.
     if (auto topLeftRTC = ctx->contextPriv().makeDeferredRenderTargetContext(
-                    SkBackingFit::kExact, 100, 200, rtc->asSurfaceProxy()->config(),
-                    nullptr, 1, GrMipMapped::kNo, kBottomLeft_GrSurfaceOrigin, nullptr,
-                    SkBudgeted::kYes)) {
+            rtc->asSurfaceProxy()->backendFormat(), SkBackingFit::kExact, 100, 200,
+            rtc->asSurfaceProxy()->config(), nullptr, 1, GrMipMapped::kNo,
+            kBottomLeft_GrSurfaceOrigin, nullptr, SkBudgeted::kYes)) {
         topLeftRTC->clear(nullptr, SK_PMColor4fTRANSPARENT,
                           GrRenderTargetContext::CanClearFullscreen::kYes);
         topLeftRTC->priv().testingOnly_addDrawOp(ClockwiseTestOp::Make(ctx, false, 0));
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index 7081f19..1a20be0 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -184,7 +184,8 @@
         GrMipMapped mipMapped = willBeMipped ? GrMipMapped::kYes : GrMipMapped::kNo;
 
         sk_sp<GrSurfaceContext> dstContext(fCtx->contextPriv().makeDeferredSurfaceContext(
-                desc, fProxy->origin(), mipMapped, SkBackingFit::kExact, SkBudgeted::kYes));
+                fProxy->backendFormat(), desc, fProxy->origin(), mipMapped, SkBackingFit::kExact,
+                SkBudgeted::kYes));
         if (!dstContext) {
             return nullptr;
         }
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index f327272..1abdf08 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -196,9 +196,11 @@
                                                 const GrReducedClip& reducedClip, GrPaint&& paint) {
     const int padRight = (kDeviceRect.right() - kCoverRect.right()) / 2;
     const int padBottom = (kDeviceRect.bottom() - kCoverRect.bottom()) / 2;
+    const GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
     sk_sp<GrRenderTargetContext> maskRTC(
         ctx->contextPriv().makeDeferredRenderTargetContextWithFallback(
-                                                         SkBackingFit::kExact,
+                                                         format, SkBackingFit::kExact,
                                                          kCoverRect.width() + padRight,
                                                          kCoverRect.height() + padBottom,
                                                          kAlpha_8_GrPixelConfig, nullptr));
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index 3f40ce2..1de6fb0 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -61,7 +61,8 @@
         return GrBackendFormat(config);
     }
 
-    GrBackendApi backend() const {return fBackend; }
+    GrBackendApi backend() const { return fBackend; }
+    GrTextureType textureType() const { return fTextureType; }
 
     // If the backend API is GL, these return a pointer to the format and target. Otherwise
     // it returns nullptr.
@@ -82,6 +83,9 @@
     // it returns nullptr.
     const GrPixelConfig* getMockFormat() const;
 
+    // If possible, copies the GrBackendFormat and forces the texture type to be Texture2D
+    GrBackendFormat makeTexture2D() const;
+
     // Returns true if the backend format has been initialized.
     bool isValid() const { return fValid; }
 
@@ -100,16 +104,14 @@
     bool      fValid;
 
     union {
-        struct {
-            GrGLenum fTarget; // GL_TEXTURE_2D, GL_TEXTURE_EXTERNAL or GL_TEXTURE_RECTANGLE
-            GrGLenum fFormat; // the sized, internal format of the GL resource
-        } fGL;
+        GrGLenum         fGLFormat; // the sized, internal format of the GL resource
         VkFormat         fVkFormat;
 #ifdef SK_METAL
         GrMTLPixelFormat fMtlFormat;
 #endif
         GrPixelConfig    fMockFormat;
     };
+    GrTextureType fTextureType;
 };
 
 class SK_API GrBackendTexture {
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index a93cacf..bcd854f 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -9,6 +9,7 @@
 #define GrSurface_DEFINED
 
 #include "GrTypes.h"
+#include "GrBackendSurface.h"
 #include "GrGpuResource.h"
 #include "SkImageInfo.h"
 #include "SkRect.h"
@@ -42,6 +43,8 @@
      */
     GrPixelConfig config() const { return fConfig; }
 
+    virtual GrBackendFormat backendFormat() const = 0;
+
     /**
      * @return the texture associated with the surface, may be null.
      */
@@ -103,7 +106,6 @@
 
     ~GrSurface() override {}
 
-
     void onRelease() override;
     void onAbandon() override;
 
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
index d74be14..1f5b79f 100644
--- a/include/private/GrRenderTargetProxy.h
+++ b/include/private/GrRenderTargetProxy.h
@@ -66,8 +66,8 @@
     friend class GrRenderTargetProxyPriv;
 
     // Deferred version
-    GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit,
-                        SkBudgeted, GrInternalSurfaceFlags);
+    GrRenderTargetProxy(const GrCaps&, const GrBackendFormat&, const GrSurfaceDesc&,
+                        GrSurfaceOrigin, SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
     // Lazy-callback version
     // There are two main use cases for lazily-instantiated proxies:
@@ -80,8 +80,8 @@
     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
     // know the final size until flush time.
     GrRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType lazyType,
-                        const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit, SkBudgeted,
-                        GrInternalSurfaceFlags);
+                        const GrBackendFormat&, const GrSurfaceDesc&, GrSurfaceOrigin,
+                        SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
     // Wrapped version
     GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 980f983..887400a 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -9,12 +9,12 @@
 #define GrSurfaceProxy_DEFINED
 
 #include "../private/SkNoncopyable.h"
+#include "GrBackendSurface.h"
 #include "GrGpuResource.h"
 #include "GrSurface.h"
 
 #include "SkRect.h"
 
-class GrBackendTexture;
 class GrCaps;
 class GrOpList;
 class GrProxyProvider;
@@ -265,6 +265,10 @@
         return fOrigin;
     }
 
+    const GrBackendFormat& backendFormat() const { return fFormat; }
+
+    GrTextureType textureType() const { return fFormat.textureType(); }
+
     class UniqueID {
     public:
         static UniqueID InvalidID() {
@@ -413,9 +417,10 @@
 
 protected:
     // Deferred version
-    GrSurfaceProxy(const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
+    GrSurfaceProxy(const GrBackendFormat& format, const GrSurfaceDesc& desc,
+                   GrSurfaceOrigin origin, SkBackingFit fit,
                    SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
-            : GrSurfaceProxy(nullptr, LazyInstantiationType::kSingleUse, desc, origin, fit,
+            : GrSurfaceProxy(nullptr, LazyInstantiationType::kSingleUse, format, desc, origin, fit,
                              budgeted, surfaceFlags) {
         // Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources
     }
@@ -424,8 +429,8 @@
 
     // Lazy-callback version
     GrSurfaceProxy(LazyInstantiateCallback&&, LazyInstantiationType,
-                   const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit,
-                   SkBudgeted, GrInternalSurfaceFlags);
+                   const GrBackendFormat& format, const GrSurfaceDesc&, GrSurfaceOrigin,
+                   SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
     // Wrapped version
     GrSurfaceProxy(sk_sp<GrSurface>, GrSurfaceOrigin, SkBackingFit);
@@ -467,8 +472,9 @@
     GrInternalSurfaceFlags fSurfaceFlags;
 
 private:
-    // For wrapped resources, 'fConfig', 'fWidth', 'fHeight', and 'fOrigin; will always be filled in
-    // from the wrapped resource.
+    // For wrapped resources, 'fFormat', 'fConfig', 'fWidth', 'fHeight', and 'fOrigin; will always
+    // be filled in from the wrapped resource.
+    GrBackendFormat        fFormat;
     GrPixelConfig          fConfig;
     int                    fWidth;
     int                    fHeight;
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
index 124c5f9..cdfd07a 100644
--- a/include/private/GrTextureProxy.h
+++ b/include/private/GrTextureProxy.h
@@ -40,9 +40,10 @@
     // been instantiated or not.
     GrMipMapped proxyMipMapped() const { return fMipMapped; }
 
-    GrTextureType textureType() const { return fTextureType; }
     /** If true then the texture does not support MIP maps and only supports clamp wrap mode. */
-    bool hasRestrictedSampling() const { return GrTextureTypeHasRestrictedSampling(fTextureType); }
+    bool hasRestrictedSampling() const {
+        return GrTextureTypeHasRestrictedSampling(this->textureType());
+    }
     /**
      * Return the texture proxy's unique key. It will be invalid if the proxy doesn't have one.
      */
@@ -79,12 +80,12 @@
     friend class GrTextureProxyPriv;
 
     // Deferred version - when constructed with data the origin is always kTopLeft.
-    GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped, GrTextureType, SkBackingFit,
+    GrTextureProxy(const GrBackendFormat&, const GrSurfaceDesc& srcDesc, GrMipMapped, SkBackingFit,
                    SkBudgeted, const void* srcData, size_t srcRowBytes, GrInternalSurfaceFlags);
 
     // Deferred version - no data.
-    GrTextureProxy(const GrSurfaceDesc& srcDesc, GrSurfaceOrigin, GrMipMapped, GrTextureType,
-                   SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
+    GrTextureProxy(const GrBackendFormat&, const GrSurfaceDesc& srcDesc, GrSurfaceOrigin,
+                   GrMipMapped, SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
     // Lazy-callback version
     // There are two main use cases for lazily-instantiated proxies:
@@ -96,9 +97,9 @@
     //
     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
     // know the final size until flush time.
-    GrTextureProxy(LazyInstantiateCallback&&, LazyInstantiationType, const GrSurfaceDesc& desc,
-                   GrSurfaceOrigin, GrMipMapped, GrTextureType, SkBackingFit, SkBudgeted,
-                   GrInternalSurfaceFlags);
+    GrTextureProxy(LazyInstantiateCallback&&, LazyInstantiationType, const GrBackendFormat&,
+                   const GrSurfaceDesc& desc, GrSurfaceOrigin, GrMipMapped, SkBackingFit,
+                   SkBudgeted, GrInternalSurfaceFlags);
 
     // Wrapped version
     GrTextureProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
@@ -117,7 +118,6 @@
     // address of other types, leading to this problem.
 
     GrMipMapped      fMipMapped;
-    GrTextureType    fTextureType;
 
     GrUniqueKey      fUniqueKey;
     GrProxyProvider* fProxyProvider; // only set when fUniqueKey is valid
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index f234951..426962a 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -182,8 +182,11 @@
 
         GrOpMemoryPool* pool = ctx->contextPriv().opMemoryPool();
 
+        const GrBackendFormat format =
+                ctx->contextPriv().caps()->getBackendFormatFromGrColorType(GrColorType::kAlpha_F16,
+                                                                           GrSRGBEncoded::kNo);
         sk_sp<GrRenderTargetContext> ccbuff =
-                ctx->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kApprox,
+                ctx->contextPriv().makeDeferredRenderTargetContext(format, SkBackingFit::kApprox,
                                                                    this->width(), this->height(),
                                                                    kAlpha_half_GrPixelConfig,
                                                                    nullptr);
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index 9d5f17a..6cb7126 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -145,6 +145,9 @@
         optionalTextureInfo = &kTextureInfo;
     }
 
+    const GrBackendFormat format = fContext->contextPriv().caps()->getBackendFormatFromColorType(
+            fCharacterization.colorType());
+
     sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
             [lazyProxyData](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
@@ -156,6 +159,7 @@
                 SkASSERT(lazyProxyData->fReplayDest->peekSurface());
                 return sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->peekSurface());
             },
+            format,
             desc,
             fCharacterization.origin(),
             surfaceFlags,
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index f9aee1c..54f1bc7 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -117,8 +117,14 @@
 
     GrPixelConfig config = get_blur_config(proxy.get());
 
+    GrBackendFormat format = proxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrRenderTargetContext> renderTargetContext;
     renderTargetContext = context->contextPriv().makeDeferredRenderTargetContext(
+                                                         format,
                                                          dstFit, dstII.width(), dstII.height(),
                                                          config, dstII.refColorSpace(),
                                                          1, GrMipMapped::kNo,
@@ -159,8 +165,14 @@
 
     GrPixelConfig config = get_blur_config(proxy.get());
 
+    GrBackendFormat format = proxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrRenderTargetContext> dstRenderTargetContext;
     dstRenderTargetContext = context->contextPriv().makeDeferredRenderTargetContext(
+                                                                format,
                                                                 fit, srcRect.width(),
                                                                 srcRect.height(),
                                                                 config,
@@ -276,11 +288,17 @@
 
     sk_sp<GrRenderTargetContext> dstRenderTargetContext;
 
+    GrBackendFormat format = src->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
         shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY);
 
         // We know this will not be the final draw so we are free to make it an approx match.
         dstRenderTargetContext = context->contextPriv().makeDeferredRenderTargetContext(
+                                                    format,
                                                     SkBackingFit::kApprox,
                                                     dstRect.fRight,
                                                     dstRect.fBottom,
@@ -382,8 +400,14 @@
 
     GrPixelConfig config = get_blur_config(srcProxy.get());
 
+    GrBackendFormat format = srcProxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrRenderTargetContext> dstRenderTargetContext =
-        context->contextPriv().makeDeferredRenderTargetContext(fit, dstII.width(), dstII.height(),
+        context->contextPriv().makeDeferredRenderTargetContext(format,
+                                                               fit, dstII.width(), dstII.height(),
                                                                config, dstII.refColorSpace(),
                                                                1, GrMipMapped::kNo,
                                                                srcProxy->origin());
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index b6ed9b3..710e1ff 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -248,9 +248,12 @@
 
     sk_sp<SkColorSpace> colorSpace = sk_ref_sp(outputProperties.colorSpace());
     GrPixelConfig config = SkColorType2GrPixelConfig(outputProperties.colorType());
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(
+                    outputProperties.colorType());
     sk_sp<GrRenderTargetContext> renderTargetContext(
         context->contextPriv().makeDeferredRenderTargetContext(
-                                SkBackingFit::kApprox, bounds.width(), bounds.height(),
+                                format, SkBackingFit::kApprox, bounds.width(), bounds.height(),
                                 config, std::move(colorSpace)));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 4309b80..a1db765 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -436,8 +436,11 @@
             return nullptr;
         }
 
+        GrBackendFormat format =
+            fContext->contextPriv().caps()->getBackendFormatFromColorType(outProps.colorType());
+
         return SkSpecialSurface::MakeRenderTarget(
-            fContext, size.width(), size.height(),
+            fContext, format, size.width(), size.height(),
             SkColorType2GrPixelConfig(outProps.colorType()), sk_ref_sp(outProps.colorSpace()),
             props);
     }
diff --git a/src/core/SkSpecialSurface.cpp b/src/core/SkSpecialSurface.cpp
index a45b40b..a1d76f1 100644
--- a/src/core/SkSpecialSurface.cpp
+++ b/src/core/SkSpecialSurface.cpp
@@ -117,6 +117,7 @@
 
 #if SK_SUPPORT_GPU
 ///////////////////////////////////////////////////////////////////////////////
+#include "GrBackendSurface.h"
 #include "GrContext.h"
 #include "SkGpuDevice.h"
 
@@ -164,6 +165,7 @@
 };
 
 sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrContext* context,
+                                                           const GrBackendFormat& format,
                                                            int width, int height,
                                                            GrPixelConfig config,
                                                            sk_sp<SkColorSpace> colorSpace,
@@ -174,7 +176,7 @@
 
     sk_sp<GrRenderTargetContext> renderTargetContext(
         context->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kApprox, width, height, config, std::move(colorSpace), 1,
+                format, SkBackingFit::kApprox, width, height, config, std::move(colorSpace), 1,
                 GrMipMapped::kNo, kBottomLeft_GrSurfaceOrigin, props));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/core/SkSpecialSurface.h b/src/core/SkSpecialSurface.h
index b04b28d..1b7aada 100644
--- a/src/core/SkSpecialSurface.h
+++ b/src/core/SkSpecialSurface.h
@@ -16,6 +16,7 @@
 #include "GrTypesPriv.h"
 #endif
 
+class GrBackendFormat;
 class GrContext;
 class SkBitmap;
 class SkCanvas;
@@ -60,6 +61,7 @@
      *  be created, nullptr will be returned.
      */
     static sk_sp<SkSpecialSurface> MakeRenderTarget(GrContext*,
+                                                    const GrBackendFormat& format,
                                                     int width, int height,
                                                     GrPixelConfig config,
                                                     sk_sp<SkColorSpace> colorSpace,
diff --git a/src/effects/imagefilters/SkAlphaThresholdFilter.cpp b/src/effects/imagefilters/SkAlphaThresholdFilter.cpp
index 8cc485f..29d5cc5 100644
--- a/src/effects/imagefilters/SkAlphaThresholdFilter.cpp
+++ b/src/effects/imagefilters/SkAlphaThresholdFilter.cpp
@@ -105,10 +105,11 @@
 sk_sp<GrTextureProxy> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* context,
                                                                     const SkMatrix& inMatrix,
                                                                     const SkIRect& bounds) const {
-
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
     sk_sp<GrRenderTargetContext> rtContext(
         context->contextPriv().makeDeferredRenderTargetContextWithFallback(
-            SkBackingFit::kApprox, bounds.width(), bounds.height(), kAlpha_8_GrPixelConfig,
+            format, SkBackingFit::kApprox, bounds.width(), bounds.height(), kAlpha_8_GrPixelConfig,
             nullptr));
     if (!rtContext) {
         return nullptr;
diff --git a/src/effects/imagefilters/SkArithmeticImageFilter.cpp b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
index 14fd17d..88a7c80 100644
--- a/src/effects/imagefilters/SkArithmeticImageFilter.cpp
+++ b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
@@ -356,10 +356,14 @@
 
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
+    SkColorType colorType = outputProperties.colorType();
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(colorType);
+
     sk_sp<GrRenderTargetContext> renderTargetContext(
         context->contextPriv().makeDeferredRenderTargetContext(
-            SkBackingFit::kApprox, bounds.width(), bounds.height(),
-            SkColorType2GrPixelConfig(outputProperties.colorType()),
+            format, SkBackingFit::kApprox, bounds.width(), bounds.height(),
+            SkColorType2GrPixelConfig(colorType),
             sk_ref_sp(outputProperties.colorSpace())));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/effects/imagefilters/SkDisplacementMapEffect.cpp b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
index c5403cb..0427cff 100644
--- a/src/effects/imagefilters/SkDisplacementMapEffect.cpp
+++ b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
@@ -300,12 +300,15 @@
         paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
         SkMatrix matrix;
         matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
-        GrPixelConfig config = SkColorType2GrPixelConfig(ctx.outputProperties().colorType());
+        SkColorType colorType = ctx.outputProperties().colorType();
+        GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
+        GrBackendFormat format =
+                context->contextPriv().caps()->getBackendFormatFromColorType(colorType);
 
         sk_sp<GrRenderTargetContext> renderTargetContext(
-            context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kApprox,
-                                                     bounds.width(), bounds.height(),
-                                                     config, sk_ref_sp(colorSpace)));
+            context->contextPriv().makeDeferredRenderTargetContext(
+                    format, SkBackingFit::kApprox, bounds.width(), bounds.height(), config,
+                    sk_ref_sp(colorSpace)));
         if (!renderTargetContext) {
             return nullptr;
         }
diff --git a/src/effects/imagefilters/SkLightingImageFilter.cpp b/src/effects/imagefilters/SkLightingImageFilter.cpp
index dbe30c6..d89233f 100644
--- a/src/effects/imagefilters/SkLightingImageFilter.cpp
+++ b/src/effects/imagefilters/SkLightingImageFilter.cpp
@@ -464,11 +464,14 @@
     sk_sp<GrTextureProxy> inputProxy(input->asTextureProxyRef(context));
     SkASSERT(inputProxy);
 
+    SkColorType colorType = outputProperties.colorType();
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(colorType);
 
     sk_sp<GrRenderTargetContext> renderTargetContext(
         context->contextPriv().makeDeferredRenderTargetContext(
-                                SkBackingFit::kApprox, offsetBounds.width(), offsetBounds.height(),
-                                SkColorType2GrPixelConfig(outputProperties.colorType()),
+                                format, SkBackingFit::kApprox, offsetBounds.width(),
+                                offsetBounds.height(), SkColorType2GrPixelConfig(colorType),
                                 sk_ref_sp(outputProperties.colorSpace())));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index ae07ffb..662343b 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -466,7 +466,10 @@
     sk_sp<GrTextureProxy> srcTexture(input->asTextureProxyRef(context));
     SkASSERT(srcTexture);
     sk_sp<SkColorSpace> colorSpace = sk_ref_sp(outputProperties.colorSpace());
-    GrPixelConfig config = SkColorType2GrPixelConfig(outputProperties.colorType());
+    SkColorType colorType = outputProperties.colorType();
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(colorType);
+    GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
 
     // setup new clip
     const GrFixedClip clip(SkIRect::MakeWH(srcTexture->width(), srcTexture->height()));
@@ -479,7 +482,7 @@
     if (radius.fWidth > 0) {
         sk_sp<GrRenderTargetContext> dstRTContext(
             context->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace));
+                format, SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace));
         if (!dstRTContext) {
             return nullptr;
         }
@@ -498,7 +501,7 @@
     if (radius.fHeight > 0) {
         sk_sp<GrRenderTargetContext> dstRTContext(
             context->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace));
+                format, SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace));
         if (!dstRTContext) {
             return nullptr;
         }
diff --git a/src/effects/imagefilters/SkXfermodeImageFilter.cpp b/src/effects/imagefilters/SkXfermodeImageFilter.cpp
index 9dad6c2..a56817f 100644
--- a/src/effects/imagefilters/SkXfermodeImageFilter.cpp
+++ b/src/effects/imagefilters/SkXfermodeImageFilter.cpp
@@ -315,10 +315,14 @@
 
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
+    SkColorType colorType = outputProperties.colorType();
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(colorType);
+
     sk_sp<GrRenderTargetContext> renderTargetContext(
         context->contextPriv().makeDeferredRenderTargetContext(
-                                    SkBackingFit::kApprox, bounds.width(), bounds.height(),
-                                    SkColorType2GrPixelConfig(outputProperties.colorType()),
+                                    format, SkBackingFit::kApprox, bounds.width(), bounds.height(),
+                                    SkColorType2GrPixelConfig(colorType),
                                     sk_ref_sp(outputProperties.colorSpace())));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 76918de..8a3d5c8 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -548,7 +548,7 @@
 
                 return tex;
             },
-            desc, fSurfaceOrigin, GrMipMapped::kNo, textureType, SkBackingFit::kExact,
+            backendFormat, desc, fSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
             SkBudgeted::kNo);
 
     if (!texProxy) {
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
index 8198d52..55f11c6 100644
--- a/src/gpu/GrBackendSurface.cpp
+++ b/src/gpu/GrBackendSurface.cpp
@@ -20,21 +20,43 @@
 
 GrBackendFormat::GrBackendFormat(GrGLenum format, GrGLenum target)
         : fBackend(GrBackendApi::kOpenGL)
-        , fValid(true) {
-    fGL.fTarget = target;
-    fGL.fFormat = format;
+        , fValid(true)
+        , fGLFormat(format) {
+    switch (target) {
+        case GR_GL_TEXTURE_2D:
+            fTextureType = GrTextureType::k2D;
+            break;
+        case GR_GL_TEXTURE_RECTANGLE:
+            fTextureType = GrTextureType::kRectangle;
+            break;
+        case GR_GL_TEXTURE_EXTERNAL:
+            fTextureType = GrTextureType::kExternal;
+            break;
+        default:
+            SK_ABORT("Unexpected texture target");
+    }
 }
 
 const GrGLenum* GrBackendFormat::getGLFormat() const {
     if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
-        return &fGL.fFormat;
+        return &fGLFormat;
     }
     return nullptr;
 }
 
 const GrGLenum* GrBackendFormat::getGLTarget() const {
     if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
-        return &fGL.fTarget;
+        static constexpr GrGLenum k2D = GR_GL_TEXTURE_2D;
+        static constexpr GrGLenum kRect = GR_GL_TEXTURE_RECTANGLE;
+        static constexpr GrGLenum kExternal = GR_GL_TEXTURE_EXTERNAL;
+        switch (fTextureType) {
+            case GrTextureType::k2D:
+                return &k2D;
+            case GrTextureType::kRectangle:
+                return &kRect;
+            case GrTextureType::kExternal:
+                return &kExternal;
+        }
     }
     return nullptr;
 }
@@ -44,9 +66,10 @@
 #ifdef SK_VULKAN
         , fValid(true)
 #else
-        ,fValid(false)
+        , fValid(false)
 #endif
-        , fVkFormat(vkFormat) {
+        , fVkFormat(vkFormat)
+        , fTextureType(GrTextureType::k2D) {
 }
 
 const VkFormat* GrBackendFormat::getVkFormat() const {
@@ -60,7 +83,8 @@
 GrBackendFormat::GrBackendFormat(GrMTLPixelFormat mtlFormat)
         : fBackend(GrBackendApi::kMetal)
         , fValid(true)
-        , fMtlFormat(mtlFormat) {
+        , fMtlFormat(mtlFormat)
+        , fTextureType(GrTextureType::k2D) {
 }
 
 const GrMTLPixelFormat* GrBackendFormat::getMtlFormat() const {
@@ -74,7 +98,8 @@
 GrBackendFormat::GrBackendFormat(GrPixelConfig config)
         : fBackend(GrBackendApi::kMock)
         , fValid(true)
-        , fMockFormat(config) {
+        , fMockFormat(config)
+        , fTextureType(GrTextureType::k2D) {
 }
 
 const GrPixelConfig* GrBackendFormat::getMockFormat() const {
@@ -84,6 +109,14 @@
     return nullptr;
 }
 
+GrBackendFormat GrBackendFormat::makeTexture2D() const {
+    // TODO: once we support ycbcr conversions in Vulkan we need to check if we are using an
+    // external format since they will not be able to be made into a Texture2D.
+    GrBackendFormat copy = *this;
+    copy.fTextureType = GrTextureType::k2D;
+    return copy;
+}
+
 GrBackendTexture::GrBackendTexture(int width,
                                    int height,
                                    const GrVkImageInfo& vkInfo)
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 212aded..2aa6544 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -133,11 +133,10 @@
     GrBackendTexture backendTexture = fBackendTexture;
     RefHelper* refHelper = fRefHelper;
 
-    GrTextureType textureType = GrTextureType::k2D;
-    GrGLTextureInfo glInfo;
-    if (backendTexture.getGLTextureInfo(&glInfo)) {
-        textureType = GrGLTexture::TextureTypeFromTarget(glInfo.fTarget);
-    }
+    GrBackendFormat format =
+            context->contextPriv().caps()->createFormatFromBackendTexture(backendTexture);
+    SkASSERT(format.isValid());
+
     sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
             [refHelper, releaseProcHelper, semaphore, backendTexture]
             (GrResourceProvider* resourceProvider) {
@@ -176,7 +175,7 @@
 
                 return tex;
             },
-            desc, fSurfaceOrigin, mipMapped, textureType, SkBackingFit::kExact, SkBudgeted::kNo);
+            format, desc, fSurfaceOrigin, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
 
     if (!proxy) {
         return nullptr;
@@ -193,10 +192,16 @@
         // layout change in Vulkan and we do not change the layout of borrowed images.
         GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
 
+        GrBackendFormat format = proxy->backendFormat().makeTexture2D();
+        if (!format.isValid()) {
+            return nullptr;
+        }
+
         sk_sp<GrRenderTargetContext> rtContext(
             context->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kExact, info.width(), info.height(), proxy->config(), nullptr, 1,
-                mipMapped, proxy->origin(), nullptr, SkBudgeted::kYes));
+                format, SkBackingFit::kExact, info.width(), info.height(),
+                proxy->config(), nullptr, 1, mipMapped, proxy->origin(), nullptr,
+                SkBudgeted::kYes));
 
         if (!rtContext) {
             return nullptr;
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index b4b93f4..4e29461 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -175,10 +175,13 @@
                                              const SkMatrix& origViewMatrix,
                                              const GrShape& shape,
                                              int sampleCnt) {
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
     sk_sp<GrRenderTargetContext> rtContext(
         context->contextPriv().makeDeferredRenderTargetContextWithFallback(
-            SkBackingFit::kApprox, maskRect.width(), maskRect.height(), kAlpha_8_GrPixelConfig,
-            nullptr, sampleCnt, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin));
+            format, SkBackingFit::kApprox, maskRect.width(), maskRect.height(),
+            kAlpha_8_GrPixelConfig, nullptr, sampleCnt, GrMipMapped::kNo,
+            kTopLeft_GrSurfaceOrigin));
     if (!rtContext) {
         return nullptr;
     }
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index c2a5a91..64625d9 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -9,6 +9,7 @@
 
 #include "GrBackendSurface.h"
 #include "GrContextOptions.h"
+#include "GrTypesPriv.h"
 #include "GrWindowRectangles.h"
 #include "SkJSONWriter.h"
 
@@ -276,9 +277,14 @@
     return true;
 }
 
+GrBackendFormat GrCaps::getBackendFormatFromColorType(SkColorType ct) const {
+    return this->getBackendFormatFromGrColorType(SkColorTypeToGrColorType(ct), GrSRGBEncoded::kNo);
+}
+
 GrBackendFormat GrCaps::createFormatFromBackendTexture(const GrBackendTexture& backendTex) const {
     if (!backendTex.isValid()) {
         return GrBackendFormat();
     }
     return this->onCreateFormatFromBackendTexture(backendTex);
 }
+
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 98eaa41..c695ebe 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -303,13 +303,15 @@
     virtual bool getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
                                                 GrPixelConfig*) const = 0;
 
-#ifdef GR_TEST_UTILS
+    virtual GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
+                                                            GrSRGBEncoded srgbEncoded) const = 0;
+    GrBackendFormat getBackendFormatFromColorType(SkColorType ct) const;
+
     /**
      * Creates a GrBackendFormat which matches the backend texture. If the backend texture is
      * invalid, the function will return the default GrBackendFormat.
      */
     GrBackendFormat createFormatFromBackendTexture(const GrBackendTexture&) const;
-#endif
 
     const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; }
 
@@ -319,13 +321,11 @@
         expand them. */
     void applyOptionsOverrides(const GrContextOptions& options);
 
-#ifdef GR_TEST_UTILS
     /**
      * Subclasses implement this to actually create a GrBackendFormat to match backend texture. At
      * this point, the backend texture has already been validated.
      */
     virtual GrBackendFormat onCreateFormatFromBackendTexture(const GrBackendTexture&) const = 0;
-#endif
 
     sk_sp<GrShaderCaps> fShaderCaps;
 
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 92af020..ca5043d 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -344,8 +344,11 @@
         return proxy;
     }
 
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
     sk_sp<GrRenderTargetContext> rtc(
         context->contextPriv().makeDeferredRenderTargetContextWithFallback(
+                                                                        format,
                                                                         SkBackingFit::kApprox,
                                                                         reducedClip.width(),
                                                                         reducedClip.height(),
@@ -473,10 +476,15 @@
         desc.fWidth = maskSpaceIBounds.width();
         desc.fHeight = maskSpaceIBounds.height();
         desc.fConfig = kAlpha_8_GrPixelConfig;
+
+        GrBackendFormat format =
+                context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
+
         // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt
         // to ops), so it can't have any pending IO.
-        proxy = proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
-                                           SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
+        proxy = proxyProvider->createProxy(format, desc, kTopLeft_GrSurfaceOrigin,
+                                           SkBackingFit::kApprox, SkBudgeted::kYes,
+                                           GrInternalSurfaceFlags::kNoPendingIO);
 
         auto uploader = skstd::make_unique<GrTDeferredProxyUploader<ClipMaskData>>(reducedClip);
         GrTDeferredProxyUploader<ClipMaskData>* uploaderRaw = uploader.get();
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index a941b50..46c7607 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -496,7 +496,8 @@
             fContext->contextPriv().caps()->isConfigTexturable(kRGBA_8888_GrPixelConfig) &&
             fContext->validPMUPMConversionExists();
 
-    if (!fContext->contextPriv().caps()->surfaceSupportsWritePixels(dstSurface) ||
+    const GrCaps* caps = this->caps();
+    if (!caps->surfaceSupportsWritePixels(dstSurface) ||
         canvas2DFastPath) {
         // We don't expect callers that are skipping flushes to require an intermediate draw.
         SkASSERT(!(pixelOpsFlags & kDontFlush_PixelOpsFlag));
@@ -505,12 +506,25 @@
         }
 
         GrSurfaceDesc desc;
-        desc.fConfig = canvas2DFastPath ? kRGBA_8888_GrPixelConfig : dstProxy->config();
         desc.fWidth = width;
         desc.fHeight = height;
         desc.fSampleCnt = 1;
+
+        GrBackendFormat format;
+        if (canvas2DFastPath) {
+            desc.fConfig = kRGBA_8888_GrPixelConfig;
+            format =
+              fContext->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+        } else {
+            desc.fConfig =  dstProxy->config();
+            format = dstProxy->backendFormat().makeTexture2D();
+            if (!format.isValid()) {
+                return false;
+            }
+        }
+
         auto tempProxy = this->proxyProvider()->createProxy(
-                desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+                format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
         if (!tempProxy) {
             return false;
         }
@@ -683,8 +697,23 @@
         desc.fWidth = width;
         desc.fHeight = height;
         desc.fSampleCnt = 1;
+
+        GrBackendFormat format;
+        if (canvas2DFastPath) {
+            desc.fFlags = kRenderTarget_GrSurfaceFlag;
+            desc.fConfig = kRGBA_8888_GrPixelConfig;
+            format = this->caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+        } else {
+            desc.fFlags = kNone_GrSurfaceFlags;
+            desc.fConfig = srcProxy->config();
+            format = srcProxy->backendFormat().makeTexture2D();
+            if (!format.isValid()) {
+                return false;
+            }
+        }
+
         auto tempProxy = this->proxyProvider()->createProxy(
-                desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+                format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
         if (!tempProxy) {
             return false;
         }
@@ -864,7 +893,8 @@
     }
 }
 
-sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
+sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrBackendFormat& format,
+                                                                  const GrSurfaceDesc& dstDesc,
                                                                   GrSurfaceOrigin origin,
                                                                   GrMipMapped mipMapped,
                                                                   SkBackingFit fit,
@@ -873,10 +903,10 @@
                                                                   const SkSurfaceProps* props) {
     sk_sp<GrTextureProxy> proxy;
     if (GrMipMapped::kNo == mipMapped) {
-        proxy = this->proxyProvider()->createProxy(dstDesc, origin, fit, isDstBudgeted);
+        proxy = this->proxyProvider()->createProxy(format, dstDesc, origin, fit, isDstBudgeted);
     } else {
         SkASSERT(SkBackingFit::kExact == fit);
-        proxy = this->proxyProvider()->createMipMapProxy(dstDesc, origin, isDstBudgeted);
+        proxy = this->proxyProvider()->createMipMapProxy(format, dstDesc, origin, isDstBudgeted);
     }
     if (!proxy) {
         return nullptr;
@@ -999,6 +1029,7 @@
 }
 
 sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContextWithFallback(
+                                                                 const GrBackendFormat& format,
                                                                  SkBackingFit fit,
                                                                  int width, int height,
                                                                  GrPixelConfig config,
@@ -1008,17 +1039,28 @@
                                                                  GrSurfaceOrigin origin,
                                                                  const SkSurfaceProps* surfaceProps,
                                                                  SkBudgeted budgeted) {
+    GrBackendFormat localFormat = format;
     SkASSERT(sampleCnt > 0);
     if (0 == fContext->contextPriv().caps()->getRenderTargetSampleCount(sampleCnt, config)) {
         config = GrPixelConfigFallback(config);
+        // TODO: First we should be checking the getRenderTargetSampleCount from the GrBackendFormat
+        // and not GrPixelConfig. Besides that, we should implement the fallback in the caps, but
+        // for now we just convert the fallback pixel config to an SkColorType and then get the
+        // GrBackendFormat from that.
+        SkColorType colorType;
+        if (!GrPixelConfigToColorType(config, &colorType)) {
+            return nullptr;
+        }
+        localFormat = fContext->fCaps->getBackendFormatFromColorType(colorType);
     }
 
-    return this->makeDeferredRenderTargetContext(fit, width, height, config, std::move(colorSpace),
-                                                 sampleCnt, mipMapped, origin, surfaceProps,
-                                                 budgeted);
+    return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config,
+                                                 std::move(colorSpace), sampleCnt, mipMapped,
+                                                 origin, surfaceProps, budgeted);
 }
 
 sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContext(
+                                                        const GrBackendFormat& format,
                                                         SkBackingFit fit,
                                                         int width, int height,
                                                         GrPixelConfig config,
@@ -1042,9 +1084,9 @@
 
     sk_sp<GrTextureProxy> rtp;
     if (GrMipMapped::kNo == mipMapped) {
-        rtp = fContext->fProxyProvider->createProxy(desc, origin, fit, budgeted);
+        rtp = fContext->fProxyProvider->createProxy(format, desc, origin, fit, budgeted);
     } else {
-        rtp = fContext->fProxyProvider->createMipMapProxy(desc, origin, budgeted);
+        rtp = fContext->fProxyProvider->createMipMapProxy(format, desc, origin, budgeted);
     }
     if (!rtp) {
         return nullptr;
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index ba7b0cf..f62979a 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -12,6 +12,7 @@
 #include "GrSurfaceContext.h"
 #include "text/GrAtlasManager.h"
 
+class GrBackendFormat;
 class GrBackendRenderTarget;
 class GrOpMemoryPool;
 class GrOnFlushCallbackObject;
@@ -43,7 +44,8 @@
                                                       sk_sp<SkColorSpace> = nullptr,
                                                       const SkSurfaceProps* = nullptr);
 
-    sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc&,
+    sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrBackendFormat&,
+                                                       const GrSurfaceDesc&,
                                                        GrSurfaceOrigin,
                                                        GrMipMapped,
                                                        SkBackingFit,
@@ -217,6 +219,7 @@
      * renderTargetContexts created via this entry point.
      */
     sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContext(
+                                                 const GrBackendFormat& format,
                                                  SkBackingFit fit,
                                                  int width, int height,
                                                  GrPixelConfig config,
@@ -233,6 +236,7 @@
      * SRGB-ness will be preserved.
      */
     sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContextWithFallback(
+                                                 const GrBackendFormat& format,
                                                  SkBackingFit fit,
                                                  int width, int height,
                                                  GrPixelConfig config,
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 88308e4..6918123 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -34,12 +34,13 @@
 }
 
 std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrProxyProvider* proxyProvider,
+                                                   const GrBackendFormat& format,
                                                    GrPixelConfig config, int width,
                                                    int height, int numPlotsX, int numPlotsY,
                                                    AllowMultitexturing allowMultitexturing,
                                                    GrDrawOpAtlas::EvictionFunc func, void* data) {
-    std::unique_ptr<GrDrawOpAtlas> atlas(new GrDrawOpAtlas(proxyProvider, config, width, height,
-                                                           numPlotsX, numPlotsY,
+    std::unique_ptr<GrDrawOpAtlas> atlas(new GrDrawOpAtlas(proxyProvider, format, config, width,
+                                                           height, numPlotsX, numPlotsY,
                                                            allowMultitexturing));
     if (!atlas->getProxies()[0]) {
         return nullptr;
@@ -178,10 +179,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider,
+GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider, const GrBackendFormat& format,
                              GrPixelConfig config, int width, int height,
                              int numPlotsX, int numPlotsY, AllowMultitexturing allowMultitexturing)
-        : fPixelConfig(config)
+        : fFormat(format)
+        , fPixelConfig(config)
         , fTextureWidth(width)
         , fTextureHeight(height)
         , fAtlasGeneration(kInvalidAtlasGeneration + 1)
@@ -521,7 +523,7 @@
     int numPlotsY = fTextureHeight/fPlotHeight;
 
     for (uint32_t i = 0; i < this->maxPages(); ++i) {
-        fProxies[i] = proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin,
+        fProxies[i] = proxyProvider->createProxy(fFormat, desc, kTopLeft_GrSurfaceOrigin,
                 SkBackingFit::kExact, SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
         if (!fProxies[i]) {
             return false;
@@ -647,4 +649,3 @@
 
 constexpr int GrDrawOpAtlasConfig::kMaxDistanceFieldDim;
 constexpr int GrDrawOpAtlasConfig::kPlotSize;
-
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index 2e8f3e7..c9d5546 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -90,7 +90,9 @@
      *                          eviction occurs
      *  @return                 An initialized GrDrawOpAtlas, or nullptr if creation fails
      */
-    static std::unique_ptr<GrDrawOpAtlas> Make(GrProxyProvider*, GrPixelConfig,
+    static std::unique_ptr<GrDrawOpAtlas> Make(GrProxyProvider*,
+                                               const GrBackendFormat& format,
+                                               GrPixelConfig,
                                                int width, int height,
                                                int numPlotsX, int numPlotsY,
                                                AllowMultitexturing allowMultitexturing,
@@ -240,8 +242,9 @@
     void setMaxPages_TestingOnly(uint32_t maxPages);
 
 private:
-    GrDrawOpAtlas(GrProxyProvider*, GrPixelConfig, int width, int height, int numPlotsX,
-                  int numPlotsY, AllowMultitexturing allowMultitexturing);
+    GrDrawOpAtlas(GrProxyProvider*, const GrBackendFormat& format, GrPixelConfig, int width,
+                  int height, int numPlotsX, int numPlotsY,
+                  AllowMultitexturing allowMultitexturing);
 
     /**
      * The backing GrTexture for a GrDrawOpAtlas is broken into a spatial grid of Plots. The Plots
@@ -377,6 +380,7 @@
         plot->resetRects();
     }
 
+    GrBackendFormat       fFormat;
     GrPixelConfig         fPixelConfig;
     int                   fTextureWidth;
     int                   fTextureHeight;
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index d63c5ac..33d116c 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -14,48 +14,6 @@
 #include "GrSurfaceProxy.h"
 
 sk_sp<GrRenderTargetContext> GrOnFlushResourceProvider::makeRenderTargetContext(
-        const GrSurfaceDesc& desc,
-        GrSurfaceOrigin origin,
-        sk_sp<SkColorSpace> colorSpace,
-        const SkSurfaceProps* props) {
-    GrSurfaceDesc tmpDesc = desc;
-    tmpDesc.fFlags |= kRenderTarget_GrSurfaceFlag;
-
-    auto proxyProvider = fDrawingMgr->getContext()->contextPriv().proxyProvider();
-    auto resourceProvider = fDrawingMgr->getContext()->contextPriv().resourceProvider();
-
-    // Because this is being allocated at the start of a flush we must ensure the proxy
-    // will, when instantiated, have no pending IO.
-    // TODO: fold the kNoPendingIO_Flag into GrSurfaceFlags?
-    sk_sp<GrSurfaceProxy> proxy =
-            proxyProvider->createProxy(tmpDesc, origin, SkBackingFit::kExact, SkBudgeted::kYes,
-                                       GrInternalSurfaceFlags::kNoPendingIO);
-    if (!proxy || !proxy->asRenderTargetProxy()) {
-        return nullptr;
-    }
-
-    sk_sp<GrRenderTargetContext> renderTargetContext(
-        fDrawingMgr->makeRenderTargetContext(std::move(proxy),
-                                             std::move(colorSpace),
-                                             props, false));
-
-    if (!renderTargetContext) {
-        return nullptr;
-    }
-
-    // Since this is at flush time and these won't be allocated for us by the GrResourceAllocator
-    // we have to manually ensure it is allocated here. The proxy had best have been created
-    // with the kNoPendingIO flag!
-    if (!renderTargetContext->asSurfaceProxy()->instantiate(resourceProvider)) {
-        return nullptr;
-    }
-
-    renderTargetContext->discard();
-
-    return renderTargetContext;
-}
-
-sk_sp<GrRenderTargetContext> GrOnFlushResourceProvider::makeRenderTargetContext(
                                                         sk_sp<GrSurfaceProxy> proxy,
                                                         sk_sp<SkColorSpace> colorSpace,
                                                         const SkSurfaceProps* props) {
diff --git a/src/gpu/GrOnFlushResourceProvider.h b/src/gpu/GrOnFlushResourceProvider.h
index c30ec61..9ff2384 100644
--- a/src/gpu/GrOnFlushResourceProvider.h
+++ b/src/gpu/GrOnFlushResourceProvider.h
@@ -66,10 +66,12 @@
 public:
     explicit GrOnFlushResourceProvider(GrDrawingManager* drawingMgr) : fDrawingMgr(drawingMgr) {}
 
+#if 0
     sk_sp<GrRenderTargetContext> makeRenderTargetContext(const GrSurfaceDesc&,
                                                          GrSurfaceOrigin,
                                                          sk_sp<SkColorSpace>,
                                                          const SkSurfaceProps*);
+#endif
 
     sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
                                                          sk_sp<SkColorSpace>,
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index c1f8fad..3259f28 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -194,6 +194,11 @@
         return nullptr;
     }
 
+    GrBackendFormat format = fCaps->getBackendFormatFromColorType(info.colorType());
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     if (!this->caps()->isConfigTexturable(config)) {
         SkBitmap copy8888;
         if (!copy8888.tryAllocPixels(info.makeColorType(kRGBA_8888_SkColorType)) ||
@@ -246,8 +251,7 @@
                 return resourceProvider->createTexture(desc, budgeted, fit, mipLevel,
                                                        resourceProviderFlags);
             },
-            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrTextureType::k2D, surfaceFlags, fit,
-            budgeted);
+            format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, surfaceFlags, fit, budgeted);
 
     if (!proxy) {
         return nullptr;
@@ -266,7 +270,8 @@
     return proxy;
 }
 
-sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrSurfaceDesc& desc,
+sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrBackendFormat& format,
+                                                         const GrSurfaceDesc& desc,
                                                          GrSurfaceOrigin origin,
                                                          SkBudgeted budgeted) {
     ASSERT_SINGLE_OWNER
@@ -275,8 +280,8 @@
         return nullptr;
     }
 
-    return this->createProxy(desc, origin, GrMipMapped::kYes, SkBackingFit::kExact, budgeted,
-                             GrInternalSurfaceFlags::kNone);
+    return this->createProxy(format, desc, origin, GrMipMapped::kYes, SkBackingFit::kExact,
+                             budgeted, GrInternalSurfaceFlags::kNone);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitmap& bitmap) {
@@ -302,6 +307,11 @@
                                         SkBackingFit::kExact);
     }
 
+    const GrBackendFormat format = fCaps->getBackendFormatFromColorType(bitmap.info().colorType());
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
     if (!this->caps()->isConfigTexturable(desc.fConfig)) {
         SkBitmap copy8888;
@@ -349,8 +359,8 @@
                 return resourceProvider->createTexture(desc, SkBudgeted::kYes, texels.get(),
                                                        mipLevelCount);
             },
-            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes, GrTextureType::k2D,
-            SkBackingFit::kExact, SkBudgeted::kYes);
+            format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes, SkBackingFit::kExact,
+            SkBudgeted::kYes);
 
     if (!proxy) {
         return nullptr;
@@ -366,7 +376,8 @@
     return proxy;
 }
 
-sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc,
+sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrBackendFormat& format,
+                                                   const GrSurfaceDesc& desc,
                                                    GrSurfaceOrigin origin,
                                                    GrMipMapped mipMapped,
                                                    SkBackingFit fit,
@@ -392,12 +403,12 @@
     if (copyDesc.fFlags & kRenderTarget_GrSurfaceFlag) {
         // We know anything we instantiate later from this deferred path will be
         // both texturable and renderable
-        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(*this->caps(), copyDesc, origin,
-                                                                    mipMapped, GrTextureType::k2D,
+        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(*this->caps(), format, copyDesc,
+                                                                    origin, mipMapped,
                                                                     fit, budgeted, surfaceFlags));
     }
 
-    return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, origin, mipMapped, GrTextureType::k2D,
+    return sk_sp<GrTextureProxy>(new GrTextureProxy(format, copyDesc, origin, mipMapped,
                                                     fit, budgeted, surfaceFlags));
 }
 
@@ -512,36 +523,36 @@
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
+                                                       const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
-                                                       GrTextureType textureType,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted) {
-    return this->createLazyProxy(std::move(callback), desc, origin, mipMapped, textureType,
+    return this->createLazyProxy(std::move(callback), format, desc, origin, mipMapped,
                                  GrInternalSurfaceFlags::kNone, fit, budgeted);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
+                                                       const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
-                                                       GrTextureType textureType,
                                                        GrInternalSurfaceFlags surfaceFlags,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted) {
     // For non-ddl draws always make lazy proxy's single use.
     LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse
                                                        : LazyInstantiationType::kMultipleUse;
-    return this->createLazyProxy(std::move(callback), desc, origin, mipMapped, textureType,
-                                 surfaceFlags, fit, budgeted, lazyType);
+    return this->createLazyProxy(std::move(callback), format, desc, origin, mipMapped, surfaceFlags,
+                                 fit, budgeted, lazyType);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
+                                                       const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
-                                                       GrTextureType textureType,
                                                        GrInternalSurfaceFlags surfaceFlags,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
@@ -567,17 +578,16 @@
 
     return sk_sp<GrTextureProxy>(
             SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)
-                    ? new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, origin,
-                                                     mipMapped, textureType, fit, budgeted,
-                                                     surfaceFlags)
-                    : new GrTextureProxy(std::move(callback), lazyType, desc, origin, mipMapped,
-                                         textureType, fit, budgeted, surfaceFlags));
+                    ? new GrTextureRenderTargetProxy(std::move(callback), lazyType, format, desc,
+                                                     origin, mipMapped, fit, budgeted, surfaceFlags)
+                    : new GrTextureProxy(std::move(callback), lazyType, format, desc, origin,
+                                         mipMapped, fit, budgeted, surfaceFlags));
 }
 
 sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy(
-        LazyInstantiateCallback&& callback, const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
-        GrInternalSurfaceFlags surfaceFlags, const TextureInfo* textureInfo, SkBackingFit fit,
-        SkBudgeted budgeted) {
+        LazyInstantiateCallback&& callback, const GrBackendFormat& format,
+        const GrSurfaceDesc& desc, GrSurfaceOrigin origin, GrInternalSurfaceFlags surfaceFlags,
+        const TextureInfo* textureInfo, SkBackingFit fit, SkBudgeted budgeted) {
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
 
@@ -603,15 +613,16 @@
 
     if (textureInfo) {
         return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(
-                std::move(callback), lazyType, desc, origin, textureInfo->fMipMapped,
-                textureInfo->fTextureType, fit, budgeted, surfaceFlags));
+                std::move(callback), lazyType, format, desc, origin, textureInfo->fMipMapped,
+                fit, budgeted, surfaceFlags));
     }
 
     return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(
-            std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags));
+            std::move(callback), lazyType, format, desc, origin, fit, budgeted, surfaceFlags));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::MakeFullyLazyProxy(LazyInstantiateCallback&& callback,
+                                                          const GrBackendFormat& format,
                                                           Renderable renderable,
                                                           GrSurfaceOrigin origin,
                                                           GrPixelConfig config,
@@ -629,15 +640,14 @@
     desc.fConfig = config;
     desc.fSampleCnt = 1;
 
-    static constexpr auto kTextureType = GrTextureType::k2D;
     return sk_sp<GrTextureProxy>(
             (Renderable::kYes == renderable)
                     ? new GrTextureRenderTargetProxy(
-                              std::move(callback), LazyInstantiationType::kSingleUse, desc, origin,
-                              GrMipMapped::kNo, kTextureType, SkBackingFit::kApprox,
-                              SkBudgeted::kYes, surfaceFlags)
+                              std::move(callback), LazyInstantiationType::kSingleUse, format, desc,
+                              origin, GrMipMapped::kNo, SkBackingFit::kApprox, SkBudgeted::kYes,
+                              surfaceFlags)
                     : new GrTextureProxy(std::move(callback), LazyInstantiationType::kSingleUse,
-                                         desc, origin, GrMipMapped::kNo, kTextureType,
+                                         format, desc, origin, GrMipMapped::kNo,
                                          SkBackingFit::kApprox, SkBudgeted::kYes, surfaceFlags));
 }
 
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 26dc6e9..1e26f51 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -76,7 +76,8 @@
      * simply has space allocated for the mips. We will allocated the full amount of mip levels
      * based on the width and height in the GrSurfaceDesc.
      */
-    sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, GrSurfaceOrigin, SkBudgeted);
+    sk_sp<GrTextureProxy> createMipMapProxy(const GrBackendFormat&, const GrSurfaceDesc&,
+                                            GrSurfaceOrigin, SkBudgeted);
 
     /*
      * Creates a new mipmapped texture proxy for the bitmap with mip levels generated by the cpu.
@@ -86,14 +87,16 @@
     /*
      * Create a GrSurfaceProxy without any data.
      */
-    sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
-                                      SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
+    sk_sp<GrTextureProxy> createProxy(const GrBackendFormat&, const GrSurfaceDesc&, GrSurfaceOrigin,
+                                      GrMipMapped, SkBackingFit, SkBudgeted,
+                                      GrInternalSurfaceFlags);
 
     sk_sp<GrTextureProxy> createProxy(
-                            const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
-                            SkBackingFit fit, SkBudgeted budgeted,
+                            const GrBackendFormat& format, const GrSurfaceDesc& desc,
+                            GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted,
                             GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone) {
-        return this->createProxy(desc, origin, GrMipMapped::kNo, fit, budgeted, surfaceFlags);
+        return this->createProxy(format, desc, origin, GrMipMapped::kNo, fit, budgeted,
+                                 surfaceFlags);
     }
 
     // These match the definitions in SkImage & GrTexture.h, for whence they came
@@ -150,21 +153,22 @@
      * It also must support being passed in a null GrResourceProvider. When this happens, the
      * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
      */
-    sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
-                                          GrSurfaceOrigin, GrMipMapped, GrTextureType,
+    sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
+                                          const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
                                           GrInternalSurfaceFlags, SkBackingFit, SkBudgeted,
                                           LazyInstantiationType);
 
-    sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
-                                          GrSurfaceOrigin, GrMipMapped, GrTextureType,
+    sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
+                                          const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
                                           GrInternalSurfaceFlags, SkBackingFit, SkBudgeted);
 
-    sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
-                                          GrSurfaceOrigin, GrMipMapped, GrTextureType, SkBackingFit,
-                                          SkBudgeted);
+    sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
+                                          const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
+                                          SkBackingFit, SkBudgeted);
 
     /** A null TextureInfo indicates a non-textureable render target. */
     sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
+                                                           const GrBackendFormat&,
                                                            const GrSurfaceDesc&,
                                                            GrSurfaceOrigin origin,
                                                            GrInternalSurfaceFlags,
@@ -176,7 +180,8 @@
      * Fully lazy proxies have unspecified width and height. Methods that rely on those values
      * (e.g., width, height, getBoundsRect) should be avoided.
      */
-    static sk_sp<GrTextureProxy> MakeFullyLazyProxy(LazyInstantiateCallback&&, Renderable,
+    static sk_sp<GrTextureProxy> MakeFullyLazyProxy(LazyInstantiateCallback&&,
+                                                    const GrBackendFormat&, Renderable,
                                                     GrSurfaceOrigin, GrPixelConfig, const GrCaps&);
 
     // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index fc446bf..7920cf1 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1865,8 +1865,10 @@
         fit = SkBackingFit::kApprox;
     }
 
+    SkASSERT(rtProxy->backendFormat().textureType() == GrTextureType::k2D);
+    const GrBackendFormat& format = rtProxy->backendFormat();
     sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeDeferredSurfaceContext(
-            desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes,
+            format, desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes,
             sk_ref_sp(this->colorSpaceInfo().colorSpace()));
     if (!sContext) {
         SkDebugf("setupDstTexture: surfaceContext creation failed.\n");
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index 5488625..39fdee3 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -19,10 +19,11 @@
 // Deferred version
 // TODO: we can probably munge the 'desc' in both the wrapped and deferred
 // cases to make the sampleConfig/numSamples stuff more rational.
-GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
-                                         GrSurfaceOrigin origin, SkBackingFit fit,
-                                         SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
-        : INHERITED(desc, origin, fit, budgeted, surfaceFlags)
+GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrBackendFormat& format,
+                                         const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
+                                         SkBackingFit fit, SkBudgeted budgeted,
+                                         GrInternalSurfaceFlags surfaceFlags)
+        : INHERITED(format, desc, origin, fit, budgeted, surfaceFlags)
         , fSampleCnt(desc.fSampleCnt)
         , fNeedsStencil(false) {
     // Since we know the newly created render target will be internal, we are able to precompute
@@ -37,10 +38,12 @@
 
 // Lazy-callback version
 GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback,
-                                         LazyInstantiationType lazyType, const GrSurfaceDesc& desc,
-                                         GrSurfaceOrigin origin, SkBackingFit fit,
+                                         LazyInstantiationType lazyType,
+                                         const GrBackendFormat& format, const GrSurfaceDesc& desc,
+                                         GrSurfaceOrigin origin,  SkBackingFit fit,
                                          SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
-        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags)
+        : INHERITED(std::move(callback), lazyType, format, desc, origin, fit, budgeted,
+                    surfaceFlags)
         , fSampleCnt(desc.fSampleCnt)
         , fNeedsStencil(false) {
     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 05b2795..68e51c9 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -181,9 +181,12 @@
     desc.fHeight = height;
     desc.fConfig = kAlpha_8_GrPixelConfig;
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
+
     // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt to
     // ops), so it can't have any pending IO.
-    return proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
+    return proxyProvider->createProxy(format, desc, kTopLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
                                       GrInternalSurfaceFlags::kNoPendingIO);
 }
 
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index c0e65c0..ac650af 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -49,9 +49,11 @@
 
 // Lazy-callback version
 GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
-                               const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit,
+                               const GrBackendFormat& format, const GrSurfaceDesc& desc,
+                               GrSurfaceOrigin origin, SkBackingFit fit,
                                SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
         : fSurfaceFlags(surfaceFlags)
+        , fFormat(format)
         , fConfig(desc.fConfig)
         , fWidth(desc.fWidth)
         , fHeight(desc.fHeight)
@@ -63,6 +65,7 @@
         , fNeedsClear(SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag))
         , fGpuMemorySize(kInvalidGpuMemorySize)
         , fLastOpList(nullptr) {
+    SkASSERT(fFormat.isValid());
     // NOTE: the default fUniqueID ctor pulls a value from the same pool as the GrGpuResources.
     if (fLazyInstantiateCallback) {
         SkASSERT(is_valid_fully_lazy(desc, fit) || is_valid_partially_lazy(desc));
@@ -75,6 +78,7 @@
 GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit)
         : INHERITED(std::move(surface))
         , fSurfaceFlags(fTarget->surfacePriv().flags())
+        , fFormat(fTarget->backendFormat())
         , fConfig(fTarget->config())
         , fWidth(fTarget->width())
         , fHeight(fTarget->height())
@@ -85,6 +89,7 @@
         , fNeedsClear(false)
         , fGpuMemorySize(kInvalidGpuMemorySize)
         , fLastOpList(nullptr) {
+    SkASSERT(fFormat.isValid());
 }
 
 GrSurfaceProxy::~GrSurfaceProxy() {
@@ -336,8 +341,13 @@
     dstDesc.fHeight = srcRect.height();
     dstDesc.fConfig = src->config();
 
+    GrBackendFormat format = src->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
-            dstDesc, src->origin(), mipMapped, SkBackingFit::kExact, budgeted));
+            format, dstDesc, src->origin(), mipMapped, SkBackingFit::kExact, budgeted));
     if (!dstContext) {
         return nullptr;
     }
@@ -358,8 +368,14 @@
 sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
                                                  GrSurfaceOrigin origin, GrSurfaceProxy* srcProxy) {
     SkASSERT(LazyState::kFully != srcProxy->lazyInstantiationState());
+
+    GrBackendFormat format = srcProxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
-            dstDesc, origin, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes));
+            format, dstDesc, origin, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes));
     if (!dstContext) {
         return nullptr;
     }
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index cbff079..97417f9 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -44,10 +44,15 @@
         }
     }
 
+    GrBackendFormat format = inputProxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrRenderTargetContext> copyRTC =
         context->contextPriv().makeDeferredRenderTargetContextWithFallback(
-            SkBackingFit::kExact, dstRect.width(), dstRect.height(), inputProxy->config(),
-            nullptr, 1, mipMapped, inputProxy->origin());
+            format, SkBackingFit::kExact, dstRect.width(), dstRect.height(),
+            inputProxy->config(), nullptr, 1, mipMapped, inputProxy->origin());
     if (!copyRTC) {
         return nullptr;
     }
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index a65f241..517b832 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -16,36 +16,35 @@
 #include "GrTexturePriv.h"
 
 // Deferred version - with data
-GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped mipMapped,
-                               GrTextureType textureType, SkBackingFit fit, SkBudgeted budgeted,
+GrTextureProxy::GrTextureProxy(const GrBackendFormat& format, const GrSurfaceDesc& srcDesc,
+                               GrMipMapped mipMapped, SkBackingFit fit, SkBudgeted budgeted,
                                const void* srcData, size_t /*rowBytes*/,
                                GrInternalSurfaceFlags surfaceFlags)
-        : INHERITED(srcDesc, kTopLeft_GrSurfaceOrigin, fit, budgeted, surfaceFlags)
+        : INHERITED(format, srcDesc, kTopLeft_GrSurfaceOrigin, fit, budgeted, surfaceFlags)
         , fMipMapped(mipMapped)
-        , fTextureType(textureType)
         , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {
     SkASSERT(!srcData);  // currently handled in Make()
 }
 
 // Deferred version - no data
-GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrSurfaceOrigin origin,
-                               GrMipMapped mipMapped, GrTextureType textureType, SkBackingFit fit,
-                               SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
-        : INHERITED(srcDesc, origin, fit, budgeted, surfaceFlags)
+GrTextureProxy::GrTextureProxy(const GrBackendFormat& format, const GrSurfaceDesc& srcDesc,
+                               GrSurfaceOrigin origin, GrMipMapped mipMapped,
+                               SkBackingFit fit, SkBudgeted budgeted,
+                               GrInternalSurfaceFlags surfaceFlags)
+        : INHERITED(format, srcDesc, origin, fit, budgeted, surfaceFlags)
         , fMipMapped(mipMapped)
-        , fTextureType(textureType)
         , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {}
 
 // Lazy-callback version
 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
-                               const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
-                               GrMipMapped mipMapped, GrTextureType textureType, SkBackingFit fit,
+                               const GrBackendFormat& format, const GrSurfaceDesc& desc,
+                               GrSurfaceOrigin origin, GrMipMapped mipMapped, SkBackingFit fit,
                                SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags)
-        : INHERITED(std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags)
+        : INHERITED(std::move(callback), lazyType, format, desc, origin, fit, budgeted,
+                    surfaceFlags)
         , fMipMapped(mipMapped)
-        , fTextureType(textureType)
         , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {}
 
@@ -53,7 +52,6 @@
 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin)
         : INHERITED(std::move(surf), origin, SkBackingFit::kExact)
         , fMipMapped(fTarget->asTexture()->texturePriv().mipMapped())
-        , fTextureType(fTarget->asTexture()->texturePriv().textureType())
         , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {
     if (fTarget->getUniqueKey().isValid()) {
@@ -168,7 +166,7 @@
     SkASSERT(surface->asTexture());
     SkASSERT(GrMipMapped::kNo == this->proxyMipMapped() ||
              GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
-    SkASSERT(surface->asTexture()->texturePriv().textureType() == fTextureType);
+    SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
 }
 #endif
 
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index fba48e7..a665270 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -19,34 +19,35 @@
 // This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
 // GrRenderTargetProxy) so its constructor must be explicitly called.
 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
+                                                       const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
-                                                       GrTextureType textureType,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
                                                        GrInternalSurfaceFlags surfaceFlags)
-        : GrSurfaceProxy(desc, origin, fit, budgeted, surfaceFlags)
+        : GrSurfaceProxy(format, desc, origin, fit, budgeted, surfaceFlags)
         // for now textures w/ data are always wrapped
-        , GrRenderTargetProxy(caps, desc, origin, fit, budgeted, surfaceFlags)
-        , GrTextureProxy(desc, origin, mipMapped, textureType, fit, budgeted, surfaceFlags) {}
+        , GrRenderTargetProxy(caps, format, desc, origin, fit, budgeted, surfaceFlags)
+        , GrTextureProxy(format, desc, origin, mipMapped, fit, budgeted, surfaceFlags) {}
 
 // Lazy-callback version
 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(LazyInstantiateCallback&& callback,
                                                        LazyInstantiationType lazyType,
+                                                       const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
-                                                       GrTextureType textureType,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
                                                        GrInternalSurfaceFlags surfaceFlags)
-        : GrSurfaceProxy(std::move(callback), lazyType, desc, origin, fit, budgeted, surfaceFlags)
+        : GrSurfaceProxy(std::move(callback), lazyType, format, desc, origin, fit, budgeted,
+                         surfaceFlags)
         // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
         // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
-        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, desc, origin, fit, budgeted,
-                              surfaceFlags)
-        , GrTextureProxy(LazyInstantiateCallback(), lazyType, desc, origin, mipMapped, textureType,
+        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, format, desc, origin, fit,
+                              budgeted, surfaceFlags)
+        , GrTextureProxy(LazyInstantiateCallback(), lazyType, format, desc, origin, mipMapped,
                          fit, budgeted, surfaceFlags) {}
 
 // Wrapped version
diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h
index a60c230..18c1419 100644
--- a/src/gpu/GrTextureRenderTargetProxy.h
+++ b/src/gpu/GrTextureRenderTargetProxy.h
@@ -28,13 +28,14 @@
     friend class GrProxyProvider; // for ctors
 
     // Deferred version
-    GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped,
-                               GrTextureType, SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
+    GrTextureRenderTargetProxy(const GrCaps&, const GrBackendFormat&, const GrSurfaceDesc&,
+                               GrSurfaceOrigin, GrMipMapped, SkBackingFit, SkBudgeted,
+                               GrInternalSurfaceFlags);
 
     // Lazy-callback version
     GrTextureRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType,
-                               const GrSurfaceDesc& desc, GrSurfaceOrigin, GrMipMapped,
-                               GrTextureType, SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
+                               const GrBackendFormat&, const GrSurfaceDesc& desc, GrSurfaceOrigin,
+                               GrMipMapped, SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
 
     // Wrapped version
     GrTextureRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index eedde34..16027df 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -101,7 +101,9 @@
     cachedData->unref();
 }
 
-sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrSurfaceDesc& desc,
+sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx,
+                                                       const GrBackendFormat& format,
+                                                       const GrSurfaceDesc& desc,
                                                        SkColorSpace* srcColorSpace,
                                                        SkColorSpace* dstColorSpace) {
     SkYUVASizeInfo yuvSizeInfo;
@@ -156,7 +158,7 @@
     // TODO: investigate preallocating mip maps here
     sk_sp<GrRenderTargetContext> renderTargetContext(
         ctx->contextPriv().makeDeferredRenderTargetContext(
-            SkBackingFit::kExact, desc.fWidth, desc.fHeight, desc.fConfig, nullptr,
+            format, SkBackingFit::kExact, desc.fWidth, desc.fHeight, desc.fConfig, nullptr,
             desc.fSampleCnt, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/gpu/GrYUVProvider.h b/src/gpu/GrYUVProvider.h
index e62a2ee..633ccfb 100644
--- a/src/gpu/GrYUVProvider.h
+++ b/src/gpu/GrYUVProvider.h
@@ -14,6 +14,7 @@
 #include "SkYUVASizeInfo.h"
 
 class GrContext;
+class GrBackendFormat;
 struct GrSurfaceDesc;
 class GrTexture;
 class GrTextureProxy;
@@ -40,7 +41,9 @@
      *
      *  On failure (e.g. the provider had no data), this returns NULL.
      */
-    sk_sp<GrTextureProxy> refAsTextureProxy(GrContext*, const GrSurfaceDesc&,
+    sk_sp<GrTextureProxy> refAsTextureProxy(GrContext*,
+                                            const GrBackendFormat&,
+                                            const GrSurfaceDesc&,
                                             SkColorSpace* srcColorSpace,
                                             SkColorSpace* dstColorSpace);
 
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index daa86fc..a29336e 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -164,10 +164,12 @@
     if (kUnknown_GrPixelConfig == config) {
         return nullptr;
     }
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(origInfo.colorType());
     // This method is used to create SkGpuDevice's for SkSurface_Gpus. In this case
     // they need to be exact.
     return context->contextPriv().makeDeferredRenderTargetContext(
-                                    SkBackingFit::kExact,
+                                    format, SkBackingFit::kExact,
                                     origInfo.width(), origInfo.height(),
                                     config, origInfo.refColorSpace(), sampleCount,
                                     mipMapped, origin, surfaceProps, budgeted);
@@ -1749,14 +1751,21 @@
                                                             : SkBackingFit::kExact;
 
     GrPixelConfig config = fRenderTargetContext->colorSpaceInfo().config();
+    const GrBackendFormat& origFormat = fRenderTargetContext->asSurfaceProxy()->backendFormat();
+    GrBackendFormat format = origFormat.makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
     if (kRGBA_1010102_GrPixelConfig == config) {
         // If the original device is 1010102, fall back to 8888 so that we have a usable alpha
         // channel in the layer.
         config = kRGBA_8888_GrPixelConfig;
+        format =
+            fContext->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     }
 
     sk_sp<GrRenderTargetContext> rtc(fContext->contextPriv().makeDeferredRenderTargetContext(
-            fit, cinfo.fInfo.width(), cinfo.fInfo.height(), config,
+            format, fit, cinfo.fInfo.width(), cinfo.fInfo.height(), config,
             fRenderTargetContext->colorSpaceInfo().refColorSpace(),
             fRenderTargetContext->numStencilSamples(), GrMipMapped::kNo,
             kBottomLeft_GrSurfaceOrigin, &props));
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 168cce6..0a6033e 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -160,8 +160,13 @@
     desc.fConfig = baseProxy->config();
     desc.fSampleCnt = 1;
 
+    GrBackendFormat format = baseProxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrTextureProxy> proxy =
-            proxyProvider->createMipMapProxy(desc, baseProxy->origin(), SkBudgeted::kYes);
+            proxyProvider->createMipMapProxy(format, desc, baseProxy->origin(), SkBudgeted::kYes);
     if (!proxy) {
         return nullptr;
     }
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index 0d1f9d9..6dc523d 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -72,6 +72,13 @@
 
     fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, fWidth, fHeight);
 
+    // TODO: don't have this rely on the GrPixelConfig
+    GrSRGBEncoded srgbEncoded = GrSRGBEncoded::kNo;
+    GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(pixelConfig, &srgbEncoded);
+
+    const GrBackendFormat format =
+            caps.getBackendFormatFromGrColorType(colorType, srgbEncoded);
+
     fTextureProxy = GrProxyProvider::MakeFullyLazyProxy(
             [this, pixelConfig](GrResourceProvider* resourceProvider) {
                     if (!resourceProvider) {
@@ -87,7 +94,7 @@
                     }
                     return fBackingTexture;
             },
-            GrProxyProvider::Renderable::kYes, kTextureOrigin, pixelConfig, caps);
+            format, GrProxyProvider::Renderable::kYes, kTextureOrigin, pixelConfig, caps);
 }
 
 GrCCAtlas::~GrCCAtlas() {
diff --git a/src/gpu/ccpr/GrCCClipPath.cpp b/src/gpu/ccpr/GrCCClipPath.cpp
index d70b4f7..8b8d8a6 100644
--- a/src/gpu/ccpr/GrCCClipPath.cpp
+++ b/src/gpu/ccpr/GrCCClipPath.cpp
@@ -16,6 +16,9 @@
                         int rtHeight, const GrCaps& caps) {
     SkASSERT(!this->isInitialized());
 
+    const GrBackendFormat format = caps.getBackendFormatFromGrColorType(GrColorType::kAlpha_F16,
+                                                                        GrSRGBEncoded::kNo);
+
     fAtlasLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
             [this](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
@@ -40,8 +43,8 @@
 
                 return sk_ref_sp(textureProxy->peekTexture());
             },
-            GrProxyProvider::Renderable::kYes, kTopLeft_GrSurfaceOrigin, kAlpha_half_GrPixelConfig,
-            caps);
+            format, GrProxyProvider::Renderable::kYes, kTopLeft_GrSurfaceOrigin,
+            kAlpha_half_GrPixelConfig, caps);
 
     fDeviceSpacePath = deviceSpacePath;
     fDeviceSpacePath.getBounds().roundOut(&fPathDevIBounds);
diff --git a/src/gpu/effects/GrConfigConversionEffect.fp b/src/gpu/effects/GrConfigConversionEffect.fp
index f466cc7..6cee538 100644
--- a/src/gpu/effects/GrConfigConversionEffect.fp
+++ b/src/gpu/effects/GrConfigConversionEffect.fp
@@ -17,6 +17,9 @@
     static bool TestForPreservingPMConversions(GrContext* context) {
         static constexpr int kSize = 256;
         static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig;
+        static constexpr SkColorType kColorType = kRGBA_8888_SkColorType;
+        const GrBackendFormat format =
+                context->contextPriv().caps()->getBackendFormatFromColorType(kColorType);
         SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
         uint32_t* srcData = data.get();
         uint32_t* firstRead = data.get() + kSize * kSize;
@@ -41,11 +44,11 @@
                                                  kRGBA_8888_SkColorType, kPremul_SkAlphaType);
 
         sk_sp<GrRenderTargetContext> readRTC(
-                context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
+                context->contextPriv().makeDeferredRenderTargetContext(format, SkBackingFit::kExact,
                                                                        kSize, kSize,
                                                                        kConfig, nullptr));
         sk_sp<GrRenderTargetContext> tempRTC(
-                context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
+                context->contextPriv().makeDeferredRenderTargetContext(format, SkBackingFit::kExact,
                                                                        kSize, kSize,
                                                                        kConfig, nullptr));
         if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) {
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index 4da5b0f..301a6f9 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -24,6 +24,9 @@
     static bool TestForPreservingPMConversions(GrContext* context) {
         static constexpr int kSize = 256;
         static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig;
+        static constexpr SkColorType kColorType = kRGBA_8888_SkColorType;
+        const GrBackendFormat format =
+                context->contextPriv().caps()->getBackendFormatFromColorType(kColorType);
         SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
         uint32_t* srcData = data.get();
         uint32_t* firstRead = data.get() + kSize * kSize;
@@ -48,9 +51,9 @@
                 SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
 
         sk_sp<GrRenderTargetContext> readRTC(context->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
+                format, SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
         sk_sp<GrRenderTargetContext> tempRTC(context->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
+                format, SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
         if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) {
             return false;
         }
diff --git a/src/gpu/effects/GrRRectBlurEffect.fp b/src/gpu/effects/GrRRectBlurEffect.fp
index a577d91..ccaad63 100644
--- a/src/gpu/effects/GrRRectBlurEffect.fp
+++ b/src/gpu/effects/GrRRectBlurEffect.fp
@@ -51,11 +51,13 @@
         sk_sp<GrTextureProxy> mask(proxyProvider->findOrCreateProxyByUniqueKey(
                                                                  key, kBottomLeft_GrSurfaceOrigin));
         if (!mask) {
+            GrBackendFormat format =
+                context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
             // TODO: this could be approx but the texture coords will need to be updated
             sk_sp<GrRenderTargetContext> rtc(
                     context->contextPriv().makeDeferredRenderTargetContextWithFallback(
-                                                SkBackingFit::kExact, size.fWidth, size.fHeight,
-                                                kAlpha_8_GrPixelConfig, nullptr));
+                                                format, SkBackingFit::kExact, size.fWidth,
+                                                size.fHeight, kAlpha_8_GrPixelConfig, nullptr));
             if (!rtc) {
                 return nullptr;
             }
diff --git a/src/gpu/effects/GrRRectBlurEffect.h b/src/gpu/effects/GrRRectBlurEffect.h
index e760f60..a774e2c 100644
--- a/src/gpu/effects/GrRRectBlurEffect.h
+++ b/src/gpu/effects/GrRRectBlurEffect.h
@@ -51,11 +51,13 @@
         sk_sp<GrTextureProxy> mask(
                 proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin));
         if (!mask) {
+            GrBackendFormat format = context->contextPriv().caps()->getBackendFormatFromColorType(
+                    kAlpha_8_SkColorType);
             // TODO: this could be approx but the texture coords will need to be updated
             sk_sp<GrRenderTargetContext> rtc(
                     context->contextPriv().makeDeferredRenderTargetContextWithFallback(
-                            SkBackingFit::kExact, size.fWidth, size.fHeight, kAlpha_8_GrPixelConfig,
-                            nullptr));
+                            format, SkBackingFit::kExact, size.fWidth, size.fHeight,
+                            kAlpha_8_GrPixelConfig, nullptr));
             if (!rtc) {
                 return nullptr;
             }
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 9dc76b6..34d9d9e 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -15,6 +15,7 @@
 #include "GrSurfaceProxyPriv.h"
 #include "GrTextureProxyPriv.h"
 #include "SkJSONWriter.h"
+#include "SkGr.h"
 #include "SkTSearch.h"
 #include "SkTSort.h"
 
@@ -2993,12 +2994,19 @@
     return get_yuva_config(*glFormat, config);
 }
 
-
-#ifdef GR_TEST_UTILS
 GrBackendFormat GrGLCaps::onCreateFormatFromBackendTexture(
         const GrBackendTexture& backendTex) const {
     GrGLTextureInfo glInfo;
     SkAssertResult(backendTex.getGLTextureInfo(&glInfo));
     return GrBackendFormat::MakeGL(glInfo.fFormat, glInfo.fTarget);
 }
-#endif
+
+GrBackendFormat GrGLCaps::getBackendFormatFromGrColorType(GrColorType ct,
+                                                          GrSRGBEncoded srgbEncoded) const {
+    GrPixelConfig config = GrColorTypeToPixelConfig(ct, srgbEncoded);
+    if (config == kUnknown_GrPixelConfig) {
+        return GrBackendFormat();
+    }
+    return GrBackendFormat::MakeGL(this->configSizedInternalFormat(config), GR_GL_TEXTURE_2D);
+}
+
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index fda673e..329618b 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -441,6 +441,9 @@
     bool getYUVAConfigFromBackendFormat(const GrBackendFormat&,
                                         GrPixelConfig*) const override;
 
+    GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
+                                                    GrSRGBEncoded srgbEncoded) const override;
+
 #if GR_TEST_UTILS
     GrGLStandard standard() const { return fStandard; }
 #endif
@@ -466,9 +469,7 @@
 
     void onApplyOptionsOverrides(const GrContextOptions& options) override;
 
-#ifdef GR_TEST_UTILS
     GrBackendFormat onCreateFormatFromBackendTexture(const GrBackendTexture&) const override;
-#endif
 
     bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const override;
 
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 5fa589a..a056a8a 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -754,7 +754,7 @@
     desc.fSampleCnt =
             this->caps()->getRenderTargetSampleCount(backendRT.sampleCnt(), backendRT.config());
 
-    return GrGLRenderTarget::MakeWrapped(this, desc, idDesc, backendRT.stencilBits());
+    return GrGLRenderTarget::MakeWrapped(this, desc, info.fFormat, idDesc, backendRT.stencilBits());
 }
 
 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
@@ -783,7 +783,7 @@
     if (!this->createRenderTargetObjects(surfDesc, info, &rtIDDesc)) {
         return nullptr;
     }
-    return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0);
+    return GrGLRenderTarget::MakeWrapped(this, surfDesc, info.fFormat, rtIDDesc, 0);
 }
 
 static bool check_write_and_transfer_input(GrGLTexture* glTex) {
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index 34f8df1..7344dd7 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -21,21 +21,22 @@
 // Constructor for wrapped render targets.
 GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu,
                                    const GrSurfaceDesc& desc,
+                                   GrGLenum format,
                                    const IDDesc& idDesc,
                                    GrGLStencilAttachment* stencil)
     : GrSurface(gpu, desc)
     , INHERITED(gpu, desc, stencil) {
     this->setFlags(gpu->glCaps(), idDesc);
-    this->init(desc, idDesc);
+    this->init(desc, format, idDesc);
     this->registerWithCacheWrapped();
 }
 
-GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc,
+GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, GrGLenum format,
                                    const IDDesc& idDesc)
     : GrSurface(gpu, desc)
     , INHERITED(gpu, desc) {
     this->setFlags(gpu->glCaps(), idDesc);
-    this->init(desc, idDesc);
+    this->init(desc, format, idDesc);
 }
 
 inline void GrGLRenderTarget::setFlags(const GrGLCaps& glCaps, const IDDesc& idDesc) {
@@ -51,12 +52,14 @@
     }
 }
 
-void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
+void GrGLRenderTarget::init(const GrSurfaceDesc& desc, GrGLenum format, const IDDesc& idDesc) {
     fRTFBOID                = idDesc.fRTFBOID;
     fTexFBOID               = idDesc.fTexFBOID;
     fMSColorRenderbufferID  = idDesc.fMSColorRenderbufferID;
     fRTFBOOwnership         = idDesc.fRTFBOOwnership;
 
+    fRTFormat               = format;
+
     fViewport.fLeft   = 0;
     fViewport.fBottom = 0;
     fViewport.fWidth  = desc.fWidth;
@@ -67,6 +70,7 @@
 
 sk_sp<GrGLRenderTarget> GrGLRenderTarget::MakeWrapped(GrGLGpu* gpu,
                                                       const GrSurfaceDesc& desc,
+                                                      GrGLenum format,
                                                       const IDDesc& idDesc,
                                                       int stencilBits) {
     GrGLStencilAttachment* sb = nullptr;
@@ -81,7 +85,7 @@
         sb = new GrGLStencilAttachment(gpu, sbDesc, desc.fWidth, desc.fHeight,
                                        desc.fSampleCnt, format);
     }
-    return sk_sp<GrGLRenderTarget>(new GrGLRenderTarget(gpu, desc, idDesc, sb));
+    return sk_sp<GrGLRenderTarget>(new GrGLRenderTarget(gpu, desc, format, idDesc, sb));
 }
 
 GrBackendRenderTarget GrGLRenderTarget::getBackendRenderTarget() const {
@@ -97,6 +101,12 @@
                                  numStencilBits, fbi);
 }
 
+GrBackendFormat GrGLRenderTarget::backendFormat() const {
+    // We should never have a GrGLRenderTarget (even a textureable one with a target that is not
+    // texture 2D.
+    return GrBackendFormat::MakeGL(fRTFormat, GR_GL_TEXTURE_2D);
+}
+
 size_t GrGLRenderTarget::onGpuMemorySize() const {
     return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
                                   fNumSamplesOwnedPerPixel, GrMipMapped::kNo);
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index a9ec3c3..49f1631 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -36,6 +36,7 @@
 
     static sk_sp<GrGLRenderTarget> MakeWrapped(GrGLGpu*,
                                                const GrSurfaceDesc&,
+                                               GrGLenum format,
                                                const IDDesc&,
                                                int stencilBits);
 
@@ -63,6 +64,8 @@
 
     GrBackendRenderTarget getBackendRenderTarget() const override;
 
+    GrBackendFormat backendFormat() const override;
+
     bool canAttemptStencilAttachment() const override;
 
     // GrGLRenderTarget overrides dumpMemoryStatistics so it can log its texture and renderbuffer
@@ -71,9 +74,9 @@
 
 protected:
     // Constructor for subclasses.
-    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&);
+    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, GrGLenum format, const IDDesc&);
 
-    void init(const GrSurfaceDesc&, const IDDesc&);
+    void init(const GrSurfaceDesc&, GrGLenum format, const IDDesc&);
 
     void onAbandon() override;
     void onRelease() override;
@@ -82,7 +85,8 @@
 
 private:
     // Constructor for instances wrapping backend objects.
-    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrGLStencilAttachment*);
+    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, GrGLenum format, const IDDesc&,
+                     GrGLStencilAttachment*);
 
     void setFlags(const GrGLCaps&, const IDDesc&);
 
@@ -98,6 +102,7 @@
     GrGLuint    fRTFBOID;
     GrGLuint    fTexFBOID;
     GrGLuint    fMSColorRenderbufferID;
+    GrGLenum    fRTFormat;
 
     GrBackendObjectOwnership fRTFBOOwnership;
 
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 47878da..1f427ca 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -103,6 +103,11 @@
     return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), info);
 }
 
+GrBackendFormat GrGLTexture::backendFormat() const {
+    return GrBackendFormat::MakeGL(fFormat,
+                                   target_from_texture_type(this->texturePriv().textureType()));
+}
+
 sk_sp<GrGLTexture> GrGLTexture::MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
                                             GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc) {
     return sk_sp<GrGLTexture>(new GrGLTexture(gpu, kWrapped, desc, mipMapsStatus, idDesc));
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index 5f662e0..e5739fb 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -66,6 +66,8 @@
 
     GrBackendTexture getBackendTexture() const override;
 
+    GrBackendFormat backendFormat() const override;
+
     void textureParamsModified() override {
         fSamplerParams.invalidate();
         fNonSamplerParams.invalidate();
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.cpp b/src/gpu/gl/GrGLTextureRenderTarget.cpp
index a9d7f14..04f8ffc 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.cpp
+++ b/src/gpu/gl/GrGLTextureRenderTarget.cpp
@@ -20,7 +20,7 @@
                                                  GrMipMapsStatus mipMapsStatus)
         : GrSurface(gpu, desc)
         , GrGLTexture(gpu, desc, texIDDesc, mipMapsStatus)
-        , GrGLRenderTarget(gpu, desc, rtIDDesc) {
+        , GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
     this->registerWithCache(budgeted);
 }
 
@@ -31,7 +31,7 @@
                                                  GrMipMapsStatus mipMapsStatus)
         : GrSurface(gpu, desc)
         , GrGLTexture(gpu, desc, texIDDesc, mipMapsStatus)
-        , GrGLRenderTarget(gpu, desc, rtIDDesc) {
+        , GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
     this->registerWithCacheWrapped();
 }
 
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h
index 4a6cae0..f33ff28 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.h
+++ b/src/gpu/gl/GrGLTextureRenderTarget.h
@@ -39,6 +39,12 @@
                                                       const GrGLTexture::IDDesc& texIDDesc,
                                                       const GrGLRenderTarget::IDDesc& rtIDDesc,
                                                       GrMipMapsStatus);
+
+    GrBackendFormat backendFormat() const override {
+        // It doesn't matter if we take the texture or render target path, so just pick texture.
+        return GrGLTexture::backendFormat();
+    }
+
 protected:
     void onAbandon() override {
         GrGLRenderTarget::onAbandon();
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index c5459b2..d24afa5 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -9,6 +9,7 @@
 #define GrMockCaps_DEFINED
 
 #include "GrCaps.h"
+#include "SkGr.h"
 #include "mock/GrMockTypes.h"
 
 class GrMockCaps : public GrCaps {
@@ -125,15 +126,22 @@
         return true;
     }
 
+    GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
+                                                    GrSRGBEncoded srgbEncoded) const override {
+        GrPixelConfig config = GrColorTypeToPixelConfig(ct, srgbEncoded);
+        if (config == kUnknown_GrPixelConfig) {
+            return GrBackendFormat();
+        }
+        return GrBackendFormat::MakeMock(config);
+    }
+
 private:
-#ifdef GR_TEST_UTILS
     GrBackendFormat onCreateFormatFromBackendTexture(
             const GrBackendTexture& backendTex) const override {
         GrMockTextureInfo mockInfo;
         SkAssertResult(backendTex.getMockTextureInfo(&mockInfo));
         return GrBackendFormat::MakeMock(mockInfo.fConfig);
     }
-#endif
 
     static const int kMaxSampleCnt = 16;
 
diff --git a/src/gpu/mock/GrMockTexture.h b/src/gpu/mock/GrMockTexture.h
index c374dcb..ecb25c1 100644
--- a/src/gpu/mock/GrMockTexture.h
+++ b/src/gpu/mock/GrMockTexture.h
@@ -36,6 +36,10 @@
                                 fInfo);
     }
 
+    GrBackendFormat backendFormat() const override {
+        return GrBackendFormat::MakeMock(fInfo.fConfig);
+    }
+
     void textureParamsModified() override {}
     void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override {
         fReleaseHelper = std::move(releaseHelper);
@@ -114,6 +118,10 @@
         return {this->width(), this->height(), this->numColorSamples(), numStencilBits, fInfo};
     }
 
+    GrBackendFormat backendFormat() const override {
+        return GrBackendFormat::MakeMock(fInfo.fConfig);
+    }
+
 protected:
     // constructor for subclasses
     GrMockRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc,
@@ -153,6 +161,10 @@
     const GrTexture* asTexture() const override { return this; }
     const GrRenderTarget* asRenderTarget() const override { return this; }
 
+    GrBackendFormat backendFormat() const override {
+        return GrMockTexture::backendFormat();
+    }
+
 private:
     void onAbandon() override {
         GrRenderTarget::onAbandon();
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 6eb775c..7edfa79 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -90,6 +90,9 @@
         return false;
     }
 
+    GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
+                                                    GrSRGBEncoded srgbEncoded) const override;
+
     bool performPartialClearsAsDraws() const override {
         return true;
     }
@@ -102,9 +105,7 @@
     void initGrCaps(const id<MTLDevice> device);
     void initShaderCaps();
 
-#ifdef GR_TEST_UTILS
     GrBackendFormat onCreateFormatFromBackendTexture(const GrBackendTexture&) const override;
-#endif
 
     void initConfigTable();
 
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 3085811..ca3779b 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -414,7 +414,6 @@
     fPreferredStencilFormat = StencilFormat{ MTLPixelFormatStencil8, 8, 8, true };
 }
 
-#ifdef GR_TEST_UTILS
 GrBackendFormat GrMtlCaps::onCreateFormatFromBackendTexture(
         const GrBackendTexture& backendTex) const {
     GrMtlTextureInfo mtlInfo;
@@ -423,5 +422,17 @@
                                                 GrWrapOwnership::kBorrow_GrWrapOwnership);
     return GrBackendFormat::MakeMtl(mtlTexture.pixelFormat);
 }
-#endif
+
+GrBackendFormat GrMtlCaps::getBackendFormatFromGrColorType(GrColorType ct,
+                                                           GrSRGBEncoded srgbEncoded) const {
+    GrPixelConfig config = GrColorTypeToPixelConfig(ct, srgbEncoded);
+    if (config == kUnknown_GrPixelConfig) {
+        return GrBackendFormat();
+    }
+    MTLPixelFormat format;
+    if (!GrPixelConfigToMTLFormat(config, &format)) {
+        return GrBackendFormat();
+    }
+    return GrBackendFormat::MakeMtl(format);
+}
 
diff --git a/src/gpu/mtl/GrMtlRenderTarget.h b/src/gpu/mtl/GrMtlRenderTarget.h
index 12f7064..98fa8e0 100644
--- a/src/gpu/mtl/GrMtlRenderTarget.h
+++ b/src/gpu/mtl/GrMtlRenderTarget.h
@@ -43,6 +43,8 @@
 
     GrBackendRenderTarget getBackendRenderTarget() const override;
 
+    GrBackendFormat backendFormat() const override;
+
 protected:
     GrMtlRenderTarget(GrMtlGpu* gpu,
                       const GrSurfaceDesc& desc,
diff --git a/src/gpu/mtl/GrMtlRenderTarget.mm b/src/gpu/mtl/GrMtlRenderTarget.mm
index d14ff7c..59fd479 100644
--- a/src/gpu/mtl/GrMtlRenderTarget.mm
+++ b/src/gpu/mtl/GrMtlRenderTarget.mm
@@ -54,6 +54,10 @@
     return GrBackendRenderTarget(this->width(), this->height(), fRenderTexture.sampleCount, info);
 }
 
+GrBackendFormat GrMtlRenderTarget::backendFormat() const {
+    return GrBackendFormat::MakeMtl(fRenderTexture.pixelFormat);
+}
+
 GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const {
     SkASSERT(!this->wasDestroyed());
     return static_cast<GrMtlGpu*>(this->getGpu());
diff --git a/src/gpu/mtl/GrMtlTexture.h b/src/gpu/mtl/GrMtlTexture.h
index 2265b72..af51092 100644
--- a/src/gpu/mtl/GrMtlTexture.h
+++ b/src/gpu/mtl/GrMtlTexture.h
@@ -30,6 +30,8 @@
 
     GrBackendTexture getBackendTexture() const override;
 
+    GrBackendFormat backendFormat() const override;
+
     void textureParamsModified() override {}
 
     bool reallocForMipmap(GrMtlGpu* gpu, uint32_t mipLevels);
diff --git a/src/gpu/mtl/GrMtlTexture.mm b/src/gpu/mtl/GrMtlTexture.mm
index 7dd6f59..abe4faa 100644
--- a/src/gpu/mtl/GrMtlTexture.mm
+++ b/src/gpu/mtl/GrMtlTexture.mm
@@ -90,3 +90,7 @@
     return GrBackendTexture(this->width(), this->height(), mipMapped, info);
 }
 
+GrBackendFormat GrMtlTexture::backendFormat() const {
+    return GrBackendFormat::MakeMtl(fTexture.pixelFormat);
+}
+
diff --git a/src/gpu/mtl/GrMtlTextureRenderTarget.h b/src/gpu/mtl/GrMtlTextureRenderTarget.h
index dae3cbc..412af7b 100644
--- a/src/gpu/mtl/GrMtlTextureRenderTarget.h
+++ b/src/gpu/mtl/GrMtlTextureRenderTarget.h
@@ -22,6 +22,9 @@
     static sk_sp<GrMtlTextureRenderTarget> MakeWrappedTextureRenderTarget(GrMtlGpu*,
                                                                           const GrSurfaceDesc&,
                                                                           id<MTLTexture>);
+    GrBackendFormat backendFormat() const override {
+        return GrMtlTexture::backendFormat();
+    }
 
 protected:
     void onAbandon() override {
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index ff48510..57d8c14 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -390,8 +390,10 @@
     desc.fHeight = random->nextRangeU(1, 1000);
     GrSurfaceOrigin origin =
             random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     auto proxy = context->contextPriv().proxyProvider()->createProxy(
-            desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
+            format, desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
 
     do {
         if (random->nextBool()) {
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 215178c..0c75017 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -911,7 +911,11 @@
     SkASSERT(!args.fShape->isEmpty());
     SkASSERT(args.fShape->hasUnstyledKey());
     if (!fAtlas) {
+        const GrBackendFormat format =
+                args.fContext->contextPriv().caps()->getBackendFormatFromColorType(
+                        kAlpha_8_SkColorType);
         fAtlas = GrDrawOpAtlas::Make(args.fContext->contextPriv().proxyProvider(),
+                                     format,
                                      kAlpha_8_GrPixelConfig,
                                      ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
                                      NUM_PLOTS_X, NUM_PLOTS_Y,
@@ -998,8 +1002,10 @@
     if (context->uniqueID() != gTestStruct.fContextID) {
         gTestStruct.fContextID = context->uniqueID();
         gTestStruct.reset();
+        const GrBackendFormat format =
+                context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
         gTestStruct.fAtlas = GrDrawOpAtlas::Make(context->contextPriv().proxyProvider(),
-                                                 kAlpha_8_GrPixelConfig,
+                                                 format, kAlpha_8_GrPixelConfig,
                                                  ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
                                                  NUM_PLOTS_X, NUM_PLOTS_Y,
                                                  GrDrawOpAtlas::AllowMultitexturing::kYes,
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index d0d6c5f..0622dbc 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -714,8 +714,11 @@
         fit = random->nextBool() ? SkBackingFit::kApprox : SkBackingFit::kExact;
     }
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, origin, mipMapped, fit,
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format, desc, origin, mipMapped, fit,
                                                              SkBudgeted::kNo,
                                                              GrInternalSurfaceFlags::kNone);
 
diff --git a/src/gpu/text/GrAtlasManager.cpp b/src/gpu/text/GrAtlasManager.cpp
index 143f84d..486127d 100644
--- a/src/gpu/text/GrAtlasManager.cpp
+++ b/src/gpu/text/GrAtlasManager.cpp
@@ -35,6 +35,21 @@
     }
 }
 
+static SkColorType mask_format_to_color_type(GrMaskFormat format) {
+    switch (format) {
+        case kA8_GrMaskFormat:
+            return kAlpha_8_SkColorType;
+        case kA565_GrMaskFormat:
+            return kRGB_565_SkColorType;
+        case kARGB_GrMaskFormat:
+            return kRGBA_8888_SkColorType;
+        default:
+            SkDEBUGFAIL("unsupported GrMaskFormat");
+            return kAlpha_8_SkColorType;
+    }
+
+}
+
 void GrAtlasManager::freeAll() {
     for (int i = 0; i < kMaskFormatCount; ++i) {
         fAtlases[i] = nullptr;
@@ -161,11 +176,14 @@
     int index = MaskFormatToAtlasIndex(format);
     if (fAtlases[index] == nullptr) {
         GrPixelConfig config = mask_format_to_pixel_config(format);
+        SkColorType colorType = mask_format_to_color_type(format);
         SkISize atlasDimensions = fAtlasConfigs.atlasDimensions(format);
         SkISize numPlots = fAtlasConfigs.numPlots(format);
 
+        const GrBackendFormat format = fCaps->getBackendFormatFromColorType(colorType);
+
         fAtlases[index] = GrDrawOpAtlas::Make(
-                fProxyProvider, config, atlasDimensions.width(), atlasDimensions.height(),
+                fProxyProvider, format, config, atlasDimensions.width(), atlasDimensions.height(),
                 numPlots.width(), numPlots.height(), fAllowMultitexturing,
                 &GrGlyphCache::HandleEviction, fGlyphCache);
         if (!fAtlases[index]) {
diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp
index ee8f1d00..acb01d7 100644
--- a/src/gpu/text/GrTextContext.cpp
+++ b/src/gpu/text/GrTextContext.cpp
@@ -214,9 +214,12 @@
         gTextContext = GrTextContext::Make(GrTextContext::Options());
     }
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     // Setup dummy SkPaint / GrPaint / GrRenderTargetContext
     sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeDeferredRenderTargetContext(
-        SkBackingFit::kApprox, 1024, 1024, kRGBA_8888_GrPixelConfig, nullptr));
+        format, SkBackingFit::kApprox, 1024, 1024, kRGBA_8888_GrPixelConfig, nullptr));
 
     SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
 
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 01cad06..6f4cb8d 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -12,6 +12,7 @@
 #include "GrShaderCaps.h"
 #include "GrVkInterface.h"
 #include "GrVkUtil.h"
+#include "SkGr.h"
 #include "vk/GrVkBackendContext.h"
 #include "vk/GrVkExtensions.h"
 
@@ -823,12 +824,23 @@
     return get_yuva_config(*vkFormat, config);
 }
 
-#ifdef GR_TEST_UTILS
 GrBackendFormat GrVkCaps::onCreateFormatFromBackendTexture(
         const GrBackendTexture& backendTex) const {
     GrVkImageInfo vkInfo;
     SkAssertResult(backendTex.getVkImageInfo(&vkInfo));
     return GrBackendFormat::MakeVk(vkInfo.fFormat);
 }
-#endif
+
+GrBackendFormat GrVkCaps::getBackendFormatFromGrColorType(GrColorType ct,
+                                                          GrSRGBEncoded srgbEncoded) const {
+    GrPixelConfig config = GrColorTypeToPixelConfig(ct, srgbEncoded);
+    if (config == kUnknown_GrPixelConfig) {
+        return GrBackendFormat();
+    }
+    VkFormat format;
+    if (!GrPixelConfigToVkFormat(config, &format)) {
+        return GrBackendFormat();
+    }
+    return GrBackendFormat::MakeVk(format);
+}
 
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 0154c0b..0b1243a 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -165,6 +165,9 @@
     bool getYUVAConfigFromBackendFormat(const GrBackendFormat&,
                                         GrPixelConfig*) const override;
 
+    GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct,
+                                                    GrSRGBEncoded srgbEncoded) const override;
+
 private:
     enum VkVendor {
         kAMD_VkVendor = 4098,
@@ -185,9 +188,7 @@
                     const GrVkExtensions&);
     void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&);
 
-#ifdef GR_TEST_UTILS
     GrBackendFormat onCreateFormatFromBackendTexture(const GrBackendTexture&) const override;
-#endif
 
     void initConfigTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
     void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
diff --git a/src/gpu/vk/GrVkImage.h b/src/gpu/vk/GrVkImage.h
index 7381e63..5240250 100644
--- a/src/gpu/vk/GrVkImage.h
+++ b/src/gpu/vk/GrVkImage.h
@@ -10,6 +10,7 @@
 
 #include "GrVkResource.h"
 
+#include "GrBackendSurface.h"
 #include "GrTypesPriv.h"
 #include "GrVkImageLayout.h"
 #include "SkTypes.h"
@@ -42,6 +43,9 @@
     VkImage image() const { return fInfo.fImage; }
     const GrVkAlloc& alloc() const { return fInfo.fAlloc; }
     VkFormat imageFormat() const { return fInfo.fFormat; }
+    GrBackendFormat getBackendFormat() const {
+        return GrBackendFormat::MakeVk(this->imageFormat());
+    }
     uint32_t mipLevels() const { return fInfo.fLevelCount; }
     const Resource* resource() const { return fResource; }
     bool isLinearTiled() const {
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index 2438a90..33f4949 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -37,6 +37,8 @@
 
     ~GrVkRenderTarget() override;
 
+    GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
+
     const GrVkFramebuffer* framebuffer() const { return fFramebuffer; }
     const GrVkImageView* colorAttachmentView() const { return fColorAttachmentView; }
     const GrVkResource* msaaImageResource() const {
diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h
index 9c6b7b1..69e4553 100644
--- a/src/gpu/vk/GrVkTexture.h
+++ b/src/gpu/vk/GrVkTexture.h
@@ -31,6 +31,8 @@
 
     GrBackendTexture getBackendTexture() const override;
 
+    GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
+
     void textureParamsModified() override {}
 
     const GrVkImageView* textureView();
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h
index bd3973c..dc4dc92 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.h
+++ b/src/gpu/vk/GrVkTextureRenderTarget.h
@@ -38,6 +38,8 @@
 
     bool updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo);
 
+    GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
+
 protected:
     void onAbandon() override {
         GrVkRenderTarget::onAbandon();
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index b8aa1a5..600ba39 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -155,10 +155,13 @@
     const int width = imageSize.width();
     const int height = imageSize.height();
 
+    const GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     // Needs to create a render target in order to draw to it for the yuv->rgb conversion.
     sk_sp<GrRenderTargetContext> renderTargetContext(
             ctx->contextPriv().makeDeferredRenderTargetContext(
-                    SkBackingFit::kExact, width, height, kRGBA_8888_GrPixelConfig,
+                    format, SkBackingFit::kExact, width, height, kRGBA_8888_GrPixelConfig,
                     std::move(imageColorSpace), 1, GrMipMapped::kNo, imageOrigin));
     if (!renderTargetContext) {
         return nullptr;
@@ -312,13 +315,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-static GrTextureType TextureTypeFromBackendFormat(const GrBackendFormat& backendFormat) {
-    if (const GrGLenum* target = backendFormat.getGLTarget()) {
-        return GrGLTexture::TextureTypeFromTarget(*target);
-    }
-    return GrTextureType::k2D;
-}
-
 sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
                                                const GrBackendFormat& backendFormat,
                                                int width,
@@ -363,9 +359,8 @@
         return nullptr;
     }
 
-    GrTextureType textureType = TextureTypeFromBackendFormat(backendFormat);
-
-    if (mipMapped == GrMipMapped::kYes && GrTextureTypeHasRestrictedSampling(textureType)) {
+    if (mipMapped == GrMipMapped::kYes &&
+        GrTextureTypeHasRestrictedSampling(backendFormat.textureType())) {
         // It is invalid to have a GL_TEXTURE_EXTERNAL or GL_TEXTURE_RECTANGLE and have mips as
         // well.
         return nullptr;
@@ -387,7 +382,7 @@
 
                 return promiseHelper.getTexture(resourceProvider, config);
             },
-            desc, origin, mipMapped, textureType, GrInternalSurfaceFlags::kNone,
+            backendFormat, desc, origin, mipMapped, GrInternalSurfaceFlags::kNone,
             SkBackingFit::kExact, SkBudgeted::kNo,
             GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
 
@@ -537,7 +532,8 @@
                 return sk_ref_sp<GrTexture>(tmp->getTexture());
 #endif
             },
-            desc, imageOrigin, GrMipMapped::kNo, GrTextureType::k2D,
+            yuvaFormats[yuvaIndices[SkYUVAIndex::kY_Index].fIndex],
+            desc, imageOrigin, GrMipMapped::kNo,
             GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo,
             GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
 
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index 8360361..4dfc483 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -100,8 +100,13 @@
     desc.fHeight = subset.height();
     desc.fConfig = proxy->config();
 
+    GrBackendFormat format = proxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrSurfaceContext> sContext(fContext->contextPriv().makeDeferredSurfaceContext(
-        desc, proxy->origin(), GrMipMapped::kNo, SkBackingFit::kExact, fBudgeted));
+        format, desc, proxy->origin(), GrMipMapped::kNo, SkBackingFit::kExact, fBudgeted));
     if (!sContext) {
         return nullptr;
     }
@@ -253,9 +258,15 @@
 
     sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef();
 
+    GrBackendFormat format = proxy->backendFormat().makeTexture2D();
+    if (!format.isValid()) {
+        return nullptr;
+    }
+
     sk_sp<GrRenderTargetContext> renderTargetContext(
         fContext->contextPriv().makeDeferredRenderTargetContextWithFallback(
-            SkBackingFit::kExact, this->width(), this->height(), proxy->config(), nullptr));
+            format, SkBackingFit::kExact, this->width(), this->height(),
+            proxy->config(), nullptr));
     if (!renderTargetContext) {
         return nullptr;
     }
diff --git a/src/image/SkImage_GpuYUVA.cpp b/src/image/SkImage_GpuYUVA.cpp
index ab13835..a1d0696 100644
--- a/src/image/SkImage_GpuYUVA.cpp
+++ b/src/image/SkImage_GpuYUVA.cpp
@@ -78,11 +78,14 @@
 
 sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef() const {
     if (!fRGBProxy) {
+        const GrBackendFormat format =
+            fContext->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
         // Needs to create a render target in order to draw to it for the yuv->rgb conversion.
         sk_sp<GrRenderTargetContext> renderTargetContext(
             fContext->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kExact, this->width(), this->height(), kRGBA_8888_GrPixelConfig,
-                fColorSpace, 1, GrMipMapped::kNo, fOrigin));
+                format, SkBackingFit::kExact, this->width(), this->height(),
+                kRGBA_8888_GrPixelConfig, fColorSpace, 1, GrMipMapped::kNo, fOrigin));
         if (!renderTargetContext) {
             return nullptr;
         }
@@ -242,8 +245,8 @@
         desc.fConfig = params.fConfig;
         desc.fSampleCnt = 1;
         proxies[texIdx] = proxyProvider->createLazyProxy(
-                            std::move(lazyInstCallback), desc, imageOrigin, GrMipMapped::kNo,
-                            GrTextureType::k2D, GrInternalSurfaceFlags::kNone,
+                            std::move(lazyInstCallback), yuvaFormats[texIdx], desc, imageOrigin,
+                            GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
                             SkBackingFit::kExact, SkBudgeted::kNo,
                             GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
         if (!proxies[texIdx]) {
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index bd219c6..fef4bf4 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -418,6 +418,11 @@
     //    the texture we fall through here and have the CPU generate the mip maps for us.
     if (!proxy && !willBeMipped && !ctx->contextPriv().disableGpuYUVConversion()) {
         const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(fInfo);
+
+        SkColorType colorType = fInfo.colorType();
+        GrBackendFormat format =
+                ctx->contextPriv().caps()->getBackendFormatFromColorType(colorType);
+
         ScopedGenerator generator(fSharedGenerator);
         Generator_GrYUVProvider provider(generator);
 
@@ -429,7 +434,7 @@
 
         // TODO: Update to create the mipped surface in the YUV generator and draw the base
         // layer directly into the mipped surface.
-        proxy = provider.refAsTextureProxy(ctx, desc, generatorColorSpace, thisColorSpace);
+        proxy = provider.refAsTextureProxy(ctx, format, desc, generatorColorSpace, thisColorSpace);
         if (proxy) {
             SK_HISTOGRAM_ENUMERATION("LockTexturePath", kYUV_LockTexturePath,
                                      kLockTexturePathCount);
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 9c04ac2..af0b564 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -300,8 +300,11 @@
     desc.fConfig = c.config();
     desc.fSampleCnt = c.stencilCount();
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(c.colorType());
+
     sk_sp<GrSurfaceContext> sc(
-            context->contextPriv().makeDeferredSurfaceContext(desc, c.origin(),
+            context->contextPriv().makeDeferredSurfaceContext(format, desc, c.origin(),
                                                               GrMipMapped(c.isMipMapped()),
                                                               SkBackingFit::kExact, budgeted,
                                                               c.refColorSpace(),
diff --git a/tests/ClearTest.cpp b/tests/ClearTest.cpp
index d9271fc..c4809f5 100644
--- a/tests/ClearTest.cpp
+++ b/tests/ClearTest.cpp
@@ -56,8 +56,10 @@
 }
 
 sk_sp<GrRenderTargetContext> newRTC(GrContext* context, int w, int h) {
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     return context->contextPriv().makeDeferredRenderTargetContext(
-                                                                SkBackingFit::kExact, w, h,
+                                                                format, SkBackingFit::kExact, w, h,
                                                                 kRGBA_8888_GrPixelConfig, nullptr);
 }
 
diff --git a/tests/DefaultPathRendererTest.cpp b/tests/DefaultPathRendererTest.cpp
index f78c283..688ecee 100644
--- a/tests/DefaultPathRendererTest.cpp
+++ b/tests/DefaultPathRendererTest.cpp
@@ -79,8 +79,11 @@
 
     GrStyle style(SkStrokeRec::kFill_InitStyle);
 
+    GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     {
         auto rtc =  ctx->contextPriv().makeDeferredRenderTargetContext(
+                                                         format,
                                                          SkBackingFit::kApprox,
                                                          kBigSize/2+1, kBigSize/2+1,
                                                          kRGBA_8888_GrPixelConfig, nullptr);
@@ -101,8 +104,9 @@
 
     {
         auto rtc = ctx->contextPriv().makeDeferredRenderTargetContext(
-                                                        SkBackingFit::kExact, kBigSize, kBigSize,
-                                                        kRGBA_8888_GrPixelConfig, nullptr);
+                                                        format, SkBackingFit::kExact, kBigSize,
+                                                        kBigSize, kRGBA_8888_GrPixelConfig,
+                                                        nullptr);
 
         rtc->clear(nullptr, { 0, 0, 0, 1 }, GrRenderTargetContext::CanClearFullscreen::kYes);
 
diff --git a/tests/DetermineDomainModeTest.cpp b/tests/DetermineDomainModeTest.cpp
index c40a957..907e535 100644
--- a/tests/DetermineDomainModeTest.cpp
+++ b/tests/DetermineDomainModeTest.cpp
@@ -118,10 +118,11 @@
 
 };
 
-static sk_sp<GrTextureProxy> create_proxy(GrProxyProvider* proxyProvider,
+static sk_sp<GrTextureProxy> create_proxy(GrContext* ctx,
                                           bool isPowerOfTwo,
                                           bool isExact,
                                           RectInfo* rect) {
+    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
     int size = isPowerOfTwo ? 128 : 100;
     SkBackingFit fit = isExact ? SkBackingFit::kExact : SkBackingFit::kApprox;
 
@@ -130,6 +131,9 @@
     desc.fHeight = size;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
+    GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     static const char* name = "proxy";
 
     // Proxies are always hard on the left and top but can be bad on the right and bottom
@@ -140,7 +144,8 @@
               (isPowerOfTwo || isExact) ? RectInfo::kHard : RectInfo::kBad,
               name);
 
-    return proxyProvider->createProxy(desc, kTopLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
+    return proxyProvider->createProxy(format, desc, kTopLeft_GrSurfaceOrigin, fit,
+                                      SkBudgeted::kYes);
 }
 
 static RectInfo::EdgeType compute_inset_edgetype(RectInfo::EdgeType previous,
@@ -313,7 +318,7 @@
                          insetAmount, halfFilterWidth, 0, name);
 }
 
-static void proxy_test(skiatest::Reporter* reporter, GrProxyProvider* proxyProvider) {
+static void proxy_test(skiatest::Reporter* reporter, GrContext* context) {
     GrTextureProducer_TestAccess::DomainMode actualMode, expectedMode;
     SkRect actualDomainRect;
 
@@ -332,7 +337,7 @@
         for (auto isExact : { true, false }) {
             RectInfo outermost;
 
-            sk_sp<GrTextureProxy> proxy = create_proxy(proxyProvider, isPowerOfTwoSized,
+            sk_sp<GrTextureProxy> proxy = create_proxy(context, isPowerOfTwoSized,
                                                        isExact, &outermost);
             SkASSERT(outermost.isHardOrBadAllAround());
 
@@ -386,5 +391,5 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DetermineDomainModeTest, reporter, ctxInfo) {
     GrContext* context = ctxInfo.grContext();
 
-    proxy_test(reporter, context->contextPriv().proxyProvider());
+    proxy_test(reporter, context);
 }
diff --git a/tests/DrawOpAtlasTest.cpp b/tests/DrawOpAtlasTest.cpp
index 251403d..10bc51d 100644
--- a/tests/DrawOpAtlasTest.cpp
+++ b/tests/DrawOpAtlasTest.cpp
@@ -135,8 +135,12 @@
     GrOnFlushResourceProvider onFlushResourceProvider(drawingManager);
     TestingUploadTarget uploadTarget;
 
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
+
     std::unique_ptr<GrDrawOpAtlas> atlas = GrDrawOpAtlas::Make(
                                                 proxyProvider,
+                                                format,
                                                 kAlpha_8_GrPixelConfig,
                                                 kAtlasSize, kAtlasSize,
                                                 kNumPlots, kNumPlots,
@@ -184,7 +188,11 @@
     auto textContext = drawingManager->getTextContext();
     auto opMemoryPool = context->contextPriv().opMemoryPool();
 
-    auto rtc =  context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kApprox,
+    GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
+    auto rtc =  context->contextPriv().makeDeferredRenderTargetContext(format,
+                                                                       SkBackingFit::kApprox,
                                                                        32, 32,
                                                                        kRGBA_8888_GrPixelConfig,
                                                                        nullptr);
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 654dce0..c2dd572 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -154,8 +154,11 @@
     // Above could be 0 if msaa isn't supported.
     sampleCnt = SkTMax(1, sampleCnt);
 
+    const GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTargetContext> renderTargetContext(
-        context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
+        context->contextPriv().makeDeferredRenderTargetContext(format,
+                                                               SkBackingFit::kExact,
                                                                kRenderTargetWidth,
                                                                kRenderTargetHeight,
                                                                kRGBA_8888_GrPixelConfig,
@@ -265,7 +268,9 @@
         dummyDesc.fWidth = 34;
         dummyDesc.fHeight = 18;
         dummyDesc.fConfig = kRGBA_8888_GrPixelConfig;
-        proxies[0] = proxyProvider->createProxy(dummyDesc, kBottomLeft_GrSurfaceOrigin,
+        const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+        proxies[0] = proxyProvider->createProxy(format, dummyDesc, kBottomLeft_GrSurfaceOrigin,
                                                 GrMipMapped::kYes, SkBackingFit::kExact,
                                                 SkBudgeted::kNo, GrInternalSurfaceFlags::kNone);
     }
@@ -275,7 +280,9 @@
         dummyDesc.fWidth = 16;
         dummyDesc.fHeight = 22;
         dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
-        proxies[1] = proxyProvider->createProxy(dummyDesc, kTopLeft_GrSurfaceOrigin,
+        const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
+        proxies[1] = proxyProvider->createProxy(format, dummyDesc, kTopLeft_GrSurfaceOrigin,
                                                 GrMipMapped::kYes, SkBackingFit::kExact,
                                                 SkBudgeted::kNo, GrInternalSurfaceFlags::kNone);
     }
@@ -308,9 +315,12 @@
     // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
     drawingManager->flush(nullptr);
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     // Validate that GrFPs work correctly without an input.
     sk_sp<GrRenderTargetContext> renderTargetContext(
-                 context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kExact,
+                 context->contextPriv().makeDeferredRenderTargetContext(format,
+                                                                        SkBackingFit::kExact,
                                                                         kRenderTargetWidth,
                                                                         kRenderTargetHeight,
                                                                         kRGBA_8888_GrPixelConfig,
diff --git a/tests/GrCCPRTest.cpp b/tests/GrCCPRTest.cpp
index 946fde6..a400985 100644
--- a/tests/GrCCPRTest.cpp
+++ b/tests/GrCCPRTest.cpp
@@ -60,9 +60,9 @@
             : fCtx(ctx)
             , fCCPR(fCtx->contextPriv().drawingManager()->getCoverageCountingPathRenderer())
             , fRTC(fCtx->contextPriv().makeDeferredRenderTargetContext(
-                                                         SkBackingFit::kExact, kCanvasSize,
-                                                         kCanvasSize, kRGBA_8888_GrPixelConfig,
-                                                         nullptr))
+                ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType),
+                SkBackingFit::kExact, kCanvasSize, kCanvasSize, kRGBA_8888_GrPixelConfig,
+                nullptr))
             , fDoStroke(doStroke) {
         if (!fCCPR) {
             ERRORF(reporter, "ccpr not enabled in GrContext for ccpr tests");
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index ec19d16..0cf91e6 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -83,9 +83,12 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrMeshTest, reporter, ctxInfo) {
     GrContext* context = ctxInfo.grContext();
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeDeferredRenderTargetContext(
-                                                 SkBackingFit::kExact, kImageWidth, kImageHeight,
-                                                 kRGBA_8888_GrPixelConfig, nullptr));
+                                                 format, SkBackingFit::kExact, kImageWidth,
+                                                 kImageHeight, kRGBA_8888_GrPixelConfig, nullptr));
     if (!rtc) {
         ERRORF(reporter, "could not create render target context.");
         return;
diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp
index cae0b2b..f77dec7 100644
--- a/tests/GrPipelineDynamicStateTest.cpp
+++ b/tests/GrPipelineDynamicStateTest.cpp
@@ -161,9 +161,12 @@
     GrContext* context = ctxInfo.grContext();
     GrResourceProvider* rp = context->contextPriv().resourceProvider();
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeDeferredRenderTargetContext(
-                                                 SkBackingFit::kExact, kScreenSize, kScreenSize,
-                                                 kRGBA_8888_GrPixelConfig, nullptr));
+                                                 format, SkBackingFit::kExact, kScreenSize,
+                                                 kScreenSize, kRGBA_8888_GrPixelConfig, nullptr));
     if (!rtc) {
         ERRORF(reporter, "could not create render target context.");
         return;
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index bdec795..d3cc2f4 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -112,8 +112,13 @@
             REPORTER_ASSERT(reporter, SkToBool(tex) == ict,
                             "config:%d, tex:%d, isConfigTexturable:%d", config, SkToBool(tex), ict);
 
+            GrSRGBEncoded srgbEncoded = GrSRGBEncoded::kNo;
+            GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(config, &srgbEncoded);
+            const GrBackendFormat format =
+                    caps->getBackendFormatFromGrColorType(colorType, srgbEncoded);
+
             sk_sp<GrTextureProxy> proxy =
-                    proxyProvider->createMipMapProxy(desc, origin, SkBudgeted::kNo);
+                    proxyProvider->createMipMapProxy(format, desc, origin, SkBudgeted::kNo);
             REPORTER_ASSERT(reporter, SkToBool(proxy.get()) ==
                             (caps->isConfigTexturable(desc.fConfig) &&
                              caps->mipMapSupport()));
@@ -146,16 +151,17 @@
     std::unique_ptr<uint32_t[]> data(new uint32_t[kSize * kSize]);
 
     GrContext* context = context_info.grContext();
+    const GrCaps* caps = context->contextPriv().caps();
     GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
 
     for (int c = 0; c <= kLast_GrPixelConfig; ++c) {
         desc.fConfig = static_cast<GrPixelConfig>(c);
-        if (!context->contextPriv().caps()->isConfigTexturable(desc.fConfig)) {
+        if (!caps->isConfigTexturable(desc.fConfig)) {
             continue;
         }
         desc.fFlags = kPerformInitialClear_GrSurfaceFlag;
         for (bool rt : {false, true}) {
-            if (rt && !context->contextPriv().caps()->isConfigRenderable(desc.fConfig)) {
+            if (rt && !caps->isConfigRenderable(desc.fConfig)) {
                 continue;
             }
             desc.fFlags |= rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
@@ -193,10 +199,16 @@
                     }
                     context->contextPriv().purgeAllUnlockedResources_ForTesting();
 
+                    GrSRGBEncoded srgbEncoded = GrSRGBEncoded::kNo;
+                    GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(desc.fConfig,
+                                                                                &srgbEncoded);
+                    const GrBackendFormat format =
+                            caps->getBackendFormatFromGrColorType(colorType, srgbEncoded);
+
                     // Try creating the texture as a deferred proxy.
                     for (int i = 0; i < 2; ++i) {
                         auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
-                                desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes);
+                                format, desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes);
                         if (!surfCtx) {
                             continue;
                         }
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index 16653e2..82cf29d 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -377,7 +377,9 @@
 
 static sk_sp<SkSpecialSurface> create_empty_special_surface(GrContext* context, int widthHeight) {
     if (context) {
-        return SkSpecialSurface::MakeRenderTarget(context,
+        GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+        return SkSpecialSurface::MakeRenderTarget(context, format,
                                                   widthHeight, widthHeight,
                                                   kRGBA_8888_GrPixelConfig, nullptr);
     } else {
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index 25ba767..d7aeb53 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -61,7 +61,7 @@
                                               bool nullTexture) {
             GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
 
-            return pool->allocate<Op>(proxyProvider, test, nullTexture);
+            return pool->allocate<Op>(context, proxyProvider, test, nullTexture);
         }
 
         void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
@@ -76,8 +76,10 @@
     private:
         friend class GrOpMemoryPool; // for ctor
 
-        Op(GrProxyProvider* proxyProvider, LazyProxyTest* test, bool nullTexture)
+        Op(GrContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test, bool nullTexture)
                     : GrDrawOp(ClassID()), fTest(test) {
+            const GrBackendFormat format =
+                    ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGB_565_SkColorType);
             fProxy = GrProxyProvider::MakeFullyLazyProxy(
                     [this, nullTexture](GrResourceProvider* rp) {
                         if (!rp) {
@@ -97,7 +99,7 @@
                             return texture;
                         }
                     },
-                    GrProxyProvider::Renderable::kNo, kTopLeft_GrSurfaceOrigin,
+                    format, GrProxyProvider::Renderable::kNo, kTopLeft_GrSurfaceOrigin,
                     kRGB_565_GrPixelConfig, *proxyProvider->caps());
 
             this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo,
@@ -117,11 +119,16 @@
 
     class ClipFP : public GrFragmentProcessor {
     public:
-        ClipFP(GrProxyProvider* proxyProvider, LazyProxyTest* test, GrTextureProxy* atlas)
+        ClipFP(GrContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test,
+               GrTextureProxy* atlas)
                 : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
+                , fContext(ctx)
                 , fProxyProvider(proxyProvider)
                 , fTest(test)
                 , fAtlas(atlas) {
+            const GrBackendFormat format =
+                ctx->contextPriv().caps()->getBackendFormatFromGrColorType(GrColorType::kAlpha_F16,
+                                                                           GrSRGBEncoded::kNo);
             fLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
                                 [this](GrResourceProvider* rp) {
                                     if (!rp) {
@@ -132,6 +139,7 @@
                                     fAtlas->instantiate(rp);
                                     return sk_ref_sp(fAtlas->peekTexture());
                                 },
+                                format,
                                 GrProxyProvider::Renderable::kYes,
                                 kBottomLeft_GrSurfaceOrigin,
                                 kAlpha_half_GrPixelConfig, *proxyProvider->caps());
@@ -143,13 +151,14 @@
     private:
         const char* name() const override { return "LazyProxyTest::ClipFP"; }
         std::unique_ptr<GrFragmentProcessor> clone() const override {
-            return skstd::make_unique<ClipFP>(fProxyProvider, fTest, fAtlas);
+            return skstd::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas);
         }
         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
         bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
         const TextureSampler& onTextureSampler(int) const override { return fAccess; }
 
+        GrContext* const fContext;
         GrProxyProvider* const fProxyProvider;
         LazyProxyTest* const fTest;
         GrTextureProxy* const fAtlas;
@@ -168,7 +177,7 @@
         bool apply(GrContext* context, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
                    SkRect* bounds) const override {
             GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
-            out->addCoverageFP(skstd::make_unique<ClipFP>(proxyProvider, fTest, fAtlas));
+            out->addCoverageFP(skstd::make_unique<ClipFP>(context, proxyProvider, fTest, fAtlas));
             return true;
         }
         bool quickContains(const SkRect&) const final { return false; }
@@ -200,12 +209,17 @@
     for (bool nullTexture : {false, true}) {
         LazyProxyTest test(reporter);
         ctx->contextPriv().addOnFlushCallbackObject(&test);
+        GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
         sk_sp<GrRenderTargetContext> rtc = ctx->contextPriv().makeDeferredRenderTargetContext(
-                                                             SkBackingFit::kExact, 100, 100,
+                                                             format, SkBackingFit::kExact, 100, 100,
                                                              kRGBA_8888_GrPixelConfig, nullptr);
         REPORTER_ASSERT(reporter, rtc);
+        format =
+                ctx->contextPriv().caps()->getBackendFormatFromGrColorType(GrColorType::kAlpha_F16,
+                                                                           GrSRGBEncoded::kNo);
         sk_sp<GrRenderTargetContext> mockAtlas = ctx->contextPriv().makeDeferredRenderTargetContext(
-                                                     SkBackingFit::kExact, 10, 10,
+                                                     format, SkBackingFit::kExact, 10, 10,
                                                      kAlpha_half_GrPixelConfig, nullptr);
         REPORTER_ASSERT(reporter, mockAtlas);
         rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
@@ -226,6 +240,9 @@
     desc.fHeight = kSize;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
+    GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
     for (bool doInstantiate : {true, false}) {
         for (auto lazyType : {LazyInstantiationType::kSingleUse,
@@ -242,7 +259,7 @@
                         *testCountPtr = 1;
                         return sk_sp<GrTexture>();
                     },
-                    desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrTextureType::k2D,
+                    format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
                     GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
 
             REPORTER_ASSERT(reporter, proxy.get());
@@ -277,7 +294,7 @@
                                           bool shouldFailInstantiation) {
         GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
 
-        return pool->allocate<LazyFailedInstantiationTestOp>(proxyProvider,
+        return pool->allocate<LazyFailedInstantiationTestOp>(context, proxyProvider,
                                                              testExecuteValue,
                                                              shouldFailInstantiation);
     }
@@ -289,14 +306,16 @@
 private:
     friend class GrOpMemoryPool; // for ctor
 
-    LazyFailedInstantiationTestOp(GrProxyProvider* proxyProvider, int* testExecuteValue,
-                                  bool shouldFailInstantiation)
+    LazyFailedInstantiationTestOp(GrContext* ctx, GrProxyProvider* proxyProvider,
+                                  int* testExecuteValue, bool shouldFailInstantiation)
             : INHERITED(ClassID())
             , fTestExecuteValue(testExecuteValue) {
         GrSurfaceDesc desc;
         desc.fWidth = kSize;
         desc.fHeight = kSize;
         desc.fConfig = kRGBA_8888_GrPixelConfig;
+        GrBackendFormat format =
+                ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
 
         fLazyProxy = proxyProvider->createLazyProxy(
                 [testExecuteValue, shouldFailInstantiation, desc](GrResourceProvider* rp) {
@@ -309,7 +328,7 @@
                     }
                     return rp->createTexture(desc, SkBudgeted::kNo);
                 },
-                desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrTextureType::k2D,
+                format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
                 SkBackingFit::kExact, SkBudgeted::kNo);
 
         SkASSERT(fLazyProxy.get());
@@ -341,9 +360,11 @@
     sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
     GrResourceProvider* resourceProvider = ctx->contextPriv().resourceProvider();
     GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
+    GrBackendFormat format =
+                ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     for (bool failInstantiation : {false, true}) {
         sk_sp<GrRenderTargetContext> rtc = ctx->contextPriv().makeDeferredRenderTargetContext(
-                                                     SkBackingFit::kExact, 100, 100,
+                                                     format, SkBackingFit::kExact, 100, 100,
                                                      kRGBA_8888_GrPixelConfig, nullptr);
         REPORTER_ASSERT(reporter, rtc);
 
@@ -417,10 +438,13 @@
     GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
     GrGpu* gpu = ctx->contextPriv().getGpu();
 
+    GrBackendFormat format =
+                ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     using LazyType = GrSurfaceProxy::LazyInstantiationType;
     for (auto lazyType : {LazyType::kSingleUse, LazyType::kMultipleUse, LazyType::kUninstantiate}) {
         sk_sp<GrRenderTargetContext> rtc = ctx->contextPriv().makeDeferredRenderTargetContext(
-                SkBackingFit::kExact, 100, 100,
+                format, SkBackingFit::kExact, 100, 100,
                 kRGBA_8888_GrPixelConfig, nullptr);
         REPORTER_ASSERT(reporter, rtc);
 
@@ -453,7 +477,7 @@
                     texture->setRelease(UninstantiateReleaseProc, releasePtr);
                     return texture;
                 },
-                desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrTextureType::k2D,
+                format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
                 GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
 
         REPORTER_ASSERT(reporter, lazyProxy.get());
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index ac9805e..805be6a 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -292,11 +292,13 @@
 
     // Get the fully lazy proxy that is backing the atlas. Its actual width isn't
     // known until flush time.
-    sk_sp<GrTextureProxy> getAtlasProxy(GrProxyProvider* proxyProvider) {
+    sk_sp<GrTextureProxy> getAtlasProxy(GrProxyProvider* proxyProvider, const GrCaps* caps) {
         if (fAtlasProxy) {
             return fAtlasProxy;
         }
 
+        const GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
         fAtlasProxy = GrProxyProvider::MakeFullyLazyProxy(
                 [](GrResourceProvider* resourceProvider) {
                     if (!resourceProvider) {
@@ -314,6 +316,7 @@
                     return resourceProvider->createTexture(desc, SkBudgeted::kYes,
                                                            GrResourceProvider::Flags::kNoPendingIO);
                 },
+                format,
                 GrProxyProvider::Renderable::kYes,
                 kBottomLeft_GrSurfaceOrigin,
                 kRGBA_8888_GrPixelConfig,
@@ -426,7 +429,11 @@
 // This creates an off-screen rendertarget whose ops which eventually pull from the atlas.
 static sk_sp<GrTextureProxy> make_upstream_image(GrContext* context, AtlasObject* object, int start,
                                                  sk_sp<GrTextureProxy> atlasProxy) {
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeDeferredRenderTargetContext(
+                                                                      format,
                                                                       SkBackingFit::kApprox,
                                                                       3*kDrawnTileSize,
                                                                       kDrawnTileSize,
@@ -537,13 +544,18 @@
     sk_sp<GrTextureProxy> proxies[kNumProxies];
     for (int i = 0; i < kNumProxies; ++i) {
         proxies[i] = make_upstream_image(context, &object, i*3,
-                                         object.getAtlasProxy(proxyProvider));
+                                         object.getAtlasProxy(proxyProvider,
+                                                              context->contextPriv().caps()));
     }
 
     static const int kFinalWidth = 6*kDrawnTileSize;
     static const int kFinalHeight = kDrawnTileSize;
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeDeferredRenderTargetContext(
+                                                                      format,
                                                                       SkBackingFit::kApprox,
                                                                       kFinalWidth,
                                                                       kFinalHeight,
diff --git a/tests/OpChainTest.cpp b/tests/OpChainTest.cpp
index e2d6769..3ad8543 100644
--- a/tests/OpChainTest.cpp
+++ b/tests/OpChainTest.cpp
@@ -141,9 +141,12 @@
     desc.fHeight = 1;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     auto proxy = context->contextPriv().proxyProvider()->createProxy(
-            desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo,
-            GrInternalSurfaceFlags::kNone);
+            format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
+            SkBudgeted::kNo, GrInternalSurfaceFlags::kNone);
     SkASSERT(proxy);
     proxy->instantiate(context->contextPriv().resourceProvider());
     int result[result_width()];
diff --git a/tests/PathRendererCacheTests.cpp b/tests/PathRendererCacheTests.cpp
index 32e5b7df..ae81b69 100644
--- a/tests/PathRendererCacheTests.cpp
+++ b/tests/PathRendererCacheTests.cpp
@@ -79,9 +79,12 @@
     ctx->setResourceCacheLimits(100, 8000000);
     GrResourceCache* cache = ctx->contextPriv().getResourceCache();
 
+    const GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTargetContext> rtc(ctx->contextPriv().makeDeferredRenderTargetContext(
-            SkBackingFit::kApprox, 800, 800, kRGBA_8888_GrPixelConfig, nullptr, 1, GrMipMapped::kNo,
-            kTopLeft_GrSurfaceOrigin));
+            format, SkBackingFit::kApprox, 800, 800, kRGBA_8888_GrPixelConfig, nullptr, 1,
+            GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin));
     if (!rtc) {
         return;
     }
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
index dea8d5c..268927e 100644
--- a/tests/PrimitiveProcessorTest.cpp
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -121,8 +121,11 @@
     GrGpu* gpu = context->contextPriv().getGpu();
 #endif
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTargetContext> renderTargetContext(
-            context->contextPriv().makeDeferredRenderTargetContext(SkBackingFit::kApprox,
+            context->contextPriv().makeDeferredRenderTargetContext(format, SkBackingFit::kApprox,
                                                                    1, 1, kRGBA_8888_GrPixelConfig,
                                                                    nullptr));
     if (!renderTargetContext) {
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index e76099c..e4aab42 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -162,21 +162,28 @@
     desc.fHeight = 10;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     for (bool makeClone : {false, true}) {
         for (int parentCnt = 0; parentCnt < 2; parentCnt++) {
             sk_sp<GrRenderTargetContext> renderTargetContext(
                     context->contextPriv().makeDeferredRenderTargetContext(
-                                                             SkBackingFit::kApprox, 1, 1,
+                                                             format, SkBackingFit::kApprox, 1, 1,
                                                              kRGBA_8888_GrPixelConfig, nullptr));
             {
                 sk_sp<GrTextureProxy> proxy1 = proxyProvider->createProxy(
-                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
+                        format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
+                        SkBudgeted::kYes);
                 sk_sp<GrTextureProxy> proxy2 = proxyProvider->createProxy(
-                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
+                        format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
+                        SkBudgeted::kYes);
                 sk_sp<GrTextureProxy> proxy3 = proxyProvider->createProxy(
-                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
+                        format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
+                        SkBudgeted::kYes);
                 sk_sp<GrTextureProxy> proxy4 = proxyProvider->createProxy(
-                        desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kYes);
+                        format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
+                        SkBudgeted::kYes);
                 {
                     SkTArray<sk_sp<GrTextureProxy>> proxies;
                     SkTArray<sk_sp<GrBuffer>> buffers;
@@ -429,10 +436,14 @@
     // use --processorSeed <seed> (without --randomProcessorTest) to reproduce.
     SkRandom random(seed);
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     // Make the destination context for the test.
     static constexpr int kRenderSize = 256;
     sk_sp<GrRenderTargetContext> rtc = context->contextPriv().makeDeferredRenderTargetContext(
-            SkBackingFit::kExact, kRenderSize, kRenderSize, kRGBA_8888_GrPixelConfig, nullptr);
+            format, SkBackingFit::kExact, kRenderSize, kRenderSize, kRGBA_8888_GrPixelConfig,
+            nullptr);
 
     sk_sp<GrTextureProxy> proxies[2];
     if (!init_test_textures(proxyProvider, &random, proxies)) {
@@ -662,10 +673,14 @@
 
     SkRandom random;
 
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     // Make the destination context for the test.
     static constexpr int kRenderSize = 1024;
     sk_sp<GrRenderTargetContext> rtc = context->contextPriv().makeDeferredRenderTargetContext(
-            SkBackingFit::kExact, kRenderSize, kRenderSize, kRGBA_8888_GrPixelConfig, nullptr);
+            format, SkBackingFit::kExact, kRenderSize, kRenderSize, kRGBA_8888_GrPixelConfig,
+            nullptr);
 
     sk_sp<GrTextureProxy> proxies[2];
     if (!init_test_textures(proxyProvider, &random, proxies)) {
diff --git a/tests/ProxyConversionTest.cpp b/tests/ProxyConversionTest.cpp
index e316da7..8913f9a 100644
--- a/tests/ProxyConversionTest.cpp
+++ b/tests/ProxyConversionTest.cpp
@@ -137,9 +137,12 @@
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
+    const GrBackendFormat format =
+            ctxInfo.grContext()->contextPriv().caps()->getBackendFormatFromColorType(
+                    kRGBA_8888_SkColorType);
     {
         sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+                format, desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
 
         // Both RenderTarget and Texture
         GrRenderTargetProxy* rtProxy = proxy->asRenderTargetProxy();
@@ -152,7 +155,7 @@
 
     {
         sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+                format, desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
 
         // Both RenderTarget and Texture - but via GrTextureProxy
         GrTextureProxy* tProxy = proxy->asTextureProxy();
@@ -167,7 +170,7 @@
         desc.fFlags = kNone_GrSurfaceFlags; // force no-RT
 
         sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+                format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
         // Texture-only
         GrTextureProxy* tProxy = proxy->asTextureProxy();
         REPORTER_ASSERT(reporter, tProxy);
diff --git a/tests/ProxyRefTest.cpp b/tests/ProxyRefTest.cpp
index 288085f..5f3ce4f 100644
--- a/tests/ProxyRefTest.cpp
+++ b/tests/ProxyRefTest.cpp
@@ -61,18 +61,20 @@
     SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
 }
 
-static sk_sp<GrTextureProxy> make_deferred(GrProxyProvider* proxyProvider) {
+static sk_sp<GrTextureProxy> make_deferred(GrProxyProvider* proxyProvider, const GrCaps* caps) {
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     desc.fWidth = kWidthHeight;
     desc.fHeight = kWidthHeight;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
-    return proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
-                                      SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
+    const GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+    return proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin,
+                                      SkBackingFit::kApprox, SkBudgeted::kYes,
+                                      GrInternalSurfaceFlags::kNoPendingIO);
 }
 
-static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider) {
+static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider, const GrCaps* caps) {
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     desc.fWidth = kWidthHeight;
@@ -86,11 +88,12 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) {
     GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
     GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
+    const GrCaps* caps = ctxInfo.grContext()->contextPriv().caps();
 
     for (auto make : { make_deferred, make_wrapped }) {
         // A single write
         {
-            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
+            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
             if (proxy.get()) {
                 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
 
@@ -110,7 +113,7 @@
 
         // A single read
         {
-            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
+            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
             if (proxy.get()) {
                 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
 
@@ -130,7 +133,7 @@
 
         // A single read/write pair
         {
-            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
+            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
             if (proxy.get()) {
                 GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(proxy.get());
 
@@ -150,7 +153,7 @@
 
         // Multiple normal refs
         {
-            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
+            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
             if (proxy.get()) {
                 proxy->ref();
                 proxy->ref();
@@ -174,7 +177,7 @@
 
         // Continue using (reffing) proxy after instantiation
         {
-            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
+            sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps));
             if (proxy.get()) {
                 proxy->ref();
 
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 8988ed5..9a5a0d1 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -124,6 +124,12 @@
                             desc.fConfig = config;
                             desc.fSampleCnt = numSamples;
 
+                            GrSRGBEncoded srgbEncoded;
+                            GrColorType colorType =
+                                    GrPixelConfigToColorTypeAndEncoding(config, &srgbEncoded);
+                            const GrBackendFormat format =
+                                    caps.getBackendFormatFromGrColorType(colorType, srgbEncoded);
+
                             {
                                 sk_sp<GrTexture> tex;
                                 if (SkBackingFit::kApprox == fit) {
@@ -134,7 +140,8 @@
                                 }
 
                                 sk_sp<GrTextureProxy> proxy =
-                                        proxyProvider->createProxy(desc, origin, fit, budgeted);
+                                        proxyProvider->createProxy(format, desc, origin, fit,
+                                                                   budgeted);
                                 REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
                                 if (proxy) {
                                     REPORTER_ASSERT(reporter, proxy->asRenderTargetProxy());
@@ -168,7 +175,8 @@
                                 }
 
                                 sk_sp<GrTextureProxy> proxy(
-                                        proxyProvider->createProxy(desc, origin, fit, budgeted));
+                                        proxyProvider->createProxy(format, desc, origin, fit,
+                                                                   budgeted));
                                 REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
                                 if (proxy) {
                                     // This forces the proxy to compute and cache its
@@ -346,8 +354,12 @@
                     desc.fConfig = kRGBA_8888_GrPixelConfig;
                     desc.fSampleCnt = 1;
 
+                    const GrBackendFormat format =
+                        ctxInfo.grContext()->contextPriv().caps()->getBackendFormatFromColorType(
+                                kRGBA_8888_SkColorType);
+
                     sk_sp<GrTextureProxy> proxy = provider->createProxy(
-                            desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kNo);
+                            format, desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kNo);
                     REPORTER_ASSERT(reporter, !proxy);
                 }
             }
diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp
index ac81e6d..21a9e19 100644
--- a/tests/RectangleTextureTest.cpp
+++ b/tests/RectangleTextureTest.cpp
@@ -23,7 +23,10 @@
 // skbug.com/5932
 static void test_basic_draw_as_src(skiatest::Reporter* reporter, GrContext* context,
                                    sk_sp<GrTextureProxy> rectProxy, uint32_t expectedPixelValues[]) {
+    GrBackendFormat format = rectProxy->backendFormat().makeTexture2D();
+    SkASSERT(format.isValid());
     sk_sp<GrRenderTargetContext> rtContext(context->contextPriv().makeDeferredRenderTargetContext(
+                                                     format,
                                                      SkBackingFit::kExact, rectProxy->width(),
                                                      rectProxy->height(), rectProxy->config(),
                                                      nullptr));
diff --git a/tests/ResourceAllocatorTest.cpp b/tests/ResourceAllocatorTest.cpp
index e839d04..e5ace1a 100644
--- a/tests/ResourceAllocatorTest.cpp
+++ b/tests/ResourceAllocatorTest.cpp
@@ -31,7 +31,8 @@
     // TODO: do we care about mipmapping
 };
 
-static GrSurfaceProxy* make_deferred(GrProxyProvider* proxyProvider, const ProxyParams& p) {
+static GrSurfaceProxy* make_deferred(GrProxyProvider* proxyProvider, const GrCaps* caps,
+                                     const ProxyParams& p) {
     GrColorType grCT = SkColorTypeToGrColorType(p.fColorType);
     GrPixelConfig config = GrColorTypeToPixelConfig(grCT, GrSRGBEncoded::kNo);
 
@@ -42,7 +43,9 @@
     desc.fConfig = config;
     desc.fSampleCnt = p.fSampleCnt;
 
-    auto tmp = proxyProvider->createProxy(desc, p.fOrigin, p.fFit, SkBudgeted::kNo);
+    const GrBackendFormat format = caps->getBackendFormatFromColorType(p.fColorType);
+
+    auto tmp = proxyProvider->createProxy(format, desc, p.fOrigin, p.fFit, SkBudgeted::kNo);
     if (!tmp) {
         return nullptr;
     }
@@ -134,6 +137,7 @@
 }
 
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceAllocatorTest, reporter, ctxInfo) {
+    const GrCaps* caps = ctxInfo.grContext()->contextPriv().caps();
     GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
     GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
 
@@ -173,8 +177,8 @@
     };
 
     for (auto test : gOverlappingTests) {
-        GrSurfaceProxy* p1 = make_deferred(proxyProvider, test.fP1);
-        GrSurfaceProxy* p2 = make_deferred(proxyProvider, test.fP2);
+        GrSurfaceProxy* p1 = make_deferred(proxyProvider, caps, test.fP1);
+        GrSurfaceProxy* p2 = make_deferred(proxyProvider, caps, test.fP2);
         overlap_test(reporter, resourceProvider, p1, p2, test.fExpectation);
         p1->completedRead();
         p2->completedRead();
@@ -215,8 +219,8 @@
     };
 
     for (auto test : gNonOverlappingTests) {
-        GrSurfaceProxy* p1 = make_deferred(proxyProvider, test.fP1);
-        GrSurfaceProxy* p2 = make_deferred(proxyProvider, test.fP2);
+        GrSurfaceProxy* p1 = make_deferred(proxyProvider, caps, test.fP1);
+        GrSurfaceProxy* p2 = make_deferred(proxyProvider, caps, test.fP2);
 
         if (!p1 || !p2) {
             continue; // creation can fail (i.e., for msaa4 on iOS)
@@ -236,7 +240,7 @@
 
         GrBackendTexture backEndTex;
         GrSurfaceProxy* p1 = make_backend(ctxInfo.grContext(), t[0].fP1, &backEndTex);
-        GrSurfaceProxy* p2 = make_deferred(proxyProvider, t[0].fP2);
+        GrSurfaceProxy* p2 = make_deferred(proxyProvider, caps, t[0].fP2);
 
         non_overlap_test(reporter, resourceProvider, p1, p2, t[0].fExpectation);
 
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index fa09db3..11c8e67 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -1580,6 +1580,7 @@
 }
 
 static sk_sp<GrTextureProxy> make_mipmap_proxy(GrProxyProvider* proxyProvider,
+                                               const GrCaps* caps,
                                                GrSurfaceDescFlags descFlags,
                                                int width, int height,
                                                int sampleCnt) {
@@ -1590,10 +1591,11 @@
     desc.fConfig = kRGBA_8888_GrPixelConfig;
     desc.fSampleCnt = sampleCnt;
 
+    const GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     auto origin = (descFlags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin
                                                             : kTopLeft_GrSurfaceOrigin;
 
-    return proxyProvider->createMipMapProxy(desc, origin, SkBudgeted::kYes);
+    return proxyProvider->createMipMapProxy(format, desc, origin, SkBudgeted::kYes);
 }
 
 // Exercise GrSurface::gpuMemorySize for different combos of MSAA, RT-only,
@@ -1632,18 +1634,20 @@
 
 
     // Mipmapped versions
-    if (context->contextPriv().caps()->mipMapSupport()) {
+    const GrCaps* caps  = context->contextPriv().caps();
+    if (caps->mipMapSupport()) {
         sk_sp<GrTextureProxy> proxy;
 
-        proxy = make_mipmap_proxy(proxyProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 1);
+        proxy = make_mipmap_proxy(proxyProvider, caps, kRenderTarget_GrSurfaceFlag, kSize, kSize,
+                                  1);
         size_t size = proxy->gpuMemorySize();
         REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);
 
         size_t sampleCount = (size_t)context->contextPriv().caps()->getRenderTargetSampleCount(
                 4, kRGBA_8888_GrPixelConfig);
         if (sampleCount >= 4) {
-            proxy = make_mipmap_proxy(proxyProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
-                                      sampleCount);
+            proxy = make_mipmap_proxy(proxyProvider, caps, kRenderTarget_GrSurfaceFlag, kSize,
+                                      kSize, sampleCount);
             size = proxy->gpuMemorySize();
             REPORTER_ASSERT(reporter,
                kSize*kSize*4+(kSize*kSize*4)/3 == size ||                 // msaa4 failed
@@ -1651,7 +1655,7 @@
                kSize*kSize*4*(sampleCount+1)+(kSize*kSize*4)/3 == size);  // explicit resolve buffer
         }
 
-        proxy = make_mipmap_proxy(proxyProvider, kNone_GrSurfaceFlags, kSize, kSize, 1);
+        proxy = make_mipmap_proxy(proxyProvider, caps, kNone_GrSurfaceFlags, kSize, kSize, 1);
         size = proxy->gpuMemorySize();
         REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);
     }
diff --git a/tests/SRGBReadWritePixelsTest.cpp b/tests/SRGBReadWritePixelsTest.cpp
index 0bb7694..201a831 100644
--- a/tests/SRGBReadWritePixelsTest.cpp
+++ b/tests/SRGBReadWritePixelsTest.cpp
@@ -202,8 +202,13 @@
     desc.fHeight = kH;
     desc.fConfig = encoding_as_pixel_config(contextEncoding);
 
+    GrSRGBEncoded srgbEncoded = GrSRGBEncoded::kNo;
+    GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(desc.fConfig, &srgbEncoded);
+    const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromGrColorType(colorType, srgbEncoded);
+
     auto surfaceContext = context->contextPriv().makeDeferredSurfaceContext(
-            desc, kBottomLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
+            format, desc, kBottomLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
             SkBudgeted::kNo, encoding_as_color_space(contextEncoding));
     if (!surfaceContext) {
         ERRORF(reporter, "Could not create %s surface context.", encoding_as_str(contextEncoding));
diff --git a/tests/SpecialSurfaceTest.cpp b/tests/SpecialSurfaceTest.cpp
index 7b3896b..a59c8ee 100644
--- a/tests/SpecialSurfaceTest.cpp
+++ b/tests/SpecialSurfaceTest.cpp
@@ -79,10 +79,16 @@
 
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialSurface_Gpu1, reporter, ctxInfo) {
     for (auto config : { kRGBA_8888_GrPixelConfig, kRGBA_1010102_GrPixelConfig }) {
-        if (!ctxInfo.grContext()->contextPriv().caps()->isConfigRenderable(config)) {
+        const GrCaps* caps = ctxInfo.grContext()->contextPriv().caps();
+        if (!caps->isConfigRenderable(config)) {
             continue;
         }
+        GrSRGBEncoded srgbEncoded = GrSRGBEncoded::kNo;
+        GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(config, &srgbEncoded);
+        const GrBackendFormat format =
+                caps->getBackendFormatFromGrColorType(colorType, srgbEncoded);
         sk_sp<SkSpecialSurface> surf(SkSpecialSurface::MakeRenderTarget(ctxInfo.grContext(),
+                                                                        format,
                                                                         kSmallerSize, kSmallerSize,
                                                                         config, nullptr));
         test_surface(surf, reporter, 0);
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index 6b1f29f..db8665d 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -675,9 +675,11 @@
 
 DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) {
     GrContext* ctx = ctxInfo.grContext();
+    const GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
     sk_sp<GrRenderTargetContext> rtc(ctx->contextPriv().makeDeferredRenderTargetContext(
-            SkBackingFit::kApprox, 800, 800, kRGBA_8888_GrPixelConfig, nullptr, 1, GrMipMapped::kNo,
-            kTopLeft_GrSurfaceOrigin));
+            format, SkBackingFit::kApprox, 800, 800, kRGBA_8888_GrPixelConfig, nullptr, 1,
+            GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin));
     if (!rtc) {
         return;
     }
diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp
index 3348631..03ded09 100644
--- a/tests/TextureProxyTest.cpp
+++ b/tests/TextureProxyTest.cpp
@@ -38,29 +38,34 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Basic test
 
-static sk_sp<GrTextureProxy> deferred_tex(skiatest::Reporter* reporter,
+static sk_sp<GrTextureProxy> deferred_tex(skiatest::Reporter* reporter, GrContext* ctx,
                                           GrProxyProvider* proxyProvider, SkBackingFit fit) {
     const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
+    GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
 
     sk_sp<GrTextureProxy> proxy =
-            proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
+            proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin, fit,
+                                       SkBudgeted::kYes);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
 }
 
-static sk_sp<GrTextureProxy> deferred_texRT(skiatest::Reporter* reporter,
+static sk_sp<GrTextureProxy> deferred_texRT(skiatest::Reporter* reporter, GrContext* ctx,
                                             GrProxyProvider* proxyProvider, SkBackingFit fit) {
     const GrSurfaceDesc desc = make_desc(kRenderTarget_GrSurfaceFlag);
+    GrBackendFormat format =
+            ctx->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
 
     sk_sp<GrTextureProxy> proxy =
-            proxyProvider->createProxy(desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
+            proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
 }
 
-static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter,
+static sk_sp<GrTextureProxy> wrapped(skiatest::Reporter* reporter, GrContext* ctx,
                                      GrProxyProvider* proxyProvider, SkBackingFit fit) {
     const GrSurfaceDesc desc = make_desc(kNone_GrSurfaceFlags);
 
@@ -71,7 +76,7 @@
     return proxy;
 }
 
-static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter,
+static sk_sp<GrTextureProxy> wrapped_with_key(skiatest::Reporter* reporter, GrContext* ctx,
                                               GrProxyProvider* proxyProvider, SkBackingFit fit) {
     static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
     static int kUniqueKeyData = 0;
@@ -237,7 +242,8 @@
     builder.finish();
 
     // Create proxy, assign unique key
-    sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, proxyProvider, SkBackingFit::kExact);
+    sk_sp<GrTextureProxy> proxy = deferred_tex(reporter, context, proxyProvider,
+                                               SkBackingFit::kExact);
     SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
 
     // Send an invalidation message, which will be sitting in the cache's inbox
@@ -274,7 +280,7 @@
     for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
         for (auto create : { deferred_tex, deferred_texRT, wrapped, wrapped_with_key }) {
             REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
-            basic_test(context, reporter, create(reporter, proxyProvider, fit));
+            basic_test(context, reporter, create(reporter, context, proxyProvider, fit));
         }
 
         REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
diff --git a/tests/TraceMemoryDumpTest.cpp b/tests/TraceMemoryDumpTest.cpp
index d7043a0..721c17b 100644
--- a/tests/TraceMemoryDumpTest.cpp
+++ b/tests/TraceMemoryDumpTest.cpp
@@ -149,7 +149,7 @@
     iddesc.fMSColorRenderbufferID = 22;
     iddesc.fIsMixedSampled = false;
 
-    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, iddesc, 0);
+    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, GR_GL_RGBA8, iddesc, 0);
 
     ValidateMemoryDumps(reporter, context, rt->gpuMemorySize(), true /* isOwned */);
 }
@@ -171,7 +171,7 @@
     iddesc.fMSColorRenderbufferID = 22;
     iddesc.fIsMixedSampled = false;
 
-    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, iddesc, 0);
+    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, GR_GL_RGBA8, iddesc, 0);
 
     ValidateMemoryDumps(reporter, context, rt->gpuMemorySize(), false /* isOwned */);
 }
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index 007f16b..9ba16c9 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -529,8 +529,11 @@
         desc.fHeight = 64;
         desc.fConfig = kRGBA_8888_GrPixelConfig;
 
+        const GrBackendFormat format =
+            context->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
         sk_sp<GrTextureProxy> temp = proxyProvider->createProxy(
-                desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+                format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
         temp->instantiate(context->contextPriv().resourceProvider());
     }
 
diff --git a/tools/gpu/ProxyUtils.cpp b/tools/gpu/ProxyUtils.cpp
index 9e77a91..fc167d8 100644
--- a/tools/gpu/ProxyUtils.cpp
+++ b/tools/gpu/ProxyUtils.cpp
@@ -50,13 +50,20 @@
             return nullptr;
         }
 
+        const GrBackendFormat format =
+                context->contextPriv().caps()->getBackendFormatFromGrColorType(colorType,
+                                                                               srgbEncoded);
+        if (!format.isValid()) {
+            return nullptr;
+        }
+
         GrSurfaceDesc desc;
         desc.fConfig = config;
         desc.fWidth = width;
         desc.fHeight = height;
         desc.fFlags = isRT ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
         proxy = context->contextPriv().proxyProvider()->createProxy(
-                desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
+                format, desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
         if (!proxy) {
             return nullptr;
         }