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();
}