Add GrColorFormatDesc GrBackendFormat::desc()

Will be used to figure out an appropriate SkColorType for
YUVA images made of texture planes.

Bug: chromium:1113801
Change-Id: I5e1733292a84e082068c9c3557f629856b7aea84
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410097
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index b1413c8..34b1c61 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -23,6 +23,7 @@
 class GrBackendSurfaceMutableStateImpl;
 class GrVkImageLayout;
 class GrGLTextureParameters;
+class GrColorFormatDesc;
 
 #ifdef SK_DAWN
 #include "dawn/webgpu_cpp.h"
@@ -119,6 +120,8 @@
      */
     uint32_t channelMask() const;
 
+    GrColorFormatDesc desc() const;
+
     /**
      * If the backend API is GL this gets the format as a GrGLFormat. Otherwise, returns
      * GrGLFormat::kUnknown.
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
index 35ee301..fbbcf9e 100644
--- a/src/gpu/GrBackendSurface.cpp
+++ b/src/gpu/GrBackendSurface.cpp
@@ -7,6 +7,7 @@
 
 #include "include/gpu/GrBackendSurface.h"
 
+#include "include/private/GrTypesPriv.h"
 #include "src/gpu/GrBackendSurfaceMutableStateImpl.h"
 #include "src/gpu/gl/GrGLUtil.h"
 
@@ -243,6 +244,39 @@
     }
 }
 
+GrColorFormatDesc GrBackendFormat::desc() const {
+    if (!this->isValid()) {
+        return GrColorFormatDesc::MakeInvalid();
+    }
+    switch (fBackend) {
+#ifdef SK_GL
+        case GrBackendApi::kOpenGL:
+            return GrGLFormatDesc(GrGLFormatFromGLEnum(fGLFormat));
+#endif
+#ifdef SK_VULKAN
+        case GrBackendApi::kVulkan:
+            return GrVkFormatDesc(fVk.fFormat);
+#endif
+#ifdef SK_METAL
+       case GrBackendApi::kMetal:
+            return GrMtlFormatDesc(fMtlFormat);
+#endif
+#ifdef SK_DAWN
+        case GrBackendApi::kDawn:
+            return GrDawnFormatDesc(fDawnFormat);
+#endif
+#ifdef SK_DIRECT3D
+        case GrBackendApi::kDirect3D:
+            return GrDxgiFormatDesc(fDxgiFormat);
+#endif
+        case GrBackendApi::kMock:
+            return GrGetColorTypeDesc(fMock.fColorType);
+
+        default:
+            return GrColorFormatDesc::MakeInvalid();
+    }
+}
+
 #ifdef SK_DEBUG
 bool GrBackendFormat::validateMock() const {
     int trueStates = 0;
diff --git a/src/gpu/d3d/GrD3DUtil.h b/src/gpu/d3d/GrD3DUtil.h
index dd6f4f9..52d98df 100644
--- a/src/gpu/d3d/GrD3DUtil.h
+++ b/src/gpu/d3d/GrD3DUtil.h
@@ -56,6 +56,48 @@
     }
 }
 
+static constexpr GrColorFormatDesc GrDxgiFormatDesc(DXGI_FORMAT format) {
+    switch (format) {
+        case DXGI_FORMAT_R8G8B8A8_UNORM:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_R8_UNORM:
+            return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_B8G8R8A8_UNORM:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_B5G6R5_UNORM:
+            return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_R16G16B16A16_FLOAT:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
+        case DXGI_FORMAT_R16_FLOAT:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
+        case DXGI_FORMAT_R8G8_UNORM:
+            return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_R10G10B10A2_UNORM:
+            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_B4G4R4A4_UNORM:
+            return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
+        case DXGI_FORMAT_R16_UNORM:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_R16G16_UNORM:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_R16G16B16A16_UNORM:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
+        case DXGI_FORMAT_R16G16_FLOAT:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
+
+        // Compressed texture formats are not expected to have a description.
+        case DXGI_FORMAT_BC1_UNORM: return GrColorFormatDesc::MakeInvalid();
+
+        // This type only describes color channels.
+        case DXGI_FORMAT_D24_UNORM_S8_UINT:    return GrColorFormatDesc::MakeInvalid();
+        case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return GrColorFormatDesc::MakeInvalid();
+
+        default: return GrColorFormatDesc::MakeInvalid();
+    }
+}
+
 static constexpr size_t GrDxgiFormatBytesPerBlock(DXGI_FORMAT format) {
     switch (format) {
         case DXGI_FORMAT_R8G8B8A8_UNORM:           return 4;
diff --git a/src/gpu/dawn/GrDawnUtil.h b/src/gpu/dawn/GrDawnUtil.h
index 775df20..9de687a 100644
--- a/src/gpu/dawn/GrDawnUtil.h
+++ b/src/gpu/dawn/GrDawnUtil.h
@@ -31,4 +31,18 @@
     }
 }
 
+static constexpr GrColorFormatDesc GrDawnFormatDesc(wgpu::TextureFormat format) {
+    switch (format) {
+        case wgpu::TextureFormat::RGBA8Unorm:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case wgpu::TextureFormat::BGRA8Unorm:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case wgpu::TextureFormat::R8Unorm:
+            return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
+
+        default:
+            return GrColorFormatDesc::MakeInvalid();
+    }
+}
+
 #endif // GrDawnUtil_DEFINED
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 5f7b2f4..fe947ec 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -71,6 +71,63 @@
     SkUNREACHABLE;
 }
 
+static constexpr GrColorFormatDesc GrGLFormatDesc(GrGLFormat format) {
+    switch (format) {
+        case GrGLFormat::kUnknown: return GrColorFormatDesc::MakeInvalid();
+
+        case GrGLFormat::kRGBA8:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kR8:
+            return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kALPHA8:
+            return GrColorFormatDesc::MakeAlpha(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kLUMINANCE8:
+            return GrColorFormatDesc::MakeGray(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kLUMINANCE8_ALPHA8:
+            return GrColorFormatDesc::MakeGrayAlpha(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kBGRA8:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRGB565:
+            return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRGBA16F:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
+        case GrGLFormat::kR16F:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
+        case GrGLFormat::kRGB8:
+            return GrColorFormatDesc::MakeRGB(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRG8:
+            return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRGB10_A2:
+            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRGBA4:
+            return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kSRGB8_ALPHA8:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
+        case GrGLFormat::kR16:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRG16:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRGBA16:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
+        case GrGLFormat::kRG16F:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
+        case GrGLFormat::kLUMINANCE16F:
+            return GrColorFormatDesc::MakeGray(16, GrColorTypeEncoding::kFloat);
+
+        // Compressed texture formats are not expected to have a description.
+        case GrGLFormat::kCOMPRESSED_ETC1_RGB8: return GrColorFormatDesc::MakeInvalid();
+        case GrGLFormat::kCOMPRESSED_RGB8_ETC2: return GrColorFormatDesc::MakeInvalid();
+        case GrGLFormat::kCOMPRESSED_RGB8_BC1:  return GrColorFormatDesc::MakeInvalid();
+        case GrGLFormat::kCOMPRESSED_RGBA8_BC1: return GrColorFormatDesc::MakeInvalid();
+
+        // This type only describes color channels.
+        case GrGLFormat::kSTENCIL_INDEX8:   return GrColorFormatDesc::MakeInvalid();
+        case GrGLFormat::kSTENCIL_INDEX16:  return GrColorFormatDesc::MakeInvalid();
+        case GrGLFormat::kDEPTH24_STENCIL8: return GrColorFormatDesc::MakeInvalid();
+    }
+    SkUNREACHABLE;
+}
+
 /**
  * The Vendor and Renderer enum values are lazily updated as required.
  */
diff --git a/src/gpu/mtl/GrMtlCppUtil.h b/src/gpu/mtl/GrMtlCppUtil.h
index 2e108e1..c095363 100644
--- a/src/gpu/mtl/GrMtlCppUtil.h
+++ b/src/gpu/mtl/GrMtlCppUtil.h
@@ -10,6 +10,7 @@
 
 #include "include/core/SkImage.h"
 #include "include/gpu/mtl/GrMtlTypes.h"
+#include "include/private/GrTypesPriv.h"
 
 class GrBackendFormat;
 
@@ -23,6 +24,8 @@
 
 uint32_t GrMtlFormatChannels(GrMTLPixelFormat);
 
+GrColorFormatDesc GrMtlFormatDesc(GrMTLPixelFormat);
+
 SkImage::CompressionType GrMtlBackendFormatToCompressionType(const GrBackendFormat& format);
 
 /**
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index 6564a27..60ebeb8 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -297,6 +297,62 @@
     }
 }
 
+GrColorFormatDesc GrMtlFormatDesc(GrMTLPixelFormat mtlFormat)  {
+    switch (mtlFormat) {
+        case MTLPixelFormatRGBA8Unorm:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case MTLPixelFormatR8Unorm:
+            return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
+        case MTLPixelFormatA8Unorm:
+            return GrColorFormatDesc::MakeAlpha(8, GrColorTypeEncoding::kUnorm);
+        case MTLPixelFormatBGRA8Unorm:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+#if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
+        case MTLPixelFormatB5G6R5Unorm:
+            return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
+#endif
+        case MTLPixelFormatRGBA16Float:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
+        case MTLPixelFormatR16Float:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
+        case MTLPixelFormatRG8Unorm:
+            return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
+        case MTLPixelFormatRGB10A2Unorm:
+            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
+#ifdef SK_BUILD_FOR_MAC
+        case MTLPixelFormatBGR10A2Unorm:
+            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
+#endif
+#if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
+        case MTLPixelFormatABGR4Unorm:
+            return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
+#endif
+        case MTLPixelFormatRGBA8Unorm_sRGB:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
+        case MTLPixelFormatR16Unorm:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
+        case MTLPixelFormatRG16Unorm:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
+        case MTLPixelFormatRGBA16Unorm:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
+        case MTLPixelFormatRG16Float:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
+
+        // Compressed texture formats are not expected to have a description.
+#ifdef SK_BUILD_FOR_IOS
+        case MTLPixelFormatETC2_RGB8: return GrColorFormatDesc::MakeInvalid();
+#else
+        case MTLPixelFormatBC1_RGBA:  return GrColorFormatDesc::MakeInvalid();
+#endif
+
+        // This type only describes color channels.
+        case MTLPixelFormatStencil8: return GrColorFormatDesc::MakeInvalid();
+
+        default:
+            return GrColorFormatDesc::MakeInvalid();
+    }
+}
+
 SkImage::CompressionType GrMtlBackendFormatToCompressionType(const GrBackendFormat& format) {
     MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
     return GrMtlFormatToCompressionType(mtlFormat);
diff --git a/src/gpu/vk/GrVkUtil.h b/src/gpu/vk/GrVkUtil.h
index 47d68a9..0836897 100644
--- a/src/gpu/vk/GrVkUtil.h
+++ b/src/gpu/vk/GrVkUtil.h
@@ -74,6 +74,57 @@
     }
 }
 
+static constexpr GrColorFormatDesc GrVkFormatDesc(VkFormat vkFormat) {
+    switch (vkFormat) {
+        case VK_FORMAT_R8G8B8A8_UNORM:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R8_UNORM:
+            return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_B8G8R8A8_UNORM:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R5G6B5_UNORM_PACK16:
+            return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R16G16B16A16_SFLOAT:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
+        case VK_FORMAT_R16_SFLOAT:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
+        case VK_FORMAT_R8G8B8_UNORM:
+            return GrColorFormatDesc::MakeRGB(8, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R8G8_UNORM:
+            return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
+            return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
+            return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R8G8B8A8_SRGB:
+            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
+        case VK_FORMAT_R16_UNORM:
+            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R16G16_UNORM:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R16G16B16A16_UNORM:
+            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
+        case VK_FORMAT_R16G16_SFLOAT:
+            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
+
+        // Compressed texture formats are not expected to have a description.
+        case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
+        case VK_FORMAT_BC1_RGB_UNORM_BLOCK:     return GrColorFormatDesc::MakeInvalid();
+        case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:    return GrColorFormatDesc::MakeInvalid();
+
+        // This type only describes color channels.
+        case VK_FORMAT_S8_UINT:            return GrColorFormatDesc::MakeInvalid();
+        case VK_FORMAT_D24_UNORM_S8_UINT:  return GrColorFormatDesc::MakeInvalid();
+        case VK_FORMAT_D32_SFLOAT_S8_UINT: return GrColorFormatDesc::MakeInvalid();
+
+        default: return GrColorFormatDesc::MakeInvalid();
+    }
+}
+
 static constexpr size_t GrVkFormatBytesPerBlock(VkFormat vkFormat) {
     switch (vkFormat) {
         case VK_FORMAT_R8G8B8A8_UNORM:            return 4;