Reduce GrCaps' reliance on GrPixelConfig

By itself this CL isn't all that compelling but I believe we need some intermediate path to wean ourselves off of GrPixelConfig. In particular, I believe isFormatTexturable will not need an SkColorType parameter in the future.

This is pulled out of:

https://skia-review.googlesource.com/c/skia/+/222781/ (Add bridge between GrContext::createBackendTexture and SkSurface::MakeFromBackendTexture)

which adds SkSurface::isCompatible - so the SkSurface_Gpu::isCompatible calls have been removed from this CL.

Change-Id: I6c2b8a2c4af98c1437b92c58513f34014e551b2e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/223188
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 3235c69..f9edab5 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -157,13 +157,16 @@
         return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt);
     }
 
+    virtual bool isFormatTexturable(SkColorType, const GrBackendFormat&) const = 0;
     virtual bool isConfigTexturable(GrPixelConfig) const = 0;
 
     // Returns whether a texture of the given config can be copied to a texture of the same config.
+    virtual bool isFormatCopyable(SkColorType, const GrBackendFormat&) const = 0;
     virtual bool isConfigCopyable(GrPixelConfig) const = 0;
 
     // Returns the maximum supported sample count for a config. 0 means the config is not renderable
     // 1 means the config is renderable but doesn't support MSAA.
+    virtual int maxRenderTargetSampleCount(SkColorType, const GrBackendFormat&) const = 0;
     virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0;
 
     // Returns the number of samples to use when performing internal draws to the given config with
@@ -185,6 +188,8 @@
     // color buffer of the given config or 0 if no such sample count is supported. If the requested
     // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0.
     // For historical reasons requestedCount==0 is handled identically to requestedCount==1.
+    virtual int getRenderTargetSampleCount(int requestedCount,
+                                           SkColorType, const GrBackendFormat&) const = 0;
     virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0;
     // TODO: Remove. Legacy name used by Chrome.
     int getSampleCount(int requestedCount, GrPixelConfig config) const {
diff --git a/src/gpu/GrContextThreadSafeProxy.cpp b/src/gpu/GrContextThreadSafeProxy.cpp
index 89c3a47..2e0758a 100644
--- a/src/gpu/GrContextThreadSafeProxy.cpp
+++ b/src/gpu/GrContextThreadSafeProxy.cpp
@@ -56,7 +56,7 @@
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
 
-    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, config);
+    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, ii.colorType(), backendFormat);
     if (!sampleCnt) {
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
@@ -65,7 +65,7 @@
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
 
-    if (isTextureable && !this->caps()->isConfigTexturable(config)) {
+    if (isTextureable && !this->caps()->isFormatTexturable(ii.colorType(), backendFormat)) {
         // Skia doesn't agree that this is textureable.
         return SkSurfaceCharacterization(); // return an invalid characterization
     }
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index d19871f..aa52c00 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -210,14 +210,14 @@
     }
 
     const SkImageInfo& info = srcImage->imageInfo();
-    GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
+    SkColorType ct = info.colorType();
 
-    if (kUnknown_GrPixelConfig == config) {
+    GrBackendFormat format = this->caps()->getBackendFormatFromColorType(ct);
+    if (!format.isValid()) {
         return nullptr;
     }
 
-    SkColorType ct = info.colorType();
-    if (!this->caps()->isConfigTexturable(config)) {
+    if (!this->caps()->isFormatTexturable(ct, format)) {
         SkBitmap copy8888;
         if (!copy8888.tryAllocPixels(info.makeColorType(kRGBA_8888_SkColorType)) ||
             !srcImage->readPixels(copy8888.pixmap(), 0, 0)) {
@@ -225,22 +225,25 @@
         }
         copy8888.setImmutable();
         srcImage = SkMakeImageFromRasterBitmap(copy8888, kNever_SkCopyPixelsMode);
-        config = kRGBA_8888_GrPixelConfig;
         ct = kRGBA_8888_SkColorType;
-    }
-
-    GrBackendFormat format = this->caps()->getBackendFormatFromColorType(ct);
-    if (!format.isValid()) {
-        return nullptr;
+        format = this->caps()->getBackendFormatFromColorType(ct);
+        if (!format.isValid()) {
+            return nullptr;
+        }
     }
 
     if (SkToBool(descFlags & kRenderTarget_GrSurfaceFlag)) {
-        sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, config);
+        sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, ct, format);
         if (!sampleCnt) {
             return nullptr;
         }
     }
 
+    GrPixelConfig config = SkColorType2GrPixelConfig(ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return nullptr;
+    }
+
     GrSurfaceDesc desc;
     desc.fWidth = srcImage->width();
     desc.fHeight = srcImage->height();
@@ -328,9 +331,13 @@
     }
 
     SkColorType colorType = bitmap.info().colorType();
+    GrBackendFormat format = this->caps()->getBackendFormatFromColorType(colorType);
+    if (!format.isValid()) {
+        return nullptr;
+    }
     GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
 
-    if (!this->caps()->isConfigTexturable(desc.fConfig)) {
+    if (!this->caps()->isFormatTexturable(colorType, format)) {
         SkBitmap copy8888;
         if (!copy8888.tryAllocPixels(bitmap.info().makeColorType(kRGBA_8888_SkColorType)) ||
             !bitmap.readPixels(copy8888.pixmap())) {
@@ -340,12 +347,12 @@
         baseLevel = SkMakeImageFromRasterBitmap(copy8888, kNever_SkCopyPixelsMode);
         desc.fConfig = kRGBA_8888_GrPixelConfig;
         colorType = kRGBA_8888_SkColorType;
+        format = this->caps()->getBackendFormatFromColorType(colorType);
+        if (!format.isValid()) {
+            return nullptr;
+        }
     }
 
-    const GrBackendFormat format = this->caps()->getBackendFormatFromColorType(colorType);
-    if (!format.isValid()) {
-        return nullptr;
-    }
 
     SkPixmap pixmap;
     SkAssertResult(baseLevel->peekPixels(&pixmap));
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 8405436..a7dc335 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -3108,6 +3108,25 @@
     return fbInfo.fFBOID != 0;
 }
 
+bool GrGLCaps::isFormatTexturable(SkColorType ct, const GrBackendFormat& format) const {
+    GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return false;
+    }
+
+    return this->isConfigTexturable(config);
+}
+
+int GrGLCaps::getRenderTargetSampleCount(int requestedCount, SkColorType ct,
+                                         const GrBackendFormat& format) const {
+    GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return 0;
+    }
+
+    return this->getRenderTargetSampleCount(requestedCount, config);
+}
+
 int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
     requestedCount = SkTMax(1, requestedCount);
     int count = fConfigTable[config].fColorSampleCounts.count();
@@ -3131,6 +3150,15 @@
     return 0;
 }
 
+int GrGLCaps::maxRenderTargetSampleCount(SkColorType ct, const GrBackendFormat& format) const {
+    GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return 0;
+    }
+
+    return this->maxRenderTargetSampleCount(config);
+}
+
 int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
     const auto& table = fConfigTable[config].fColorSampleCounts;
     if (!table.count()) {
@@ -3143,6 +3171,15 @@
     return count;
 }
 
+bool GrGLCaps::isFormatCopyable(SkColorType ct, const GrBackendFormat& format) const {
+    GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return false;
+    }
+
+    return this->isConfigCopyable(config);
+}
+
 GrPixelConfig validate_sized_format(GrGLenum format, SkColorType ct, GrGLStandard standard) {
     switch (ct) {
         case kUnknown_SkColorType:
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index cc7cb35..48c5c79 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -106,13 +106,20 @@
     GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
              const GrGLInterface* glInterface);
 
+    bool isFormatTexturable(SkColorType, const GrBackendFormat&) const override;
+
     bool isConfigTexturable(GrPixelConfig config) const override {
         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
     }
 
+    int getRenderTargetSampleCount(int requestedCount,
+                                   SkColorType, const GrBackendFormat&) const override;
     int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override;
+
+    int maxRenderTargetSampleCount(SkColorType, const GrBackendFormat&) const override;
     int maxRenderTargetSampleCount(GrPixelConfig config) const override;
 
+    bool isFormatCopyable(SkColorType, const GrBackendFormat&) const override;
     bool isConfigCopyable(GrPixelConfig config) const override {
         // In GL we have three ways to be able to copy. CopyTexImage, blit, and draw. CopyTexImage
         // requires the src to be an FBO attachment, blit requires both src and dst to be FBO
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index 41fff59..f111296 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -35,14 +35,40 @@
 
         this->applyOptionsOverrides(contextOptions);
     }
+
+    bool isFormatTexturable(SkColorType, const GrBackendFormat& format) const override {
+        if (!format.getMockFormat()) {
+            return false;
+        }
+
+        return this->isConfigTexturable(*format.getMockFormat());
+    }
+
     bool isConfigTexturable(GrPixelConfig config) const override {
         return fOptions.fConfigOptions[config].fTexturable;
     }
 
+    bool isFormatCopyable(SkColorType, const GrBackendFormat& format) const override {
+        if (!format.getMockFormat()) {
+            return false;
+        }
+
+        return this->isConfigCopyable(*format.getMockFormat());
+    }
+
     bool isConfigCopyable(GrPixelConfig config) const override {
         return false;
     }
 
+    int getRenderTargetSampleCount(int requestCount,
+                                   SkColorType, const GrBackendFormat& format) const override {
+        if (!format.getMockFormat()) {
+            return 0;
+        }
+
+        return this->getRenderTargetSampleCount(requestCount, *format.getMockFormat());
+    }
+
     int getRenderTargetSampleCount(int requestCount, GrPixelConfig config) const override {
         requestCount = SkTMax(requestCount, 1);
         switch (fOptions.fConfigOptions[config].fRenderability) {
@@ -56,6 +82,14 @@
         return 0;
     }
 
+    int maxRenderTargetSampleCount(SkColorType, const GrBackendFormat& format) const override {
+        if (!format.getMockFormat()) {
+            return 0;
+        }
+
+        return this->maxRenderTargetSampleCount(*format.getMockFormat());
+    }
+
     int maxRenderTargetSampleCount(GrPixelConfig config) const override {
         switch (fOptions.fConfigOptions[config].fRenderability) {
             case GrMockOptions::ConfigOptions::Renderability::kNo:
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 091fc7f..60e7ddd 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -26,20 +26,25 @@
     GrMtlCaps(const GrContextOptions& contextOptions, id<MTLDevice> device,
               MTLFeatureSet featureSet);
 
+    bool isFormatTexturable(SkColorType, const GrBackendFormat&) const override;
+
     bool isConfigTexturable(GrPixelConfig config) const override {
         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
     }
 
+    int getRenderTargetSampleCount(int requestedCount,
+                                   SkColorType, const GrBackendFormat&) const override;
     int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const override;
+
+    int maxRenderTargetSampleCount(SkColorType, const GrBackendFormat&) const override;
     int maxRenderTargetSampleCount(GrPixelConfig) const override;
 
     ReadFlags surfaceSupportsReadPixels(const GrSurface*) const override {
         return kSupported_ReadFlag;
     }
 
-    bool isConfigCopyable(GrPixelConfig config) const override {
-        return true;
-    }
+    bool isFormatCopyable(SkColorType, const GrBackendFormat&) const override { return true; }
+    bool isConfigCopyable(GrPixelConfig) const override { return true; }
 
     /**
      * Returns both a supported and most prefered stencil format to use in draws.
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index f303c85..432024e 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -231,6 +231,23 @@
     fHalfFloatVertexAttributeSupport = true;
 }
 
+bool GrMtlCaps::isFormatTexturable(SkColorType ct, const GrBackendFormat& format) const {
+    GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return false;
+    }
+
+    return this->isConfigTexturable(config);
+}
+
+int GrMtlCaps::maxRenderTargetSampleCount(SkColorType ct, const GrBackendFormat& format) const {
+    GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return false;
+    }
+
+    return this->maxRenderTargetSampleCount(config);
+}
 
 int GrMtlCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
     if (fConfigTable[config].fFlags & ConfigInfo::kMSAA_Flag) {
@@ -241,6 +258,16 @@
     return 0;
 }
 
+int GrMtlCaps::getRenderTargetSampleCount(int requestedCount,
+                                          SkColorType ct, const GrBackendFormat& format) const {
+    GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
+    if (kUnknown_GrPixelConfig == config) {
+        return false;
+    }
+
+    return this->getRenderTargetSampleCount(requestedCount, config);
+}
+
 int GrMtlCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
     requestedCount = SkTMax(requestedCount, 1);
     if (fConfigTable[config].fFlags & ConfigInfo::kMSAA_Flag) {
@@ -707,4 +734,3 @@
 GrSwizzle GrMtlCaps::getOutputSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
     return get_swizzle(format, colorType, true);
 }
-
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index dfd6ef0..7370667 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -804,6 +804,14 @@
     }
 }
 
+bool GrVkCaps::isFormatTexturable(SkColorType, const GrBackendFormat& format) const {
+    if (!format.getVkFormat()) {
+        return false;
+    }
+
+    return this->isFormatTexturable(*format.getVkFormat());
+}
+
 bool GrVkCaps::isFormatTexturable(VkFormat format) const {
     if (!GrVkFormatIsSupported(format)) {
         return false;
@@ -825,6 +833,15 @@
     return this->maxRenderTargetSampleCount(format) > 0;
 }
 
+int GrVkCaps::getRenderTargetSampleCount(int requestedCount,
+                                         SkColorType, const GrBackendFormat& format) const {
+    if (!format.getVkFormat()) {
+        return 0;
+    }
+
+    return this->getRenderTargetSampleCount(requestedCount, *format.getVkFormat());
+}
+
 int GrVkCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
     // Currently we don't allow RGB_888X to be renderable because we don't have a way to handle
     // blends that reference dst alpha when the values in the dst alpha channel are uninitialized.
@@ -864,6 +881,14 @@
     return 0;
 }
 
+int GrVkCaps::maxRenderTargetSampleCount(SkColorType, const GrBackendFormat& format) const {
+    if (!format.getVkFormat()) {
+        return 0;
+    }
+
+    return this->maxRenderTargetSampleCount(*format.getVkFormat());
+}
+
 int GrVkCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
     // Currently we don't allow RGB_888X to be renderable because we don't have a way to handle
     // blends that reference dst alpha when the values in the dst alpha channel are uninitialized.
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 204c3d0..99235ec 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -32,17 +32,21 @@
              uint32_t instanceVersion, uint32_t physicalDeviceVersion,
              const GrVkExtensions& extensions, GrProtected isProtected = GrProtected::kNo);
 
+    bool isFormatTexturable(SkColorType, const GrBackendFormat&) const override;
     bool isFormatTexturable(VkFormat) const;
     bool isConfigTexturable(GrPixelConfig config) const override;
 
-    bool isConfigCopyable(GrPixelConfig config) const override {
-        return true;
-    }
+    bool isFormatCopyable(SkColorType, const GrBackendFormat&) const override { return true; }
+    bool isConfigCopyable(GrPixelConfig config) const override { return true; }
 
     bool isFormatRenderable(VkFormat) const;
 
+    int getRenderTargetSampleCount(int requestedCount,
+                                   SkColorType, const GrBackendFormat&) const override;
     int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override;
     int getRenderTargetSampleCount(int requestedCount, VkFormat) const;
+
+    int maxRenderTargetSampleCount(SkColorType, const GrBackendFormat&) const override;
     int maxRenderTargetSampleCount(GrPixelConfig config) const override;
     int maxRenderTargetSampleCount(VkFormat format) const;
 
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 1e579c6..51f4767 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -724,13 +724,13 @@
         // First check that we'll be able to do the copy to the to the R8G8B8 image in the end via a
         // blit or draw.
         if (!this->vkCaps().formatCanBeDstofBlit(VK_FORMAT_R8G8B8_UNORM, tex->isLinearTiled()) &&
-            !this->vkCaps().maxRenderTargetSampleCount(kRGB_888_GrPixelConfig)) {
+            !this->vkCaps().maxRenderTargetSampleCount(VK_FORMAT_R8G8B8_UNORM)) {
             return false;
         }
         mipLevelCount = 1;
     }
 
-    SkASSERT(this->caps()->isConfigTexturable(tex->config()));
+    SkASSERT(this->vkCaps().isFormatTexturable(tex->imageFormat()));
     int bpp = GrColorTypeBytesPerPixel(dataColorType);
 
     // texels is const.
@@ -917,7 +917,7 @@
         return false;
     }
 
-    SkASSERT(this->caps()->isConfigTexturable(tex->config()));
+    SkASSERT(this->vkCaps().isFormatTexturable(tex->imageFormat()));
 
     SkTArray<size_t> individualMipOffsets(mipLevelCount);
     individualMipOffsets.push_back(0);
@@ -1343,6 +1343,12 @@
     if (!backendFormat.isValid()) {
         return nullptr;
     }
+    int sampleCnt = this->caps()->getRenderTargetSampleCount(1, imageInfo.colorType(),
+                                                             backendFormat);
+    if (!sampleCnt) {
+        return nullptr;
+    }
+
     GrPixelConfig config = this->caps()->getConfigFromBackendFormat(backendFormat,
                                                                     imageInfo.colorType());
     if (config == kUnknown_GrPixelConfig) {
@@ -1354,10 +1360,7 @@
     desc.fWidth = imageInfo.width();
     desc.fHeight = imageInfo.height();
     desc.fConfig = config;
-    desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(1, config);
-    if (!desc.fSampleCnt) {
-        return nullptr;
-    }
+    desc.fSampleCnt = sampleCnt;
 
     return GrVkRenderTarget::MakeSecondaryCBRenderTarget(this, desc, vkInfo);
 }
@@ -1893,6 +1896,7 @@
                                                GrRenderable renderable,
                                                const void* srcData, size_t rowBytes,
                                                const SkColor4f* color, GrProtected isProtected) {
+    const GrVkCaps& caps = this->vkCaps();
     this->handleDirtyContext();
 
     if (fProtectedContext != isProtected) {
@@ -1900,7 +1904,7 @@
         return GrBackendTexture();
     }
 
-    if (w > this->caps()->maxTextureSize() || h > this->caps()->maxTextureSize()) {
+    if (w > caps.maxTextureSize() || h > caps.maxTextureSize()) {
         return GrBackendTexture();
     }
 
@@ -1910,14 +1914,14 @@
         return GrBackendTexture();
     }
 
-    GrPixelConfig config;
-
-    if (!vk_format_to_pixel_config(*vkFormat, &config)) {
-        SkDebugf("Could net get vkformat\n");
+    if (!caps.isFormatTexturable(*vkFormat)) {
+        SkDebugf("Config is not texturable\n");
         return GrBackendTexture();
     }
-    if (!this->caps()->isConfigTexturable(config)) {
-        SkDebugf("Config is not texturable\n");
+
+    GrPixelConfig config;
+    if (!vk_format_to_pixel_config(*vkFormat, &config)) {
+        SkDebugf("Could net get vkformat\n");
         return GrBackendTexture();
     }
 
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 018d7a8..78b726d 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -484,7 +484,7 @@
             // We current disallow uninitialized ETC1 textures in the GL backend
             continue;
         }
-        if (!glCaps->isConfigTexturable(combo.fConfig)) {
+        if (!glCaps->isFormatTexturable(combo.fColorType, format)) {
             continue;
         }
 
diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp
index 683e5c3..373d1f9 100644
--- a/tests/DeferredDisplayListTest.cpp
+++ b/tests/DeferredDisplayListTest.cpp
@@ -70,6 +70,7 @@
     int sampleCount() const { return fSampleCount; }
 
     void setColorType(SkColorType ct) { fColorType = ct; }
+    SkColorType colorType() const { return fColorType; }
     void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
     void setTextureable(bool isTextureable) { fIsTextureable = isTextureable; }
     void setShouldCreateMipMaps(bool shouldCreateMipMaps) {
@@ -162,6 +163,8 @@
     sk_sp<SkSurface> make(GrContext* context, GrBackendTexture* backend) const {
         GrGpu* gpu = context->priv().getGpu();
 
+        const SkSurfaceCharacterization c = this->createCharacterization(context);
+
         GrMipMapped mipmapped = !fIsTextureable
                                         ? GrMipMapped::kNo
                                         : GrMipMapped(fShouldCreateMipMaps);
@@ -181,8 +184,11 @@
                 return nullptr;
             }
 
-            return SkSurface::MakeFromBackendRenderTarget(context, backendRT, fOrigin,
-                                                          fColorType, fColorSpace, &fSurfaceProps);
+            sk_sp<SkSurface> result = SkSurface::MakeFromBackendRenderTarget(context, backendRT,
+                                                                             fOrigin, fColorType,
+                                                                             fColorSpace,
+                                                                             &fSurfaceProps);
+            return result;
         }
 
         *backend = context->createBackendTexture(fWidth, fHeight, fColorType,
@@ -281,6 +287,7 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
     GrContext* context = ctxInfo.grContext();
     GrGpu* gpu = context->priv().getGpu();
+    const GrCaps* caps = context->priv().caps();
 
     // Create a bitmap that we can readback into
     SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
@@ -324,14 +331,8 @@
         }
 
         if (SurfaceParameters::kSampleCount == i) {
-            SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
-
-            int supportedSampleCount = context->priv().caps()->getRenderTargetSampleCount(
-                    params.sampleCount(),
-                    gpuSurf->getDevice()
-                            ->accessRenderTargetContext()
-                            ->asRenderTargetProxy()
-                            ->config());
+            int supportedSampleCount = caps->getRenderTargetSampleCount(
+                    params.sampleCount(), params.colorType(), backend.getBackendFormat());
             if (1 == supportedSampleCount) {
                 // If changing the sample count won't result in a different
                 // surface characterization, skip this step
@@ -341,8 +342,7 @@
             }
         }
 
-        if (SurfaceParameters::kMipMipCount == i &&
-            !context->priv().caps()->mipMapSupport()) {
+        if (SurfaceParameters::kMipMipCount == i && !caps->mipMapSupport()) {
             // If changing the mipmap setting won't result in a different surface characterization,
             // skip this step
             s = nullptr;
@@ -508,20 +508,14 @@
 
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
-// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
-DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
-    GrContext* context = ctxInfo.grContext();
-
-    for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
-        SurfaceParameters params(context->backend());
-        params.modify(i);
-
-        SkSurfaceCharacterization c = params.createCharacterization(context);
-        GrBackendTexture backend;
+static void test_make_render_target(skiatest::Reporter* reporter,
+                                    GrContext* context,
+                                    const SurfaceParameters& params) {
+    {
+        const SkSurfaceCharacterization c = params.createCharacterization(context);
 
         if (!c.isValid()) {
+            GrBackendTexture backend;
             sk_sp<SkSurface> tmp = params.make(context, &backend);
 
             // If we couldn't characterize the surface we shouldn't be able to create it either
@@ -530,34 +524,57 @@
                 tmp = nullptr;
                 params.cleanUpBackEnd(context, backend);
             }
+            return;
+        }
+    }
+
+    const SkSurfaceCharacterization c = params.createCharacterization(context);
+    GrBackendTexture backend;
+
+    {
+        sk_sp<SkSurface> s = params.make(context, &backend);
+        REPORTER_ASSERT(reporter, s);
+        if (!s) {
+            REPORTER_ASSERT(reporter, !c.isValid());
+            params.cleanUpBackEnd(context, backend);
+            return;
+        }
+
+        REPORTER_ASSERT(reporter, c.isValid());
+        // Note that we're leaving 'backend' live here
+    }
+
+    // Make an SkSurface from scratch
+    {
+        sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
+        REPORTER_ASSERT(reporter, s);
+    }
+
+    params.cleanUpBackEnd(context, backend);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// This tests the SkSurface::MakeRenderTarget variants that take an SkSurfaceCharacterization.
+// In particular, the SkSurface, backendTexture and SkSurfaceCharacterization
+// should always be compatible.
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
+    GrContext* context = ctxInfo.grContext();
+
+    for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
+
+        if (SurfaceParameters::kFBO0Count == i) {
+            // MakeRenderTarget doesn't support FBO0
             continue;
         }
 
+        SurfaceParameters params(context->backend());
+        params.modify(i);
+
         if (!context->priv().caps()->mipMapSupport()) {
             params.setShouldCreateMipMaps(false);
         }
-        sk_sp<SkSurface> s = params.make(context, &backend);
-        if (!s) {
-            REPORTER_ASSERT(reporter, !c.isValid());
-            continue;
-        }
 
-        REPORTER_ASSERT(reporter, c.isValid());
-
-        if (SurfaceParameters::kFBO0Count == i) {
-            // MakeRenderTarget doesn't support FBO0
-            params.cleanUpBackEnd(context, backend);
-            continue;
-        }
-
-        s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
-        REPORTER_ASSERT(reporter, s);
-
-        SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
-        REPORTER_ASSERT(reporter, g->isCompatible(c));
-
-        s = nullptr;
-        params.cleanUpBackEnd(context, backend);
+        test_make_render_target(reporter, context, params);
     }
 }
 
@@ -902,7 +919,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-
 // Test colorType and pixelConfig compatibility.
 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
     GrContext* context = ctxInfo.grContext();
@@ -914,46 +930,11 @@
         params.setColorType(colorType);
         params.setColorSpace(nullptr);
 
-        SkSurfaceCharacterization c = params.createCharacterization(context);
-        GrBackendTexture backend;
-
-        if (!c.isValid()) {
-            sk_sp<SkSurface> tmp = params.make(context, &backend);
-
-            // If we couldn't characterize the surface we shouldn't be able to create it either
-            REPORTER_ASSERT(reporter, !tmp);
-            if (tmp) {
-                tmp = nullptr;
-                params.cleanUpBackEnd(context, backend);
-            }
-            continue;
-        }
-
         if (!context->priv().caps()->mipMapSupport()) {
             params.setShouldCreateMipMaps(false);
         }
-        sk_sp<SkSurface> s = params.make(context, &backend);
-        REPORTER_ASSERT(reporter, s);
-        if (!s) {
-            s = nullptr;
-            params.cleanUpBackEnd(context, backend);
-            continue;
-        }
 
-        SkSurface_Gpu* gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
-        REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
-
-        s = nullptr;
-        params.cleanUpBackEnd(context, backend);
-
-        s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
-        REPORTER_ASSERT(reporter, s);
-        if (!s) {
-            continue;
-        }
-
-        gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
-        REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
+        test_make_render_target(reporter, context, params);
     }
 
 }
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 850f426..5a26ca8 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -147,13 +147,15 @@
                                                                  const GrCaps* caps) {
     GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
                                                 : kBottomLeft_GrSurfaceOrigin;
-    int sampleCnt =
-            random->nextBool() ? caps->getRenderTargetSampleCount(2, kRGBA_8888_GrPixelConfig) : 1;
-    // Above could be 0 if msaa isn't supported.
-    sampleCnt = SkTMax(1, sampleCnt);
 
     const GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
 
+    int sampleCnt = random->nextBool()
+                           ? caps->getRenderTargetSampleCount(2, kRGBA_8888_SkColorType, format)
+                           : 1;
+    // Above could be 0 if msaa isn't supported.
+    sampleCnt = SkTMax(1, sampleCnt);
+
     sk_sp<GrRenderTargetContext> renderTargetContext(
         context->priv().makeDeferredRenderTargetContext(format,
                                                         SkBackingFit::kExact,
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 2391559..7f831b7 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -121,12 +121,16 @@
 DEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angle_es3, reporter,
                          ctxInfo, nullptr) {
     GrContext* context = ctxInfo.grContext();
-    if (context->priv().caps()->avoidStencilBuffers()) {
+    const GrCaps* caps = context->priv().caps();
+
+    if (caps->avoidStencilBuffers()) {
         return;
     }
 
     GrResourceProvider* resourceProvider = context->priv().resourceProvider();
 
+    GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
+
     sk_sp<GrRenderTarget> smallRT0 = create_RT_with_SB(resourceProvider, 4, 1, SkBudgeted::kYes);
     REPORTER_ASSERT(reporter, smallRT0);
 
@@ -155,7 +159,7 @@
     }
 
     int smallSampleCount =
-            context->priv().caps()->getRenderTargetSampleCount(2, kRGBA_8888_GrPixelConfig);
+            context->priv().caps()->getRenderTargetSampleCount(2, kRGBA_8888_SkColorType, format);
     if (smallSampleCount > 1) {
         // An RT with a different sample count should not share.
         sk_sp<GrRenderTarget> smallMSAART0 = create_RT_with_SB(resourceProvider, 4,
@@ -177,7 +181,7 @@
         // But one with a larger sample count should not. (Also check that the two requests didn't
         // rounded up to the same actual sample count or else they could share.).
         int bigSampleCount = context->priv().caps()->getRenderTargetSampleCount(
-                5, kRGBA_8888_GrPixelConfig);
+                5, kRGBA_8888_SkColorType, format);
         if (bigSampleCount > 0 && bigSampleCount != smallSampleCount) {
             sk_sp<GrRenderTarget> smallMSAART2 = create_RT_with_SB(resourceProvider, 4,
                                                                    bigSampleCount,
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 9a38a4f..5496bb0 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -141,7 +141,7 @@
         if (surf) {
             auto* rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext();
             int storedCnt = rtc->numSamples();
-            int allowedCnt = context->priv().caps()->getSampleCount(
+            int allowedCnt = context->priv().caps()->getRenderTargetSampleCount(
                     storedCnt, rtc->asSurfaceProxy()->config());
             REPORTER_ASSERT(reporter, storedCnt == allowedCnt,
                             "Should store an allowed sample count (%d vs %d)", allowedCnt,
@@ -157,7 +157,7 @@
         if (surf) {
             auto* rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext();
             int storedCnt = rtc->numSamples();
-            int allowedCnt = context->priv().caps()->getSampleCount(
+            int allowedCnt = context->priv().caps()->getRenderTargetSampleCount(
                     storedCnt, rtc->asSurfaceProxy()->config());
             REPORTER_ASSERT(reporter, storedCnt == allowedCnt,
                             "Should store an allowed sample count (%d vs %d)", allowedCnt,