Pass GrBackendFormat to GrResourceProvider and GrGpu texture create
functions.

Change-Id: Ie3fe9d56fdbf369ccacd0188a3d3d73ce1d30d48
Bug: skia:6718
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/232141
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 280885f..6130312 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -144,10 +144,10 @@
     return levelsWithPixelsCnt == mipLevelCount;
 }
 
-sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, GrRenderable renderable,
-                                      int renderTargetSampleCnt, SkBudgeted budgeted,
-                                      GrProtected isProtected, const GrMipLevel texels[],
-                                      int mipLevelCount) {
+sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, const GrBackendFormat& format,
+                                      GrRenderable renderable, int renderTargetSampleCnt,
+                                      SkBudgeted budgeted, GrProtected isProtected,
+                                      const GrMipLevel texels[], int mipLevelCount) {
     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
     if (GrPixelConfigIsCompressed(origDesc.fConfig)) {
         // Call GrGpu::createCompressedTexture.
@@ -191,15 +191,17 @@
                 fStats.incTextureUploads();
             }
         }
+        //  TODO: Assert this once format is passed to onCreateTexture().
+        //  SkASSERT(tex->backendFormat() == format);
     }
     return tex;
 }
 
-sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                      int renderTargetSampleCnt, SkBudgeted budgeted,
-                                      GrProtected isProtected) {
-    return this->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected,
-                               nullptr, 0);
+sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, const GrBackendFormat& format,
+                                      GrRenderable renderable, int renderTargetSampleCnt,
+                                      SkBudgeted budgeted, GrProtected isProtected) {
+    return this->createTexture(desc, format, renderable, renderTargetSampleCnt, budgeted,
+                               isProtected, nullptr, 0);
 }
 
 sk_sp<GrTexture> GrGpu::createCompressedTexture(int width, int height,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index fb9a7c5..d1d8294 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -86,6 +86,7 @@
      * or render targets can be checked using GrCaps.
      *
      * @param desc           describes the texture to be created.
+     * @param format         the format for the texture (not currently used).
      * @param renderable     should the resulting texture be renderable
      * @param renderTargetSampleCnt The number of samples to use for rendering if renderable is
      *                       kYes. If renderable is kNo then this must be 1.
@@ -107,15 +108,17 @@
      *                       latter if GrCaps::createTextureMustSpecifyAllLevels() is true.
      * @return  The texture object if successful, otherwise nullptr.
      */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                   int renderTargetSampleCnt, SkBudgeted, GrProtected isProtected,
-                                   const GrMipLevel texels[], int mipLevelCount);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, const GrBackendFormat& format,
+                                   GrRenderable renderable, int renderTargetSampleCnt, SkBudgeted,
+                                   GrProtected isProtected, const GrMipLevel texels[],
+                                   int mipLevelCount);
 
     /**
      * Simplified createTexture() interface for when there is no initial texel data to upload.
      */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
-                                   SkBudgeted, GrProtected);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, const GrBackendFormat& format,
+                                   GrRenderable renderable, int renderTargetSampleCnt,
+                                   SkBudgeted budgeted, GrProtected isProtected);
 
     sk_sp<GrTexture> createCompressedTexture(int width, int height, SkImage::CompressionType,
                                              SkBudgeted, const void* data, size_t dataSize);
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 3d0bace..f64b345 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -115,23 +115,44 @@
 
 #if GR_TEST_UTILS
 sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createInstantiatedProxy(
-        const GrSurfaceDesc& desc, GrRenderable renderable, int renderTargetSampleCnt,
-        GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted, GrProtected isProtected) {
+        const SkISize& size,
+        GrColorType colorType,
+        const GrBackendFormat& format,
+        GrRenderable renderable,
+        int renderTargetSampleCnt,
+        GrSurfaceOrigin origin,
+        SkBackingFit fit,
+        SkBudgeted budgeted,
+        GrProtected isProtected) {
     GrContext* direct = fImageContext->priv().asDirectContext();
     if (!direct) {
         return nullptr;
     }
 
+    if (this->caps()->isFormatCompressed(format)) {
+        // TODO: Allow this to go to GrResourceProvider::createCompressedTexture() once we no longer
+        // rely on GrColorType to get to GrPixelConfig. Currently this will cause
+        // makeConfigSpecific() to assert because GrColorTypeToPixelConfig() never returns a
+        // compressed GrPixelConfig.
+        return nullptr;
+    }
+    GrSurfaceDesc desc;
+    desc.fConfig = GrColorTypeToPixelConfig(colorType);
+    desc.fConfig = this->caps()->makeConfigSpecific(desc.fConfig, format);
+    desc.fWidth = size.width();
+    desc.fHeight = size.height();
+
     GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
     sk_sp<GrTexture> tex;
 
     if (SkBackingFit::kApprox == fit) {
-        tex = resourceProvider->createApproxTexture(desc, renderable, renderTargetSampleCnt,
+        tex = resourceProvider->createApproxTexture(desc, format, renderable, renderTargetSampleCnt,
                                                     isProtected,
                                                     GrResourceProvider::Flags::kNoPendingIO);
     } else {
-        tex = resourceProvider->createTexture(desc, renderable, renderTargetSampleCnt, budgeted,
-                                              isProtected, GrResourceProvider::Flags::kNoPendingIO);
+        tex = resourceProvider->createTexture(desc, format, renderable, renderTargetSampleCnt,
+                                              budgeted, isProtected,
+                                              GrResourceProvider::Flags::kNoPendingIO);
     }
     if (!tex) {
         return nullptr;
@@ -140,6 +161,27 @@
     return this->createWrapped(std::move(tex), origin);
 }
 
+sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createInstantiatedProxy(
+        const SkISize& size,
+        GrColorType colorType,
+        GrRenderable renderable,
+        int renderTargetSampleCnt,
+        GrSurfaceOrigin origin,
+        SkBackingFit fit,
+        SkBudgeted budgeted,
+        GrProtected isProtected) {
+    auto format = this->caps()->getDefaultBackendFormat(colorType, renderable);
+    return this->testingOnly_createInstantiatedProxy(size,
+                                                     colorType,
+                                                     format,
+                                                     renderable,
+                                                     renderTargetSampleCnt,
+                                                     origin,
+                                                     fit,
+                                                     budgeted,
+                                                     isProtected);
+}
+
 sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createWrapped(sk_sp<GrTexture> tex,
                                                                  GrSurfaceOrigin origin) {
     return this->createWrapped(std::move(tex), origin);
@@ -252,15 +294,15 @@
     desc.fConfig = config;
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [desc, renderable, sampleCnt, budgeted, srcImage,
+            [desc, format, renderable, sampleCnt, budgeted, srcImage,
              fit](GrResourceProvider* resourceProvider) {
                 SkPixmap pixMap;
                 SkAssertResult(srcImage->peekPixels(&pixMap));
                 GrMipLevel mipLevel = { pixMap.addr(), pixMap.rowBytes() };
 
                 return LazyInstantiationResult(resourceProvider->createTexture(
-                        desc, renderable, sampleCnt, budgeted, fit, GrProtected::kNo, mipLevel,
-                        GrResourceProvider::Flags::kNoPendingIO));
+                        desc, format, renderable, sampleCnt, budgeted, fit, GrProtected::kNo,
+                        mipLevel, GrResourceProvider::Flags::kNoPendingIO));
             },
             format, desc, renderable, sampleCnt, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
             GrMipMapsStatus::kNotAllocated, surfaceFlags, fit, budgeted, GrProtected::kNo);
@@ -365,7 +407,7 @@
     }
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [desc, baseLevel, mipmaps](GrResourceProvider* resourceProvider) {
+            [desc, format, baseLevel, mipmaps](GrResourceProvider* resourceProvider) {
                 const int mipLevelCount = mipmaps->countLevels() + 1;
                 std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
 
@@ -386,7 +428,7 @@
                 }
 
                 return LazyInstantiationResult(resourceProvider->createTexture(
-                        desc, GrRenderable::kNo, 1, SkBudgeted::kYes, GrProtected::kNo,
+                        desc, format, GrRenderable::kNo, 1, SkBudgeted::kYes, GrProtected::kNo,
                         texels.get(), mipLevelCount));
             },
             format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes,
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 6a971a6..76c8e56 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -246,11 +246,28 @@
 #if GR_TEST_UTILS
     /*
      * Create a texture proxy that is backed by an instantiated GrSurface.
+     * TODO: Remove GrColorType. Currently used to infer a GrPixelConfig.
      */
-    sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const GrSurfaceDesc&, GrRenderable,
+    sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const SkISize& size,
+                                                              GrColorType colorType,
+                                                              const GrBackendFormat& format,
+                                                              GrRenderable renderable,
                                                               int renderTargetSampleCnt,
-                                                              GrSurfaceOrigin, SkBackingFit,
-                                                              SkBudgeted, GrProtected);
+                                                              GrSurfaceOrigin origin,
+                                                              SkBackingFit fit,
+                                                              SkBudgeted budgeted,
+                                                              GrProtected isProtected);
+
+    /** Version of above that picks the default format for the color type. */
+    sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const SkISize& size,
+                                                              GrColorType colorType,
+                                                              GrRenderable renderable,
+                                                              int renderTargetSampleCnt,
+                                                              GrSurfaceOrigin origin,
+                                                              SkBackingFit fit,
+                                                              SkBudgeted budgeted,
+                                                              GrProtected isProtected);
+
     sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>, GrSurfaceOrigin);
 #endif
 
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index d9b4f92..2413c64 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -77,6 +77,7 @@
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
+                                                   const GrBackendFormat& format,
                                                    GrRenderable renderable,
                                                    int renderTargetSampleCnt, SkBudgeted budgeted,
                                                    GrProtected isProtected,
@@ -112,18 +113,19 @@
             h = std::max(h / 2, 1);
         }
     }
-    return fGpu->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected,
-                               tmpTexels.get(), mipLevelCount);
+    return fGpu->createTexture(desc, format, renderable, renderTargetSampleCnt, budgeted,
+                               isProtected, tmpTexels.get(), mipLevelCount);
 }
 
 sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
+                                                     const GrBackendFormat& format,
                                                      GrRenderable renderable,
                                                      int renderTargetSampleCnt,
                                                      SkBudgeted budgeted,
                                                      GrProtected isProtected,
                                                      Flags flags) {
-    sk_sp<GrTexture> tex(
-            this->refScratchTexture(desc, renderable, renderTargetSampleCnt, isProtected, flags));
+    sk_sp<GrTexture> tex(this->refScratchTexture(desc, format, renderable, renderTargetSampleCnt,
+                                                 isProtected, flags));
     if (tex && SkBudgeted::kNo == budgeted) {
         tex->resourcePriv().makeUnbudgeted();
     }
@@ -132,6 +134,7 @@
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
+                                                   const GrBackendFormat& format,
                                                    GrRenderable renderable,
                                                    int renderTargetSampleCnt,
                                                    SkBudgeted budgeted,
@@ -170,9 +173,9 @@
     GrColorType colorType = GrPixelConfigToColorType(desc.fConfig);
     sk_sp<GrTexture> tex =
             (SkBackingFit::kApprox == fit)
-                    ? this->createApproxTexture(desc, renderable, renderTargetSampleCnt,
+                    ? this->createApproxTexture(desc, format, renderable, renderTargetSampleCnt,
                                                 isProtected, flags)
-                    : this->createTexture(desc, renderable, renderTargetSampleCnt, budgeted,
+                    : this->createTexture(desc, format, renderable, renderTargetSampleCnt, budgeted,
                                           isProtected, flags);
     if (!tex) {
         return nullptr;
@@ -208,6 +211,7 @@
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
+                                                   const GrBackendFormat& format,
                                                    GrRenderable renderable,
                                                    int renderTargetSampleCnt,
                                                    SkBudgeted budgeted,
@@ -224,8 +228,8 @@
 
     // Compressed textures are read-only so they don't support re-use for scratch.
     if (!GrPixelConfigIsCompressed(desc.fConfig)) {
-        sk_sp<GrTexture> tex = this->getExactScratch(desc, renderable, renderTargetSampleCnt,
-                                                     budgeted, isProtected, flags);
+        sk_sp<GrTexture> tex = this->getExactScratch(
+                desc, format, renderable, renderTargetSampleCnt, budgeted, isProtected, flags);
         if (tex) {
             return tex;
         }
@@ -238,11 +242,12 @@
         GrMipLevel level;
         level.fRowBytes = rowBytes;
         level.fPixels = zeros.get();
-        return fGpu->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected,
-                                   &level, 1);
+        return fGpu->createTexture(desc, format, renderable, renderTargetSampleCnt, budgeted,
+                                   isProtected, &level, 1);
     }
 
-    return fGpu->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected);
+    return fGpu->createTexture(desc, format, renderable, renderTargetSampleCnt, budgeted,
+                               isProtected);
 }
 
 // Map 'value' to a larger multiple of 2. Values <= 'kMagicTol' will pop up to
@@ -272,9 +277,11 @@
 }
 
 sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
+                                                         const GrBackendFormat& format,
                                                          GrRenderable renderable,
                                                          int renderTargetSampleCnt,
-                                                         GrProtected isProtected, Flags flags) {
+                                                         GrProtected isProtected,
+                                                         Flags flags) {
     ASSERT_SINGLE_OWNER
     SkASSERT(Flags::kNone == flags || Flags::kNoPendingIO == flags);
 
@@ -291,8 +298,8 @@
         return nullptr;
     }
 
-    if (auto tex = this->refScratchTexture(desc, renderable, renderTargetSampleCnt, isProtected,
-                                           flags)) {
+    if (auto tex = this->refScratchTexture(desc, format, renderable, renderTargetSampleCnt,
+                                           isProtected, flags)) {
         return tex;
     }
 
@@ -305,7 +312,7 @@
         wdesc->fHeight = MakeApprox(wdesc->fHeight);
     }
 
-    if (auto tex = this->refScratchTexture(*copyDesc, renderable, renderTargetSampleCnt,
+    if (auto tex = this->refScratchTexture(*copyDesc, format, renderable, renderTargetSampleCnt,
                                            isProtected, flags)) {
         return tex;
     }
@@ -317,14 +324,15 @@
         GrMipLevel level;
         level.fRowBytes = rowBytes;
         level.fPixels = zeros.get();
-        return fGpu->createTexture(*copyDesc, renderable, renderTargetSampleCnt, SkBudgeted::kYes,
-                                   isProtected, &level, 1);
+        return fGpu->createTexture(*copyDesc, format, renderable, renderTargetSampleCnt,
+                                   SkBudgeted::kYes, isProtected, &level, 1);
     }
-    return fGpu->createTexture(*copyDesc, renderable, renderTargetSampleCnt, SkBudgeted::kYes,
-                               isProtected);
+    return fGpu->createTexture(*copyDesc, format, renderable, renderTargetSampleCnt,
+                               SkBudgeted::kYes, isProtected);
 }
 
 sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc,
+                                                       const GrBackendFormat& format,
                                                        GrRenderable renderable,
                                                        int renderTargetSampleCnt,
                                                        GrProtected isProtected,
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 1a1d37d..7df4b6b 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -75,20 +75,41 @@
      * GrRenderTarget. The texture's format and sample count will always match the request.
      * The contents of the texture are undefined.
      */
-    sk_sp<GrTexture> createApproxTexture(const GrSurfaceDesc&, GrRenderable,
-                                         int renderTargetSampleCnt, GrProtected, Flags);
+    sk_sp<GrTexture> createApproxTexture(const GrSurfaceDesc& desc,
+                                         const GrBackendFormat& format,
+                                         GrRenderable renderable,
+                                         int renderTargetSampleCnt,
+                                         GrProtected isProtected,
+                                         Flags flags);
 
     /** Create an exact fit texture with no initial data to upload. */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
-                                   SkBudgeted, GrProtected, Flags = Flags::kNone);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc,
+                                   const GrBackendFormat& format,
+                                   GrRenderable renderable,
+                                   int renderTargetSampleCnt,
+                                   SkBudgeted budgeted,
+                                   GrProtected isProtected,
+                                   Flags flags = Flags::kNone);
 
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
-                                   SkBudgeted, GrProtected, const GrMipLevel texels[],
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc,
+                                   const GrBackendFormat& format,
+                                   GrRenderable renderable,
+                                   int renderTargetSampleCnt,
+                                   SkBudgeted budgeted,
+                                   GrProtected isProtected,
+                                   const GrMipLevel texels[],
                                    int mipLevelCount);
 
     /** Create a potentially loose fit texture with the provided data */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
-                                   SkBudgeted, SkBackingFit, GrProtected, const GrMipLevel&, Flags);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc,
+                                   const GrBackendFormat& format,
+                                   GrRenderable renderable,
+                                   int renderTargetSampleCnt,
+                                   SkBudgeted budgeted,
+                                   SkBackingFit fit,
+                                   GrProtected isProtected,
+                                   const GrMipLevel& mipLevel,
+                                   Flags flags);
 
     /**
      * Creates a compressed texture. The GrGpu must support the SkImageImage::Compression type.
@@ -270,15 +291,24 @@
 
     // Attempts to find a resource in the cache that exactly matches the GrSurfaceDesc. Failing that
     // it returns null. If non-null, the resulting texture is always budgeted.
-    sk_sp<GrTexture> refScratchTexture(const GrSurfaceDesc&, GrRenderable,
-                                       int renderTargetSampleCnt, GrProtected, Flags);
+    sk_sp<GrTexture> refScratchTexture(const GrSurfaceDesc& desc,
+                                       const GrBackendFormat& format,
+                                       GrRenderable renderable,
+                                       int renderTargetSampleCnt,
+                                       GrProtected isProtected,
+                                       Flags flags);
 
     /*
      * Try to find an existing scratch texture that exactly matches 'desc'. If successful
      * update the budgeting accordingly.
      */
-    sk_sp<GrTexture> getExactScratch(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
-                                     SkBudgeted, GrProtected, Flags);
+    sk_sp<GrTexture> getExactScratch(const GrSurfaceDesc& desc,
+                                     const GrBackendFormat& format,
+                                     GrRenderable renderable,
+                                     int renderTargetSampleCnt,
+                                     SkBudgeted budgeted,
+                                     GrProtected isProtected,
+                                     Flags flags);
 
     GrResourceCache* cache() { return fCache; }
     const GrResourceCache* cache() const { return fCache; }
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 5e874c6..2dbc716 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -130,7 +130,8 @@
 }
 
 sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl(GrResourceProvider* resourceProvider,
-                                                   int sampleCnt, int minStencilSampleCount,
+                                                   int sampleCnt,
+                                                   int minStencilSampleCount,
                                                    GrRenderable renderable,
                                                    GrMipMapped mipMapped) const {
     SkASSERT(GrSurfaceProxy::LazyState::kNot == this->lazyInstantiationState());
@@ -160,7 +161,7 @@
             texels[i].fPixels = nullptr;
             texels[i].fRowBytes = 0;
         }
-        surface = resourceProvider->createTexture(desc, renderable, sampleCnt, fBudgeted,
+        surface = resourceProvider->createTexture(desc, fFormat, renderable, sampleCnt, fBudgeted,
                                                   fIsProtected, texels.get(), mipCount);
 #ifdef SK_DEBUG
         if (surface) {
@@ -176,11 +177,12 @@
 #endif
     } else {
         if (SkBackingFit::kApprox == fFit) {
-            surface = resourceProvider->createApproxTexture(desc, renderable, sampleCnt,
+            surface = resourceProvider->createApproxTexture(desc, fFormat, renderable, sampleCnt,
                                                             fIsProtected, resourceProviderFlags);
         } else {
-            surface = resourceProvider->createTexture(desc, renderable, sampleCnt, fBudgeted,
-                                                      fIsProtected, resourceProviderFlags);
+            surface =
+                    resourceProvider->createTexture(desc, fFormat, renderable, sampleCnt, fBudgeted,
+                                                    fIsProtected, resourceProviderFlags);
         }
     }
     if (!surface) {
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index 56b115e..89eff1a 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -75,9 +75,13 @@
             break;
     }
 
+    auto instantiate = [cb = std::move(callback), pixelConfig, format,
+                        sampleCount](GrResourceProvider* rp) {
+        return cb(rp, pixelConfig, format, sampleCount);
+    };
     sk_sp<GrTextureProxy> proxy = GrProxyProvider::MakeFullyLazyProxy(
-            std::bind(callback, std::placeholders::_1, pixelConfig, sampleCount), format,
-            GrRenderable::kYes, sampleCount, GrProtected::kNo, kTextureOrigin, pixelConfig, caps);
+            std::move(instantiate), format, GrRenderable::kYes, sampleCount, GrProtected::kNo,
+            kTextureOrigin, pixelConfig, caps);
 
     return proxy;
 }
@@ -109,19 +113,21 @@
 
     fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, fWidth, fHeight);
 
-    fTextureProxy = MakeLazyAtlasProxy([this](
-            GrResourceProvider* resourceProvider, GrPixelConfig pixelConfig, int sampleCount) {
-        if (!fBackingTexture) {
-            GrSurfaceDesc desc;
-            desc.fWidth = fWidth;
-            desc.fHeight = fHeight;
-            desc.fConfig = pixelConfig;
-            fBackingTexture = resourceProvider->createTexture(
-                    desc, GrRenderable::kYes, sampleCount, SkBudgeted::kYes, GrProtected::kNo,
-                    GrResourceProvider::Flags::kNoPendingIO);
-        }
-        return fBackingTexture;
-    }, fCoverageType, caps);
+    fTextureProxy = MakeLazyAtlasProxy(
+            [this](GrResourceProvider* resourceProvider, GrPixelConfig pixelConfig,
+                   const GrBackendFormat& format, int sampleCount) {
+                if (!fBackingTexture) {
+                    GrSurfaceDesc desc;
+                    desc.fWidth = fWidth;
+                    desc.fHeight = fHeight;
+                    desc.fConfig = pixelConfig;
+                    fBackingTexture = resourceProvider->createTexture(
+                            desc, format, GrRenderable::kYes, sampleCount, SkBudgeted::kYes,
+                            GrProtected::kNo, GrResourceProvider::Flags::kNoPendingIO);
+                }
+                return fBackingTexture;
+            },
+            fCoverageType, caps);
 
     fTextureProxy->priv().setIgnoredByResourceAllocator();
 }
diff --git a/src/gpu/ccpr/GrCCAtlas.h b/src/gpu/ccpr/GrCCAtlas.h
index 223d955..125f41a 100644
--- a/src/gpu/ccpr/GrCCAtlas.h
+++ b/src/gpu/ccpr/GrCCAtlas.h
@@ -54,7 +54,7 @@
     };
 
     using LazyInstantiateAtlasCallback = std::function<sk_sp<GrTexture>(
-            GrResourceProvider*, GrPixelConfig, int sampleCount)>;
+            GrResourceProvider*, GrPixelConfig, const GrBackendFormat&, int sampleCount)>;
 
     static sk_sp<GrTextureProxy> MakeLazyAtlasProxy(
             const LazyInstantiateAtlasCallback&, CoverageType, const GrCaps&);
diff --git a/src/gpu/ccpr/GrCCClipPath.cpp b/src/gpu/ccpr/GrCCClipPath.cpp
index 922e170..451d545 100644
--- a/src/gpu/ccpr/GrCCClipPath.cpp
+++ b/src/gpu/ccpr/GrCCClipPath.cpp
@@ -18,31 +18,34 @@
         GrCCAtlas::CoverageType atlasCoverageType, const GrCaps& caps) {
     SkASSERT(!this->isInitialized());
 
-    fAtlasLazyProxy = GrCCAtlas::MakeLazyAtlasProxy([this](
-            GrResourceProvider* resourceProvider, GrPixelConfig pixelConfig, int sampleCount) {
-        SkASSERT(fHasAtlas);
-        SkASSERT(!fHasAtlasTransform);
+    fAtlasLazyProxy = GrCCAtlas::MakeLazyAtlasProxy(
+            [this](GrResourceProvider* resourceProvider, GrPixelConfig,
+                   const GrBackendFormat& format, int sampleCount) {
+                SkASSERT(fHasAtlas);
+                SkASSERT(!fHasAtlasTransform);
 
-        GrTextureProxy* textureProxy = fAtlas ? fAtlas->textureProxy() : nullptr;
+                GrTextureProxy* textureProxy = fAtlas ? fAtlas->textureProxy() : nullptr;
 
-        if (!textureProxy || !textureProxy->instantiate(resourceProvider)) {
-            fAtlasScale = fAtlasTranslate = {0, 0};
-            SkDEBUGCODE(fHasAtlasTransform = true);
-            return sk_sp<GrTexture>();
-        }
+                if (!textureProxy || !textureProxy->instantiate(resourceProvider)) {
+                    fAtlasScale = fAtlasTranslate = {0, 0};
+                    SkDEBUGCODE(fHasAtlasTransform = true);
+                    return sk_sp<GrTexture>();
+                }
 
-        sk_sp<GrTexture> texture = sk_ref_sp(textureProxy->peekTexture());
-        SkASSERT(texture);
-        SkASSERT(texture->asRenderTarget()->numSamples() == sampleCount);
-        SkASSERT(textureProxy->origin() == kTopLeft_GrSurfaceOrigin);
+                sk_sp<GrTexture> texture = sk_ref_sp(textureProxy->peekTexture());
+                SkASSERT(texture);
+                SkASSERT(texture->backendFormat() == format);
+                SkASSERT(texture->asRenderTarget()->numSamples() == sampleCount);
+                SkASSERT(textureProxy->origin() == kTopLeft_GrSurfaceOrigin);
 
-        fAtlasScale = {1.f / texture->width(), 1.f / texture->height()};
-        fAtlasTranslate.set(fDevToAtlasOffset.fX * fAtlasScale.x(),
-                            fDevToAtlasOffset.fY * fAtlasScale.y());
-        SkDEBUGCODE(fHasAtlasTransform = true);
+                fAtlasScale = {1.f / texture->width(), 1.f / texture->height()};
+                fAtlasTranslate.set(fDevToAtlasOffset.fX * fAtlasScale.x(),
+                                    fDevToAtlasOffset.fY * fAtlasScale.y());
+                SkDEBUGCODE(fHasAtlasTransform = true);
 
-        return texture;
-    }, atlasCoverageType, caps);
+                return texture;
+            },
+            atlasCoverageType, caps);
 
     fDeviceSpacePath = deviceSpacePath;
     fDeviceSpacePath.getBounds().roundOut(&fPathDevIBounds);
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 8070a75..08706a9 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -563,7 +563,8 @@
 #ifdef SK_BUILD_FOR_IOS
     // ETC2_RGB8
     info = &fFormatTable[GetFormatIndex(MTLPixelFormatETC2_RGB8)];
-    info->fFlags = FormatInfo::kTextureable_Flag;
+    // GrMtlGpu::onCreateCompressedTexture() not implemented.
+    info->fFlags = 0;
 #endif
 
     // Experimental (for Y416 and mutant P016/P010)
@@ -635,6 +636,11 @@
             if (MTLPixelFormatRGBA8Unorm == format) {
                 return kRGB_888X_GrPixelConfig;
             }
+#ifdef SK_BUILD_FOR_IOS
+            else if (MTLPixelFormatETC2_RGB8 == format) {
+                return kRGB_ETC1_GrPixelConfig;
+            }
+#endif
             break;
         case GrColorType::kRG_88:
             if (MTLPixelFormatRG8Unorm == format) {
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 2d940f3..efbd1b1 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -1128,8 +1128,23 @@
 }
 
 int GrVkCaps::getRenderTargetSampleCount(int requestedCount,
-                                         GrColorType, const GrBackendFormat& format) const {
-    if (!format.getVkFormat()) {
+                                         GrColorType colorType,
+                                         const GrBackendFormat& format) const {
+    VkFormat vkFormat;
+    if (const auto* temp = format.getVkFormat()) {
+        vkFormat = *temp;
+    } else {
+        return 0;
+    }
+
+    // Currently we don't allow RGB_888X to be renderable with R8G8B8A8_UNORM because we don't have
+    // a way to handle blends that reference dst alpha when the values in the dst alpha channel are
+    // uninitialized.
+    if (colorType == GrColorType::kRGB_888x && vkFormat == VK_FORMAT_R8G8B8A8_UNORM) {
+        return 0;
+    }
+    // We also do not support rendering to kGray.
+    if (GrColorTypeComponentFlags(colorType) & kGray_SkColorTypeComponentFlag) {
         return 0;
     }