More YUV cleanup
* Remove more uses of colortype
* Add back SkImage_GpuYUVA::MakeFromYUVATextures
Bug: skia:7903
Change-Id: I3ee119d190db39c128516dbb78db34fe29ba3cce
Reviewed-on: https://skia-review.googlesource.com/c/165943
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 3047148..98eaa41 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -290,6 +290,14 @@
/**
* Special method only for YUVA images. Returns true if the format can be used for a
* YUVA plane, and the passed in GrPixelConfig will be set to a config that matches
+ * the backend texture.
+ */
+ virtual bool getYUVAConfigFromBackendTexture(const GrBackendTexture& tex,
+ GrPixelConfig*) const = 0;
+
+ /**
+ * Special method only for YUVA images. Returns true if the format can be used for a
+ * YUVA plane, and the passed in GrPixelConfig will be set to a config that matches
* the backend format.
*/
virtual bool getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 962e496..0829945 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2941,14 +2941,10 @@
return validate_sized_format(*glFormat, ct, config, fStandard);
}
-bool GrGLCaps::getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
- GrPixelConfig* config) const {
- const GrGLenum* glFormat = format.getGLFormat();
- if (!glFormat) {
- return false;
- }
+static bool get_yuva_config(GrGLenum format, GrPixelConfig* config) {
+ *config = kUnknown_GrPixelConfig;
- switch (*glFormat) {
+ switch (format) {
case GR_GL_ALPHA8:
*config = kAlpha_8_as_Alpha_GrPixelConfig;
break;
@@ -2971,6 +2967,24 @@
return true;
}
+bool GrGLCaps::getYUVAConfigFromBackendTexture(const GrBackendTexture& tex,
+ GrPixelConfig* config) const {
+ GrGLTextureInfo texInfo;
+ if (!tex.getGLTextureInfo(&texInfo)) {
+ return false;
+ }
+ return get_yuva_config(texInfo.fFormat, config);
+}
+
+bool GrGLCaps::getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
+ GrPixelConfig* config) const {
+ const GrGLenum* glFormat = format.getGLFormat();
+ if (!glFormat) {
+ return false;
+ }
+ return get_yuva_config(*glFormat, config);
+}
+
#ifdef GR_TEST_UTILS
GrBackendFormat GrGLCaps::onCreateFormatFromBackendTexture(
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index f8b8134..fda673e 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -436,6 +436,8 @@
bool getConfigFromBackendFormat(const GrBackendFormat&, SkColorType,
GrPixelConfig*) const override;
+ bool getYUVAConfigFromBackendTexture(const GrBackendTexture&,
+ GrPixelConfig*) const override;
bool getYUVAConfigFromBackendFormat(const GrBackendFormat&,
GrPixelConfig*) const override;
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index 2e6e8d9..c5459b2 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -104,6 +104,17 @@
return true;
}
+ bool getYUVAConfigFromBackendTexture(const GrBackendTexture& tex,
+ GrPixelConfig* config) const override {
+ GrMockTextureInfo texInfo;
+ if (!tex.getMockTextureInfo(&texInfo)) {
+ return false;
+ }
+
+ *config = texInfo.fConfig;
+ return true;
+ }
+
bool getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
GrPixelConfig* config) const override {
const GrPixelConfig* mockFormat = format.getMockFormat();
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 6de830d..6eb775c 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -80,6 +80,11 @@
return false;
}
+ bool getYUVAConfigFromBackendTexture(const GrBackendTexture&,
+ GrPixelConfig*) const override {
+ return false;
+ }
+
bool getYUVAConfigFromBackendFormat(const GrBackendFormat&,
GrPixelConfig*) const override {
return false;
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 54693d9..01cad06 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -782,14 +782,10 @@
return validate_image_info(*vkFormat, ct, config);
}
-bool GrVkCaps::getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
- GrPixelConfig* config) const {
- const VkFormat* vkFormat = format.getVkFormat();
- if (!vkFormat) {
- return false;
- }
+static bool get_yuva_config(VkFormat vkFormat, GrPixelConfig* config) {
+ *config = kUnknown_GrPixelConfig;
- switch (*vkFormat) {
+ switch (vkFormat) {
case VK_FORMAT_R8_UNORM:
*config = kAlpha_8_as_Red_GrPixelConfig;
break;
@@ -809,6 +805,24 @@
return true;
}
+bool GrVkCaps::getYUVAConfigFromBackendTexture(const GrBackendTexture& tex,
+ GrPixelConfig* config) const {
+ GrVkImageInfo imageInfo;
+ if (!tex.getVkImageInfo(&imageInfo)) {
+ return false;
+ }
+ return get_yuva_config(imageInfo.fFormat, config);
+}
+
+bool GrVkCaps::getYUVAConfigFromBackendFormat(const GrBackendFormat& format,
+ GrPixelConfig* config) const {
+ const VkFormat* vkFormat = format.getVkFormat();
+ if (!vkFormat) {
+ return false;
+ }
+ return get_yuva_config(*vkFormat, config);
+}
+
#ifdef GR_TEST_UTILS
GrBackendFormat GrVkCaps::onCreateFormatFromBackendTexture(
const GrBackendTexture& backendTex) const {
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 19cdc1d..0154c0b 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -160,6 +160,8 @@
bool getConfigFromBackendFormat(const GrBackendFormat&, SkColorType,
GrPixelConfig*) const override;
+ bool getYUVAConfigFromBackendTexture(const GrBackendTexture&,
+ GrPixelConfig*) const override;
bool getYUVAConfigFromBackendFormat(const GrBackendFormat&,
GrPixelConfig*) const override;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 4ef8b1c..8cf4edb 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -127,8 +127,6 @@
// of validate_backend_texture.
GrBackendTexture yuvaTexturesCopy[4];
- bool nv12 = (yuvaIndices[1].fIndex == yuvaIndices[2].fIndex);
-
for (int i = 0; i < 4; ++i) {
// Validate that the yuvaIndices refer to valid backend textures.
const SkYUVAIndex& yuvaIndex = yuvaIndices[i];
@@ -142,31 +140,13 @@
return nullptr;
}
- SkColorType ct = kUnknown_SkColorType;
- if (SkYUVAIndex::kA_Index == i) {
- // The A plane is always kAlpha8 (for now)
- ct = kAlpha_8_SkColorType;
- } else {
- // The UV planes can either be interleaved or planar. If interleaved the Y plane
- // should have A8 color type but may be RGBA. We fall back in the latter case below.
- ct = nv12 && SkYUVAIndex::kY_Index != i ? kRGBA_8888_SkColorType : kAlpha_8_SkColorType;
- }
-
if (!yuvaTexturesCopy[yuvaIndex.fIndex].isValid()) {
yuvaTexturesCopy[yuvaIndex.fIndex] = yuvaTextures[yuvaIndex.fIndex];
- // TODO: Instead of using assumption about whether it is NV12 format to guess colorType,
- // actually use channel information here.
- // Alternate TODO: Don't bother validating.
- if (!ValidateBackendTexture(ctx, yuvaTexturesCopy[yuvaIndex.fIndex],
- &yuvaTexturesCopy[yuvaIndex.fIndex].fConfig,
- ct, kPremul_SkAlphaType, nullptr)) {
- // Try RGBA in case the assumed colortype is wrong
- if (!ValidateBackendTexture(ctx, yuvaTexturesCopy[yuvaIndex.fIndex],
- &yuvaTexturesCopy[yuvaIndex.fIndex].fConfig,
- kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr)) {
- return nullptr;
- }
+ if (!ctx->contextPriv().caps()->getYUVAConfigFromBackendTexture(
+ yuvaTexturesCopy[yuvaIndex.fIndex],
+ &yuvaTexturesCopy[yuvaIndex.fIndex].fConfig)) {
+ return nullptr;
}
}
diff --git a/src/image/SkImage_GpuYUVA.cpp b/src/image/SkImage_GpuYUVA.cpp
index ae15f4b..9a54d23 100644
--- a/src/image/SkImage_GpuYUVA.cpp
+++ b/src/image/SkImage_GpuYUVA.cpp
@@ -96,6 +96,72 @@
return fRGBProxy;
}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+sk_sp<SkImage> SkImage::MakeFromYUVATextures(GrContext* ctx,
+ SkYUVColorSpace colorSpace,
+ const GrBackendTexture yuvaTextures[],
+ const SkYUVAIndex yuvaIndices[4],
+ SkISize imageSize,
+ GrSurfaceOrigin imageOrigin,
+ sk_sp<SkColorSpace> imageColorSpace) {
+ GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
+
+ // We need to make a copy of the input backend textures because we need to preserve the result
+ // of validate_backend_texture.
+ GrBackendTexture yuvaTexturesCopy[4];
+ for (int i = 0; i < 4; ++i) {
+ // Validate that the yuvaIndices refer to valid backend textures.
+ const SkYUVAIndex& yuvaIndex = yuvaIndices[i];
+ if (SkYUVAIndex::kA_Index == i && yuvaIndex.fIndex == -1) {
+ // Meaning the A plane isn't passed in.
+ continue;
+ }
+ if (yuvaIndex.fIndex == -1 || yuvaIndex.fIndex > 3) {
+ // Y plane, U plane, and V plane must refer to image sources being passed in. There are
+ // at most 4 image sources being passed in, could not have a index more than 3.
+ return nullptr;
+ }
+
+ if (!yuvaTexturesCopy[yuvaIndex.fIndex].isValid()) {
+ yuvaTexturesCopy[yuvaIndex.fIndex] = yuvaTextures[yuvaIndex.fIndex];
+
+ if (!ctx->contextPriv().caps()->getYUVAConfigFromBackendTexture(
+ yuvaTexturesCopy[yuvaIndex.fIndex],
+ &yuvaTexturesCopy[yuvaIndex.fIndex].fConfig)) {
+ return nullptr;
+ }
+ }
+
+ // TODO: Check that for each plane, the channel actually exist in the image source we are
+ // reading from.
+ }
+
+ sk_sp<GrTextureProxy> tempTextureProxies[4]; // build from yuvaTextures
+ for (int i = 0; i < 4; ++i) {
+ // Fill in tempTextureProxies to avoid duplicate texture proxies.
+ int textureIndex = yuvaIndices[i].fIndex;
+
+ // Safely ignore since this means we are missing the A plane.
+ if (textureIndex == -1) {
+ SkASSERT(SkYUVAIndex::kA_Index == i);
+ continue;
+ }
+
+ if (!tempTextureProxies[textureIndex]) {
+ SkASSERT(yuvaTexturesCopy[textureIndex].isValid());
+ tempTextureProxies[textureIndex] =
+ proxyProvider->wrapBackendTexture(yuvaTexturesCopy[textureIndex], imageOrigin);
+ if (!tempTextureProxies[textureIndex]) {
+ return nullptr;
+ }
+ }
+ }
+
+ return sk_make_sp<SkImage_GpuYUVA>(sk_ref_sp(ctx), imageSize.width(), imageSize.height(),
+ kNeedNewImageUniqueID, colorSpace, tempTextureProxies,
+ yuvaIndices, imageOrigin, imageColorSpace, SkBudgeted::kYes);
+}
/////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkImage> SkImage_GpuYUVA::MakePromiseYUVATexture(GrContext* context,
SkYUVColorSpace yuvColorSpace,