Add asserts to make sure we always have valid GrBackendFormats before creating proxies.

Change-Id: I59dd970b6fd512f2e2ee08cc821b758b950a2b53
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/220743
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 95dc735..3620881 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -402,6 +402,25 @@
     return proxy;
 }
 
+#ifdef SK_DEBUG
+static bool validate_backend_format_and_config(const GrCaps* caps,
+                                               const GrBackendFormat& format,
+                                               GrPixelConfig config) {
+    if (kUnknown_GrPixelConfig == config) {
+        return false;
+    }
+    SkColorType colorType = GrColorTypeToSkColorType(GrPixelConfigToColorType(config));
+    if (colorType == kUnknown_SkColorType) {
+        // We should add support for validating GrColorType with a GrBackendFormat. Currently we
+        // only support SkColorType. For now we just assume things that don't have a corresponding
+        // SkColorType are correct.
+        return true;
+    }
+    GrPixelConfig testConfig = caps->getConfigFromBackendFormat(format, colorType);
+    return testConfig != kUnknown_GrPixelConfig;
+}
+#endif
+
 sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrBackendFormat& format,
                                                    const GrSurfaceDesc& desc,
                                                    GrSurfaceOrigin origin,
@@ -409,6 +428,7 @@
                                                    SkBackingFit fit,
                                                    SkBudgeted budgeted,
                                                    GrInternalSurfaceFlags surfaceFlags) {
+    SkASSERT(validate_backend_format_and_config(this->caps(), format, desc.fConfig));
     if (GrMipMapped::kYes == mipMapped) {
         // SkMipMap doesn't include the base level in the level count so we have to add 1
         int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
@@ -492,6 +512,11 @@
         return nullptr;
     }
 
+#ifdef SK_DEBUG
+    SkASSERT(validate_backend_format_and_config(this->caps(), backendTex.getBackendFormat(),
+                                                backendTex.config()));
+#endif
+
     GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
 
     sk_sp<GrTexture> tex =
@@ -525,6 +550,9 @@
         return nullptr;
     }
 
+    SkASSERT(validate_backend_format_and_config(this->caps(), backendTex.getBackendFormat(),
+                                                backendTex.config()));
+
     GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
 
     sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config());
@@ -562,6 +590,14 @@
         return nullptr;
     }
 
+#ifdef SK_DEBUG
+    GrColorType colorType = GrPixelConfigToColorType(backendRT.config());
+    GrPixelConfig testConfig =
+            this->caps()->validateBackendRenderTarget(backendRT,
+                                                      GrColorTypeToSkColorType(colorType));
+    SkASSERT(testConfig != kUnknown_GrPixelConfig);
+#endif
+
     GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
 
     sk_sp<GrRenderTarget> rt = resourceProvider->wrapBackendRenderTarget(backendRT);
@@ -593,6 +629,9 @@
         return nullptr;
     }
 
+    SkASSERT(validate_backend_format_and_config(this->caps(), backendTex.getBackendFormat(),
+                                                backendTex.config()));
+
     GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
 
     sk_sp<GrRenderTarget> rt =
@@ -683,6 +722,7 @@
         return nullptr;
     }
 
+    SkASSERT(validate_backend_format_and_config(this->caps(), format, desc.fConfig));
 
 #ifdef SK_DEBUG
     if (SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)) {
@@ -714,6 +754,7 @@
     }
 
     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
+    SkASSERT(validate_backend_format_and_config(this->caps(), format, desc.fConfig));
 
 #ifdef SK_DEBUG
     if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kMixedSampled)) {
@@ -747,6 +788,7 @@
 sk_sp<GrTextureProxy> GrProxyProvider::MakeFullyLazyProxy(
         LazyInstantiateCallback&& callback, const GrBackendFormat& format, Renderable renderable,
         GrSurfaceOrigin origin, GrPixelConfig config, const GrCaps& caps, int sampleCnt) {
+    SkASSERT(validate_backend_format_and_config(&caps, format, config));
     GrSurfaceDesc desc;
     GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
     if (Renderable::kYes == renderable) {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 3bac37e..509eed1 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -161,6 +161,9 @@
     }
     GrBackendFormat format =
             context->priv().caps()->getBackendFormatFromColorType(origInfo.colorType());
+    if (!format.isValid()) {
+        return nullptr;
+    }
     // This method is used to create SkGpuDevice's for SkSurface_Gpus. In this case
     // they need to be exact.
     return context->priv().makeDeferredRenderTargetContext(
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 34ecb67..da2e374 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -511,7 +511,7 @@
             }
             break;
         case kRGBA_F32_SkColorType:
-            if (MTLPixelFormatR32Float == format) {
+            if (MTLPixelFormatRGBA32Float == format) {
                 return kRGBA_float_GrPixelConfig;
             }
             break;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 21d74b7..7d3c772 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -86,7 +86,7 @@
 
     sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef(context);
 
-    GrBackendFormat format = proxy->backendFormat().makeTexture2D();
+    GrBackendFormat format = context->priv().caps()->getBackendFormatFromColorType(targetCT);
     if (!format.isValid()) {
         return nullptr;
     }
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index afe3f5c..b655053 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -117,6 +117,10 @@
 
     for (GrPixelConfig config : configs) {
         for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
+            if (config == kUnknown_GrPixelConfig) {
+                // It is not valid to be calling into GrProxyProvider with an unknown pixel config.
+                continue;
+            }
             desc.fFlags = kNone_GrSurfaceFlags;
             desc.fConfig = config;
             desc.fSampleCnt = 1;
@@ -131,6 +135,9 @@
             GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(config, &srgbEncoded);
             const GrBackendFormat format =
                     caps->getBackendFormatFromGrColorType(colorType, srgbEncoded);
+            if (!format.isValid()) {
+                continue;
+            }
 
             sk_sp<GrTextureProxy> proxy =
                     proxyProvider->createMipMapProxy(format, desc, origin, SkBudgeted::kNo);
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 8b5e130..cdc4421 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -136,6 +136,9 @@
                                     GrPixelConfigToColorTypeAndEncoding(config, &srgbEncoded);
                             const GrBackendFormat format =
                                     caps.getBackendFormatFromGrColorType(colorType, srgbEncoded);
+                            if (!format.isValid()) {
+                                continue;
+                            }
 
                             {
                                 sk_sp<GrTexture> tex;
@@ -254,9 +257,11 @@
                 // Test wrapping FBO 0 (with made up properties). This tests sample count and the
                 // special case where FBO 0 doesn't support window rectangles.
                 if (GrBackendApi::kOpenGL == ctxInfo.backend()) {
+                    GrBackendFormat beFormat = caps.getBackendFormatFromColorType(colorType);
                     GrGLFramebufferInfo fboInfo;
                     fboInfo.fFBOID = 0;
-                    fboInfo.fFormat = GR_GL_RGBA8;
+                    SkASSERT(beFormat.getGLFormat());
+                    fboInfo.fFormat = *beFormat.getGLFormat();
                     static constexpr int kStencilBits = 8;
                     GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples,
                                                     kStencilBits, fboInfo);
diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp
index 5214a5d..e444f16 100644
--- a/tests/RectangleTextureTest.cpp
+++ b/tests/RectangleTextureTest.cpp
@@ -151,6 +151,7 @@
         GrGLTextureInfo rectangleInfo;
         rectangleInfo.fID = rectTexID;
         rectangleInfo.fTarget = GR_GL_TEXTURE_RECTANGLE;
+        rectangleInfo.fFormat = GR_GL_RGBA8;
 
         GrBackendTexture rectangleTex(kWidth, kHeight, GrMipMapped::kNo, rectangleInfo);
         rectangleTex.setPixelConfig(kRGBA_8888_GrPixelConfig);