Move read swizzle from GL ConfigInfo to FormatInfo.
With this change I also removed GrPixelConfig as param to supportedReadPixelsColorType().
This meant some updates had to be made to Vulkan and Metal to make sure they return the
right GrColorType.
Bug: skia:6718
Change-Id: I71b6360489cf499692c7b777e5915090fad05c56
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228349
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index b324429..e8f51e9 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -372,10 +372,9 @@
}
GrCaps::SupportedRead GrCaps::supportedReadPixelsColorType(GrColorType srcColorType,
- GrPixelConfig config,
const GrBackendFormat&,
GrColorType dstColorType) const {
- return SupportedRead{GrSwizzle::RGBA(), GrPixelConfigToColorType(config)};
+ return SupportedRead{GrSwizzle::RGBA(), srcColorType};
}
#ifdef SK_DEBUG
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 11dee73..54a6f80 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -237,7 +237,7 @@
};
/**
- * Given a src surface's pixel config and its backend format as well as a color type the caller
+ * Given a src surface's color type and its backend format as well as a color type the caller
* would like read into, this provides a legal color type that the caller may pass to
* GrGpu::readPixels(). The returned color type may differ from the passed dstColorType, in
* which case the caller must convert the read pixel data (see GrConvertPixels). When converting
@@ -245,7 +245,6 @@
* the returned color type for kUnknown.
*/
virtual SupportedRead supportedReadPixelsColorType(GrColorType srcColorType,
- GrPixelConfig srcConfig,
const GrBackendFormat& srcFormat,
GrColorType dstColorType) const;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 5afffe8..8e49259 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1743,16 +1743,12 @@
auto dstCT = SkColorTypeToGrColorType(info.colorType());
bool needsRescale = srcRect.width() != info.width() || srcRect.height() != info.height();
auto colorTypeOfFinalContext = this->colorSpaceInfo().colorType();
- GrPixelConfig configOfFinalContext = fRenderTargetProxy->config();
auto backendFormatOfFinalContext = fRenderTargetProxy->backendFormat();
if (needsRescale) {
colorTypeOfFinalContext = dstCT;
backendFormatOfFinalContext = this->caps()->getBackendFormatFromColorType(dstCT);
- configOfFinalContext = this->caps()->getConfigFromBackendFormat(backendFormatOfFinalContext,
- dstCT);
}
auto readInfo = this->caps()->supportedReadPixelsColorType(colorTypeOfFinalContext,
- configOfFinalContext,
backendFormatOfFinalContext, dstCT);
// Fail if we can't read from the source surface's color type.
if (readInfo.fColorType == GrColorType::kUnknown) {
@@ -1841,8 +1837,7 @@
return {};
}
auto supportedRead = this->caps()->supportedReadPixelsColorType(
- this->colorSpaceInfo().colorType(), fRenderTargetProxy->config(),
- fRenderTargetProxy->backendFormat(), dstCT);
+ this->colorSpaceInfo().colorType(), fRenderTargetProxy->backendFormat(), dstCT);
// Fail if read color type does not have all of dstCT's color channels and those missing color
// channels are in the src.
uint32_t dstComponents = GrColorTypeComponentFlags(dstCT);
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index 47a8940..1882e3c 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -172,8 +172,7 @@
bool flip = srcProxy->origin() == kBottomLeft_GrSurfaceOrigin;
auto supportedRead = caps->supportedReadPixelsColorType(
- this->colorSpaceInfo().colorType(), srcProxy->config(), srcProxy->backendFormat(),
- dstInfo.colorType());
+ this->colorSpaceInfo().colorType(), srcProxy->backendFormat(), dstInfo.colorType());
bool makeTight = !caps->readPixelsRowBytesSupport() && tightRowBytes != rowBytes;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index b581924..48c7ce7 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -1525,7 +1525,7 @@
// kAlpha_8
{
uint32_t flags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
- info.fColorTypeInfos.emplace_back(GrColorType::kAlpha_8, flags);
+ info.fColorTypeInfos.emplace_back(GrColorType::kAlpha_8, flags, GrSwizzle("000r"));
this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kR8);
}
@@ -1576,7 +1576,8 @@
{
uint32_t flags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
if (alpha8IsValidForGL || alpha8IsValidForGLES || alpha8IsValidForWebGL) {
- info.fColorTypeInfos.emplace_back(GrColorType::kAlpha_8, flags);
+ info.fColorTypeInfos.emplace_back(GrColorType::kAlpha_8, flags,
+ GrSwizzle("000r"));
int idx = static_cast<int>(GrColorType::kAlpha_8);
if (fColorTypeToFormatTable[idx] == GrGLFormat::kUnknown) {
this->setColorTypeFormat(GrColorType::kAlpha_8, GrGLFormat::kALPHA8);
@@ -1831,7 +1832,8 @@
// kAlpha_F16
{
uint32_t flags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
- info.fColorTypeInfos.emplace_back(GrColorType::kAlpha_F16, flags);
+ info.fColorTypeInfos.emplace_back(GrColorType::kAlpha_F16, flags,
+ GrSwizzle("000r"));
this->setColorTypeFormat(GrColorType::kAlpha_F16, GrGLFormat::kR16F);
}
}
@@ -2430,12 +2432,10 @@
ConfigInfo& alphaInfo = fConfigTable[kAlpha_8_as_Alpha_GrPixelConfig];
alphaInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
alphaInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_ALPHA;
- alphaInfo.fRGBAReadSwizzle = GrSwizzle("000a");
ConfigInfo& redInfo = fConfigTable[kAlpha_8_as_Red_GrPixelConfig];
redInfo.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
redInfo.fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
- redInfo.fRGBAReadSwizzle = GrSwizzle("000r");
if (textureRedSupport) {
fConfigTable[kAlpha_8_GrPixelConfig] = redInfo;
@@ -2471,7 +2471,6 @@
ConfigInfo& redHalf = fConfigTable[kAlpha_half_as_Red_GrPixelConfig];
redHalf.fFormats.fExternalType = redHalfExternalType;
redHalf.fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] = GR_GL_RED;
- redHalf.fRGBAReadSwizzle = GrSwizzle("000r");
fConfigTable[kAlpha_half_GrPixelConfig] = redHalf;
fConfigTable[kRGBA_half_GrPixelConfig].fFormats.fExternalFormat[kReadPixels_ExternalFormatUsage] =
@@ -3278,8 +3277,8 @@
}
GrCaps::SupportedRead GrGLCaps::supportedReadPixelsColorType(
- GrColorType srcColorType, GrPixelConfig srcPixelConfig,
- const GrBackendFormat& srcBackendFormat, GrColorType dstColorType) const {
+ GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
+ GrColorType dstColorType) const {
// For now, we mostly report the read back format that is required by the ES spec without
// checking for implementation allowed formats or consider laxer rules in non-ES GL. TODO: Relax
// this as makes sense to increase performance and correctness.
@@ -3289,7 +3288,7 @@
}
GrGLFormat srcFormat = GrGLBackendFormatToGLFormat(srcBackendFormat);
- auto swizzle = fConfigTable[srcPixelConfig].fRGBAReadSwizzle;
+ auto swizzle = this->getFormatInfo(srcFormat).rgbaReadSwizzle(srcColorType);
switch (this->getFormatInfo(srcFormat).fFormatType) {
case FormatType::kUnknown:
return {GrSwizzle{}, GrColorType::kUnknown};
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 088a3de..437a7a9 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -346,7 +346,7 @@
bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
- SupportedRead supportedReadPixelsColorType(GrColorType, GrPixelConfig, const GrBackendFormat&,
+ SupportedRead supportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
bool isCoreProfile() const { return fIsCoreProfile; }
@@ -595,12 +595,6 @@
// ReadPixels. One is implicitly specified by the current FBO's format. The other is
// queryable. This stores the queried option (lazily).
ReadPixelsFormat fSecondReadPixelsFormat;
-
-
- // If data from a surface of this config is read back to a GrColorType with all four
- // color channels this indicates how each channel should be interpreted. May contain
- // 0s and 1s.
- GrSwizzle fRGBAReadSwizzle = GrSwizzle("rgba");
};
ConfigInfo fConfigTable[kGrPixelConfigCnt];
@@ -618,6 +612,11 @@
: fColorType(colorType)
, fFlags(flags) {}
+ ColorTypeInfo(GrColorType colorType, uint32_t flags, GrSwizzle rgbaReadSwizzle)
+ : fColorType(colorType)
+ , fFlags(flags)
+ , fRGBAReadSwizzle(rgbaReadSwizzle) {}
+
GrColorType fColorType;
enum {
kUploadData_Flag = 0x1,
@@ -626,6 +625,11 @@
kRenderable_Flag = 0x2,
};
uint32_t fFlags;
+
+ // If data from a surface of this colorType & format is read back to a GrColorType with all
+ // four color channels this indicates how each channel should be interpreted. May contain
+ // 0s and 1s.
+ GrSwizzle fRGBAReadSwizzle = GrSwizzle("rgba");
};
struct FormatInfo {
@@ -638,6 +642,15 @@
return 0;
}
+ GrSwizzle rgbaReadSwizzle(GrColorType colorType) const {
+ for (int i = 0; i < fColorTypeInfos.count(); ++i) {
+ if (fColorTypeInfos[i].fColorType == colorType) {
+ return fColorTypeInfos[i].fRGBAReadSwizzle;
+ }
+ }
+ return GrSwizzle();
+ }
+
enum {
kTextureable_Flag = 0x1,
/** kFBOColorAttachment means that even if the format cannot be a GrRenderTarget, we can
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 65608d0..e52f848 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -47,6 +47,8 @@
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override {
return SurfaceReadPixelsSupport::kSupported;
}
+ SupportedRead supportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
+ GrColorType) const override;
/**
* 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 85b2082..a608644 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -900,3 +900,61 @@
GrSwizzle GrMtlCaps::getOutputSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
return get_swizzle(format, colorType, true);
}
+
+GrCaps::SupportedRead GrMtlCaps::supportedReadPixelsColorType(
+ GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
+ GrColorType dstColorType) const {
+ const GrMTLPixelFormat* grMtlFormat = srcBackendFormat.getMtlFormat();
+ if (!grMtlFormat) {
+ return {GrSwizzle(), GrColorType::kUnknown};
+ }
+
+ switch (*grMtlFormat) {
+ case MTLPixelFormatRGBA8Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888};
+ case MTLPixelFormatR8Unorm:
+ if (srcColorType == GrColorType::kAlpha_8) {
+ return {GrSwizzle::RGBA(), GrColorType::kAlpha_8};
+ } else if (srcColorType == GrColorType::kGray_8) {
+ return {GrSwizzle::RGBA(), GrColorType::kGray_8};
+ }
+ case MTLPixelFormatBGRA8Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kBGRA_8888};
+#ifdef SK_BIULD_FOR_IOS
+ case MTLPixelFormatB5G6R5Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kBGR_565};
+#endif
+ case MTLPixelFormatRGBA16Float:
+ if (srcColorType == GrColorType::kRGBA_F16) {
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16};
+ } else if (srcColorType == GrColorType::kRGBA_F16_Clamped){
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16_Clamped};
+ }
+ case MTLPixelFormatR16Float:
+ return {GrSwizzle::RGBA(), GrColorType::kAlpha_F16};
+ case MTLPixelFormatRG8Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kRG_88};
+ case MTLPixelFormatRGB10A2Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_1010102};
+#ifdef SK_BIULD_FOR_IOS
+ case MTLPixelFormatABGR4Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kABGR_4444};
+#endif
+ case MTLPixelFormatRGBA32Float:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_F32};
+ case MTLPixelFormatRGBA8Unorm_sRGB:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888_SRGB};
+ case MTLPixelFormatR16Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kR_16};
+ case MTLPixelFormatRG16Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kRG_1616};
+ // Experimental (for Y416 and mutant P016/P010)
+ case MTLPixelFormatRGBA16Unorm:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_16161616};
+ case MTLPixelFormatRG16Float:
+ return {GrSwizzle::RGBA(), GrColorType::kRG_F16};
+ default:
+ return {GrSwizzle(), GrColorType::kUnknown};
+ }
+}
+
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 93876d0..b2796f9 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -629,7 +629,6 @@
switch (format) {
case VK_FORMAT_R8G8B8A8_SRGB:
- case VK_FORMAT_B8G8R8A8_SRGB:
return true;
default:
return false;
@@ -652,7 +651,6 @@
VK_FORMAT_R4G4B4A4_UNORM_PACK16,
VK_FORMAT_R32G32B32A32_SFLOAT,
VK_FORMAT_R8G8B8A8_SRGB,
- VK_FORMAT_B8G8R8A8_SRGB,
VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
VK_FORMAT_R16_UNORM,
VK_FORMAT_R16G16_UNORM,
@@ -891,6 +889,11 @@
if (tex->ycbcrConversionInfo().isValid()) {
return SurfaceReadPixelsSupport::kCopyToTexture2D;
}
+ // We can't directly read from a compressed format
+ SkImage::CompressionType compressionType;
+ if (GrVkFormatToCompressionType(tex->imageFormat(), &compressionType)) {
+ return SurfaceReadPixelsSupport::kCopyToTexture2D;
+ }
}
return SurfaceReadPixelsSupport::kSupported;
}
@@ -1146,7 +1149,7 @@
case GrColorType::kRG_88:
return VK_FORMAT_R8G8_UNORM == vkFormat;
case GrColorType::kBGRA_8888:
- return VK_FORMAT_B8G8R8A8_UNORM == vkFormat || VK_FORMAT_B8G8R8A8_SRGB == vkFormat;
+ return VK_FORMAT_B8G8R8A8_UNORM == vkFormat;
case GrColorType::kRGBA_1010102:
return VK_FORMAT_A2B10G10R10_UNORM_PACK32 == vkFormat;
case GrColorType::kGray_8:
@@ -1234,3 +1237,60 @@
default: return 4 * bpp;
}
}
+
+GrCaps::SupportedRead GrVkCaps::supportedReadPixelsColorType(
+ GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
+ GrColorType dstColorType) const {
+ const VkFormat* vkFormat = srcBackendFormat.getVkFormat();
+ if (!vkFormat) {
+ return {GrSwizzle(), GrColorType::kUnknown};
+ }
+
+ switch (*vkFormat) {
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888};
+ case VK_FORMAT_R8_UNORM:
+ if (srcColorType == GrColorType::kAlpha_8) {
+ return {GrSwizzle::RGBA(), GrColorType::kAlpha_8};
+ } else if (srcColorType == GrColorType::kGray_8) {
+ return {GrSwizzle::RGBA(), GrColorType::kGray_8};
+ }
+ case VK_FORMAT_B8G8R8A8_UNORM:
+ return {GrSwizzle::RGBA(), GrColorType::kBGRA_8888};
+ case VK_FORMAT_R5G6B5_UNORM_PACK16:
+ return {GrSwizzle::RGBA(), GrColorType::kBGR_565};
+ case VK_FORMAT_R16G16B16A16_SFLOAT:
+ if (srcColorType == GrColorType::kRGBA_F16) {
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16};
+ } else if (srcColorType == GrColorType::kRGBA_F16_Clamped){
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16_Clamped};
+ }
+ case VK_FORMAT_R16_SFLOAT:
+ return {GrSwizzle::RGBA(), GrColorType::kAlpha_F16};
+ case VK_FORMAT_R8G8B8_UNORM:
+ return {GrSwizzle::RGBA(), GrColorType::kRGB_888x};
+ case VK_FORMAT_R8G8_UNORM:
+ return {GrSwizzle::RGBA(), GrColorType::kRG_88};
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_1010102};
+ case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
+ return {GrSwizzle::RGBA(), GrColorType::kABGR_4444};
+ case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
+ return {GrSwizzle::RGBA(), GrColorType::kABGR_4444};
+ case VK_FORMAT_R32G32B32A32_SFLOAT:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_F32};
+ case VK_FORMAT_R8G8B8A8_SRGB:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888_SRGB};
+ case VK_FORMAT_R16_UNORM:
+ return {GrSwizzle::RGBA(), GrColorType::kR_16};
+ case VK_FORMAT_R16G16_UNORM:
+ return {GrSwizzle::RGBA(), GrColorType::kRG_1616};
+ // Experimental (for Y416 and mutant P016/P010)
+ case VK_FORMAT_R16G16B16A16_UNORM:
+ return {GrSwizzle::RGBA(), GrColorType::kRGBA_16161616};
+ case VK_FORMAT_R16G16_SFLOAT:
+ return {GrSwizzle::RGBA(), GrColorType::kRG_F16};
+ default:
+ return {GrSwizzle(), GrColorType::kUnknown};
+ }
+}
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 46d6b2b..f5d35cb 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -53,6 +53,8 @@
int maxRenderTargetSampleCount(VkFormat format) const;
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
+ SupportedRead supportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
+ GrColorType) const override;
bool isVkFormatTexturableLinearly(VkFormat format) const {
return SkToBool(FormatInfo::kTextureable_Flag & this->getFormatInfo(format).fLinearFlags);
@@ -228,7 +230,7 @@
SkTDArray<int> fColorSampleCounts;
};
- static const size_t kNumVkFormats = 19;
+ static const size_t kNumVkFormats = 18;
FormatInfo fFormatTable[kNumVkFormats];
const FormatInfo& getFormatInfo(VkFormat) const;
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 7101201..0153af2 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -155,7 +155,6 @@
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SRGB:
- case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_R8G8B8_UNORM:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
@@ -296,7 +295,6 @@
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SRGB:
case VK_FORMAT_B8G8R8A8_UNORM:
- case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_R16G16_UNORM:
return 4;