Add idea of DataType to SkYUVAPixmapInfo.

DataType describes the data type of YUVA channels
independent of how they are grouped into planes.

Adds mapping functions between SkColorType/channel count
and DataType.

SkYUVAPixmapInfo can be constructed from DataType and will
choose appropriate SkColorTypes for each plane.

Valid SkYUVAPixmapInfos now have the same DataType for each
plane (could relax this in the future, esp for alpha plane).

SkYUVAPixmapInfo::SupportedDataTypes specifies the supported
combinations of SkYUVAInfo::PlanarConfig and
kYUVAPixmapInfo::DataType supported by a GrContext (based on
supported texture formats).

SkImageGenerator/SkCodec YUVA query API now takes a
SupportedDataTypes.

Change-Id: I8791234638e6ba3396d1e7960b7bc210edc6dd57
Bug: skia:10632
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/314276
Reviewed-by: Leon Scroggins <scroggo@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2020-09-01 15:01:15 -04:00 committed by Skia Commit-Bot
parent 1338a37a1a
commit ed63444587
19 changed files with 251 additions and 73 deletions

View File

@ -21,6 +21,7 @@ Milestone 87
Doesn't assume 8bit planar values.
https://review.skia.org/309658
https://review.skia.org/312886
https://review.skia.org/314276
* Added VkImageUsageFlags to GrVkImageInfo struct.

View File

@ -1814,7 +1814,8 @@ Result GPUDDLSink::ddlDraw(const Src& src,
// this is our ultimate final drawing area/rect
SkIRect viewport = SkIRect::MakeWH(size.fWidth, size.fHeight);
DDLPromiseImageHelper promiseImageHelper;
SkYUVAPixmapInfo::SupportedDataTypes supportedYUVADataTypes(*gpuThreadCtx);
DDLPromiseImageHelper promiseImageHelper(supportedYUVADataTypes);
sk_sp<SkData> compressedPictureData = promiseImageHelper.deflateSKP(inputPicture.get());
if (!compressedPictureData) {
return Result::Fatal("GPUDDLSink: Couldn't deflate SkPicture");
@ -2270,7 +2271,7 @@ Result ViaDDL::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStrin
// this is our ultimate final drawing area/rect
SkIRect viewport = SkIRect::MakeWH(size.fWidth, size.fHeight);
DDLPromiseImageHelper promiseImageHelper;
DDLPromiseImageHelper promiseImageHelper(SkYUVAPixmapInfo::SupportedDataTypes::All());
sk_sp<SkData> compressedPictureData = promiseImageHelper.deflateSKP(inputPicture.get());
if (!compressedPictureData) {
return Result::Fatal("ViaDDL: Couldn't deflate SkPicture");

View File

@ -381,11 +381,18 @@ public:
}
/**
* If decoding to YUVA is supported, this returns true and updates yuvaPixmapInfo to be a
* specification of the planar layout, YUVA->RGBA transformation, per-plane color types and row
* bytes. If YUVA decoding is not supported then returns false.
* If decoding to YUV is supported, this returns true. Otherwise, this
* returns false and the caller will ignore output parameter yuvaPixmapInfo.
*
* @param supportedDataTypes Indicates the data type/planar config combinations that are
* supported by the caller. If the generator supports decoding to
* YUV(A), but not as a type in supportedDataTypes, this method
* returns false.
* @param yuvaPixmapInfo Output parameter that specifies the planar configuration, subsampling,
* orientation, chroma siting, plane color types, and row bytes.
*/
bool queryYUVAInfo(SkYUVAPixmapInfo* yuvaPixmapInfo) const;
bool queryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVAPixmapInfo* yuvaPixmapInfo) const;
/**
* Returns kSuccess, or another value explaining the type of failure.
@ -732,7 +739,8 @@ protected:
void* pixels, size_t rowBytes, const Options&,
int* rowsDecoded) = 0;
virtual bool onQueryYUVAInfo(SkYUVAPixmapInfo*) const { return false; }
virtual bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
SkYUVAPixmapInfo*) const { return false; }
virtual Result onGetYUVAPlanes(const SkYUVAPixmaps&) { return kUnimplemented; }

View File

@ -91,12 +91,17 @@ public:
/**
* If decoding to YUV is supported, this returns true. Otherwise, this
* returns false and does not modify yuvaPixmapInfo.
* returns false and the caller will ignore output parameter yuvaPixmapInfo.
*
* @param yuvaPixmapInfo Specifies the planar configuration, subsampling, orientation,
* chroma siting, plane color types, and row bytes.
* @param supportedDataTypes Indicates the data type/planar config combinations that are
* supported by the caller. If the generator supports decoding to
* YUV(A), but not as a type in supportedDataTypes, this method
* returns false.
* @param yuvaPixmapInfo Output parameter that specifies the planar configuration, subsampling,
* orientation, chroma siting, plane color types, and row bytes.
*/
bool queryYUVAInfo(SkYUVAPixmapInfo* yuvaPixmapInfo) const;
bool queryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVAPixmapInfo* yuvaPixmapInfo) const;
/**
* Returns true on success and false on failure.
@ -204,7 +209,8 @@ protected:
struct Options {};
virtual bool onGetPixels(const SkImageInfo&, void*, size_t, const Options&) { return false; }
virtual bool onIsValid(GrRecordingContext*) const { return true; }
virtual bool onQueryYUVAInfo(SkYUVAPixmapInfo*) const { return false; }
virtual bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
SkYUVAPixmapInfo*) const { return false; }
virtual bool onGetYUVAPlanes(const SkYUVAPixmaps&) { return false; }
virtual bool onQueryYUVA8(SkYUVASizeInfo*, SkYUVAIndex[SkYUVAIndex::kIndexCount],
SkYUVColorSpace*) const { return false; }

View File

@ -15,7 +15,9 @@
#include "include/private/SkTo.h"
#include <array>
#include <bitset>
class GrImageContext;
struct SkYUVASizeInfo;
struct SkYUVAIndex;
@ -27,6 +29,67 @@ class SK_API SkYUVAPixmapInfo {
public:
static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
using PlanarConfig = SkYUVAInfo::PlanarConfig;
/**
* Data type for Y, U, V, and possibly A channels independent of how values are packed into
* planes.
**/
enum class DataType {
kUnorm8, ///< 8 bit unsigned normalized
kUnorm16, ///< 16 bit unsigned normalized
kFloat16, ///< 16 bit (half) floating point
kLast = kFloat16
};
static constexpr int kDataTypeCnt = static_cast<int>(DataType::kLast) + 1;
class SupportedDataTypes {
public:
/** Defaults to nothing supported. */
constexpr SupportedDataTypes() = default;
/** Init based on texture formats supported by the context. */
SupportedDataTypes(const GrImageContext&);
/** All combinations of PlanarConfig and DataType are supported. */
static constexpr SupportedDataTypes All() {
SupportedDataTypes combinations;
combinations.fDataTypeSupport = std::bitset<kDataTypeCnt>(~(0ULL));
return combinations;
}
constexpr bool supported(PlanarConfig, DataType type) const {
return fDataTypeSupport[static_cast<size_t>(type)];
}
/**
* Update to add support for pixmaps with numChannel channels where each channel is
* represented as DataType.
*/
void enableDataType(DataType, int numChannels);
private:
// Because all of our PlanarConfigs are currently single channel per-plane, we just need to
// keep track of whether each data type is supported (implicitly as a single channel plane).
// As we add multi-channel per-plane PlanarConfigs this will have to change.
std::bitset<kDataTypeCnt> fDataTypeSupport = {};
};
/**
* Gets the default SkColorType to use with numChannels channels, each represented as DataType.
* Returns kUnknown_SkColorType if no such color type.
*/
static SkColorType DefaultColorTypeForDataType(DataType dataType, int numChannels);
/**
* If the SkColorType is supported for YUVA pixmaps this will return the number of YUVA channels
* that can be stored in a plane of this color type and what the DataType is of those channels.
* If the SkColorType is not supported as a YUVA plane the number of channels is reported as 0
* and the DataType returned should be ignored.
*/
static std::tuple<int, DataType> NumChannelsAndDataType(SkColorType);
/** Default SkYUVAPixmapInfo is invalid. */
SkYUVAPixmapInfo() = default;
@ -34,7 +97,8 @@ public:
* Initializes the SkYUVAPixmapInfo from a SkYUVAInfo with per-plane color types and row bytes.
* This will be invalid if the colorTypes aren't compatible with the SkYUVAInfo or if a
* rowBytes entry is not valid for the plane dimensions and color type. Color type and
* row byte values beyond the number of planes in SkYUVAInfo are ignored.
* row byte values beyond the number of planes in SkYUVAInfo are ignored. All SkColorTypes
* must have the same DataType or this will be invalid.
*
* If rowBytes is nullptr then bpp*width is assumed for each plane.
*/
@ -42,14 +106,18 @@ public:
const SkColorType[kMaxPlanes],
const size_t rowBytes[kMaxPlanes]);
/**
* Like above but uses the same color type for all planes.
* Like above but uses DefaultColorTypeForDataType to determine each plane's SkColorType. If
* rowBytes is nullptr then bpp*width is assumed for each plane.
*/
SkYUVAPixmapInfo(const SkYUVAInfo&, SkColorType, const size_t rowBytes[kMaxPlanes]);
SkYUVAPixmapInfo(const SkYUVAInfo&, DataType, const size_t rowBytes[kMaxPlanes]);
SkYUVAPixmapInfo(const SkYUVAPixmapInfo&) = default;
SkYUVAPixmapInfo& operator=(const SkYUVAPixmapInfo&) = default;
bool operator==(const SkYUVAPixmapInfo&) const;
bool operator!=(const SkYUVAPixmapInfo& that) const { return !(*this == that); }
const SkYUVAInfo& yuvaInfo() const { return fYUVAInfo; }
SkYUVColorSpace yuvColorSpace() const { return fYUVAInfo.yuvColorSpace(); }
@ -57,14 +125,17 @@ public:
/** The number of SkPixmap planes, 0 if this SkYUVAPixmapInfo is invalid. */
int numPlanes() const { return this->isValid() ? fYUVAInfo.numPlanes() : 0; }
/** The per-YUV[A] channel data type. */
DataType dataType() const { return fDataType; }
/**
* Row bytes for the ith plane. Returns zero if i >= numPlanes() or this SkYUVAPixmapInfo is
* invalid.
*/
size_t rowBytes(int i) const { return fRowBytes[i]; }
size_t rowBytes(int i) const { return fRowBytes[static_cast<size_t>(i)]; }
/** Image info for the ith plane, or default SkImageInfo if i >= numPlanes() */
const SkImageInfo& planeInfo(int i) const { return fPlaneInfos[i]; }
const SkImageInfo& planeInfo(int i) const { return fPlaneInfos[static_cast<size_t>(i)]; }
/**
* Determine size to allocate for all planes. Optionally retrieves the per-plane sizes in
@ -86,10 +157,14 @@ public:
*/
bool isValid() const { return fPlaneInfos[0].colorType() != kUnknown_SkColorType; }
/** Is this valid and does it use color types allowed by the passed SupportedDataTypes? */
bool isSupported(const SupportedDataTypes&) const;
private:
SkYUVAInfo fYUVAInfo;
SkImageInfo fPlaneInfos[kMaxPlanes] = {};
size_t fRowBytes[kMaxPlanes] = {};
std::array<SkImageInfo, kMaxPlanes> fPlaneInfos = {};
std::array<size_t, kMaxPlanes> fRowBytes = {};
DataType fDataType = DataType::kUnorm8;
static_assert(kUnknown_SkColorType == 0, "default init isn't kUnknown");
};

View File

@ -167,11 +167,13 @@ SkCodec::SkCodec(SkEncodedInfo&& info, XformFormat srcFormat, std::unique_ptr<Sk
SkCodec::~SkCodec() {}
bool SkCodec::queryYUVAInfo(SkYUVAPixmapInfo* yuvaPixmapInfo) const {
bool SkCodec::queryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVAPixmapInfo* yuvaPixmapInfo) const {
if (!yuvaPixmapInfo) {
return false;
}
return this->onQueryYUVAInfo(yuvaPixmapInfo) && yuvaPixmapInfo->isValid();
return this->onQueryYUVAInfo(supportedDataTypes, yuvaPixmapInfo) &&
yuvaPixmapInfo->isSupported(supportedDataTypes);
}
SkCodec::Result SkCodec::getYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {

View File

@ -69,8 +69,10 @@ bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* re
return this->getPixels(requestInfo, requestPixels, requestRowBytes, nullptr);
}
bool SkCodecImageGenerator::onQueryYUVAInfo(SkYUVAPixmapInfo* yuvaPixmapInfo) const {
return fCodec->queryYUVAInfo(yuvaPixmapInfo);
bool SkCodecImageGenerator::onQueryYUVAInfo(
const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVAPixmapInfo* yuvaPixmapInfo) const {
return fCodec->queryYUVAInfo(supportedDataTypes, yuvaPixmapInfo);
}
bool SkCodecImageGenerator::onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {

View File

@ -98,7 +98,8 @@ protected:
size_t rowBytes,
const Options& opts) override;
bool onQueryYUVAInfo(SkYUVAPixmapInfo* yuvaPixmapInfo) const override;
bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
SkYUVAPixmapInfo*) const override;
bool onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) override;

View File

@ -745,6 +745,7 @@ bool SkJpegCodec::onSkipScanlines(int count) {
static bool is_yuv_supported(const jpeg_decompress_struct* dinfo,
const SkJpegCodec& codec,
const SkYUVAPixmapInfo::SupportedDataTypes* supportedDataTypes,
SkYUVAPixmapInfo* yuvaPixmapInfo) {
// Scaling is not supported in raw data mode.
SkASSERT(dinfo->scale_num == dinfo->scale_denom);
@ -811,6 +812,10 @@ static bool is_yuv_supported(const jpeg_decompress_struct* dinfo,
} else {
return false;
}
if (supportedDataTypes &&
!supportedDataTypes->supported(tempPlanarConfig, SkYUVAPixmapInfo::DataType::kUnorm8)) {
return false;
}
if (yuvaPixmapInfo) {
SkColorType colorTypes[SkYUVAPixmapInfo::kMaxPlanes];
size_t rowBytes[SkYUVAPixmapInfo::kMaxPlanes];
@ -829,15 +834,16 @@ static bool is_yuv_supported(const jpeg_decompress_struct* dinfo,
return true;
}
bool SkJpegCodec::onQueryYUVAInfo(SkYUVAPixmapInfo* yuvaPixmapInfo) const {
bool SkJpegCodec::onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVAPixmapInfo* yuvaPixmapInfo) const {
jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
return is_yuv_supported(dinfo, *this, yuvaPixmapInfo);
return is_yuv_supported(dinfo, *this, &supportedDataTypes, yuvaPixmapInfo);
}
SkCodec::Result SkJpegCodec::onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {
// Get a pointer to the decompress info since we will use it quite frequently
jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
if (!is_yuv_supported(dinfo, *this, nullptr)) {
if (!is_yuv_supported(dinfo, *this, nullptr, nullptr)) {
return fDecoderMgr->returnFailure("onGetYUVAPlanes", kInvalidInput);
}
// Set the jump location for libjpeg errors
@ -860,7 +866,7 @@ SkCodec::Result SkJpegCodec::onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {
// was caused by a bug in the old code, but we'll be safe and check here.
// Also check that pixmap properties agree with expectations.
SkYUVAPixmapInfo info;
SkASSERT(is_yuv_supported(dinfo, *this, &info));
SkASSERT(is_yuv_supported(dinfo, *this, nullptr, &info));
SkASSERT(info.yuvaInfo() == yuvaPixmaps.yuvaInfo());
for (int i = 0; i < info.numPlanes(); ++i) {
SkASSERT(planes[i].colorType() == kAlpha_8_SkColorType);

View File

@ -44,7 +44,8 @@ protected:
Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
int*) override;
bool onQueryYUVAInfo(SkYUVAPixmapInfo*) const override;
bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
SkYUVAPixmapInfo*) const override;
Result onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) override;

View File

@ -30,10 +30,12 @@ bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t r
return this->onGetPixels(info, pixels, rowBytes, defaultOpts);
}
bool SkImageGenerator::queryYUVAInfo(SkYUVAPixmapInfo* yuvaPixmapInfo) const {
bool SkImageGenerator::queryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVAPixmapInfo* yuvaPixmapInfo) const {
SkASSERT(yuvaPixmapInfo);
return this->onQueryYUVAInfo(yuvaPixmapInfo);
return this->onQueryYUVAInfo(supportedDataTypes, yuvaPixmapInfo) &&
yuvaPixmapInfo->isSupported(supportedDataTypes);
}
bool SkImageGenerator::getYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {

View File

@ -11,6 +11,60 @@
#include "include/core/SkYUVASizeInfo.h"
#include "include/private/SkImageInfoPriv.h"
#if SK_SUPPORT_GPU
#include "include/private/GrImageContext.h"
#endif
void SkYUVAPixmapInfo::SupportedDataTypes::enableDataType(DataType type, int numChannels) {
// All of our PlanarConfigs are one channel per plane so far.
if (numChannels != 1) {
return;
}
fDataTypeSupport[static_cast<size_t>(type)] = true;
}
SkYUVAPixmapInfo::SupportedDataTypes::SupportedDataTypes(const GrImageContext& context) {
#if SK_SUPPORT_GPU
if (context.defaultBackendFormat(DefaultColorTypeForDataType(DataType::kUnorm8, 1),
GrRenderable::kNo).isValid()) {
this->enableDataType(DataType::kUnorm8, 1);
}
if (context.defaultBackendFormat(DefaultColorTypeForDataType(DataType::kUnorm16, 1),
GrRenderable::kNo).isValid()) {
this->enableDataType(DataType::kUnorm16, 1);
}
if (context.defaultBackendFormat(DefaultColorTypeForDataType(DataType::kFloat16, 1),
GrRenderable::kNo).isValid()) {
this->enableDataType(DataType::kFloat16, 1);
}
#endif
}
//////////////////////////////////////////////////////////////////////////////
SkColorType SkYUVAPixmapInfo::DefaultColorTypeForDataType(DataType dataType, int numChannels) {
if (numChannels != 1) {
return kUnknown_SkColorType;
}
switch (dataType) {
case DataType::kUnorm8: return kGray_8_SkColorType;
case DataType::kUnorm16: return kA16_unorm_SkColorType;
case DataType::kFloat16: return kA16_float_SkColorType;
}
SkUNREACHABLE;
}
std::tuple<int, SkYUVAPixmapInfo::DataType> SkYUVAPixmapInfo::NumChannelsAndDataType(
SkColorType ct) {
switch (ct) {
case kAlpha_8_SkColorType:
case kGray_8_SkColorType: return {1, DataType::kUnorm8 };
case kA16_unorm_SkColorType: return {1, DataType::kUnorm16};
case kA16_float_SkColorType: return {1, DataType::kFloat16};
default: return {0, DataType::kUnorm8 };
}
}
static int num_channels_in_plane(SkYUVAInfo::PlanarConfig config, int planeIdx) {
switch (config) {
case SkYUVAInfo::PlanarConfig::kY_U_V_444:
@ -54,30 +108,15 @@ SkYUVAPixmapInfo::SkYUVAPixmapInfo(const SkYUVAInfo& yuvaInfo,
rowBytes = tempRowBytes;
}
bool ok = true;
for (int i = 0; i < n; ++i) {
for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
fRowBytes[i] = rowBytes[i];
fPlaneInfos[i] = SkImageInfo::Make(planeDimensions[i], colorTypes[i], kPremul_SkAlphaType);
int numRequiredChannels = num_channels_in_plane(yuvaInfo.planarConfig(), i);
switch (SkColorTypeChannelFlags(colorTypes[i])) {
case kGray_SkColorChannelFlag:
case kRed_SkColorChannelFlag:
case kAlpha_SkColorChannelFlag:
ok |= numRequiredChannels == 1;
break;
case kRG_SkColorChannelFlags:
ok |= numRequiredChannels <= 2;
break;
case kRGB_SkColorChannelFlags:
ok |= numRequiredChannels <= 3;
break;
case kRGBA_SkColorChannelFlags:
ok |= numRequiredChannels <= 4;
break;
default:
ok = false;
break;
}
auto [numColorTypeChannels, colorTypeDataType] = NumChannelsAndDataType(colorTypes[i]);
ok |= i == 0 || colorTypeDataType == fDataType;
ok |= numColorTypeChannels >= numRequiredChannels;
ok |= fPlaneInfos[i].validRowBytes(fRowBytes[i]);
fDataType = colorTypeDataType;
}
if (!ok) {
*this = {};
@ -88,13 +127,25 @@ SkYUVAPixmapInfo::SkYUVAPixmapInfo(const SkYUVAInfo& yuvaInfo,
}
SkYUVAPixmapInfo::SkYUVAPixmapInfo(const SkYUVAInfo& yuvaInfo,
const SkColorType colorType,
DataType dataType,
const size_t rowBytes[kMaxPlanes]) {
SkColorType colorTypes[kMaxPlanes];
std::fill_n(colorTypes, kMaxPlanes, colorType);
int n = yuvaInfo.numPlanes();
for (int i = 0; i < n; ++i) {
// Currently all PlanarConfigs have 1 channel per plane.
colorTypes[i] = DefaultColorTypeForDataType(dataType, 1);
}
*this = SkYUVAPixmapInfo(yuvaInfo, colorTypes, rowBytes);
}
bool SkYUVAPixmapInfo::operator==(const SkYUVAPixmapInfo& that) const {
bool result = fYUVAInfo == that.fYUVAInfo &&
fPlaneInfos == that.fPlaneInfos &&
fRowBytes == that.fRowBytes;
SkASSERT(!result || fDataType == that.fDataType);
return result;
}
size_t SkYUVAPixmapInfo::computeTotalBytes(size_t planeSizes[kMaxPlanes]) const {
if (!this->isValid()) {
if (planeSizes) {
@ -102,7 +153,7 @@ size_t SkYUVAPixmapInfo::computeTotalBytes(size_t planeSizes[kMaxPlanes]) const
}
return 0;
}
return fYUVAInfo.computeTotalBytes(fRowBytes, planeSizes);
return fYUVAInfo.computeTotalBytes(fRowBytes.data(), planeSizes);
}
bool SkYUVAPixmapInfo::initPixmapsFromSingleAllocation(void* memory,
@ -126,6 +177,13 @@ bool SkYUVAPixmapInfo::initPixmapsFromSingleAllocation(void* memory,
return true;
}
bool SkYUVAPixmapInfo::isSupported(const SupportedDataTypes& supportedDataTypes) const {
if (!this->isValid()) {
return false;
}
return supportedDataTypes.supported(fYUVAInfo.planarConfig(), fDataType);
}
//////////////////////////////////////////////////////////////////////////////
SkYUVAPixmaps SkYUVAPixmaps::Allocate(const SkYUVAPixmapInfo& yuvaPixmapInfo) {

View File

@ -266,8 +266,9 @@ GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext*
SkYUVColorSpace yuvColorSpace;
SkPixmap planes[SkYUVASizeInfo::kMaxCount];
SkYUVAPixmapInfo::SupportedDataTypes supportedDataTypes(*ctx);
sk_sp<SkCachedData> dataStorage =
this->getPlanes(&yuvSizeInfo, yuvaIndices, &yuvColorSpace, planes);
this->getPlanes(supportedDataTypes, &yuvSizeInfo, yuvaIndices, &yuvColorSpace, planes);
if (!dataStorage) {
return {};
}
@ -359,10 +360,12 @@ GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext*
return renderTargetContext->readSurfaceView();
}
sk_sp<SkCachedData> SkImage_Lazy::getPlanes(SkYUVASizeInfo* yuvaSizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* yuvColorSpace,
SkPixmap planes[SkYUVASizeInfo::kMaxCount]) const {
sk_sp<SkCachedData> SkImage_Lazy::getPlanes(
const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVASizeInfo* yuvaSizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* yuvColorSpace,
SkPixmap planes[SkYUVASizeInfo::kMaxCount]) const {
ScopedGenerator generator(fSharedGenerator);
SkYUVPlanesCache::Info yuvInfo;
@ -370,9 +373,8 @@ sk_sp<SkCachedData> SkImage_Lazy::getPlanes(SkYUVASizeInfo* yuvaSizeInfo,
// Try the new more descriptive SkImageGenerator/SkCodec YUVA interface.
if (SkYUVAPixmapInfo yuvaPixmapInfo;
!data && generator->queryYUVAInfo(&yuvaPixmapInfo) &&
!data && generator->queryYUVAInfo(supportedDataTypes, &yuvaPixmapInfo) &&
yuvaPixmapInfo.yuvaInfo().dimensions() == this->dimensions()) {
data.reset(SkResourceCache::NewCachedData(yuvaPixmapInfo.computeTotalBytes()));
auto pixmaps = SkYUVAPixmaps::FromExternalMemory(yuvaPixmapInfo, data->writable_data());
SkASSERT(pixmaps.isValid());

View File

@ -15,7 +15,7 @@
#if SK_SUPPORT_GPU
#include "include/core/SkYUVAIndex.h"
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
#include "include/core/SkYUVASizeInfo.h"
#include "src/gpu/GrTextureMaker.h"
#endif
@ -69,7 +69,8 @@ public:
private:
void addUniqueIDListener(sk_sp<SkIDChangeListener>) const;
#if SK_SUPPORT_GPU
sk_sp<SkCachedData> getPlanes(SkYUVASizeInfo* yuvaSizeInfo,
sk_sp<SkCachedData> getPlanes(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVASizeInfo* yuvaSizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* yuvColorSpace,
SkPixmap planes[SkYUVASizeInfo::kMaxCount]) const;

View File

@ -30,10 +30,17 @@ static void codec_yuv(skiatest::Reporter* reporter,
// Test queryYUBAInfo()
SkYUVAPixmapInfo yuvaPixmapInfo;
// Param is required to be non-null.
bool success = codec->queryYUVAInfo(nullptr);
static constexpr auto kAllTypes = SkYUVAPixmapInfo::SupportedDataTypes::All();
static constexpr auto kNoTypes = SkYUVAPixmapInfo::SupportedDataTypes();
// SkYUVAInfo param is required to be non-null.
bool success = codec->queryYUVAInfo(kAllTypes, nullptr);
REPORTER_ASSERT(reporter, !success);
success = codec->queryYUVAInfo(&yuvaPixmapInfo);
// Fails when there is no support for YUVA planes.
success = codec->queryYUVAInfo(kNoTypes, &yuvaPixmapInfo);
REPORTER_ASSERT(reporter, !success);
success = codec->queryYUVAInfo(kAllTypes, &yuvaPixmapInfo);
REPORTER_ASSERT(reporter, SkToBool(expectedInfo) == success);
if (!success) {
return;
@ -42,13 +49,15 @@ static void codec_yuv(skiatest::Reporter* reporter,
int numPlanes = yuvaPixmapInfo.numPlanes();
REPORTER_ASSERT(reporter, numPlanes <= SkYUVAInfo::kMaxPlanes);
size_t totalBytes = 0;
for (int i = 0; i < numPlanes; ++i) {
const SkImageInfo& planeInfo = yuvaPixmapInfo.planeInfo(i);
SkColorType planeCT = planeInfo.colorType();
REPORTER_ASSERT(reporter, !planeInfo.isEmpty());
REPORTER_ASSERT(reporter, planeInfo.colorType() != kUnknown_SkColorType);
REPORTER_ASSERT(reporter, planeCT != kUnknown_SkColorType);
REPORTER_ASSERT(reporter, planeInfo.validRowBytes(yuvaPixmapInfo.rowBytes(i)));
totalBytes += planeInfo.height()*yuvaPixmapInfo.rowBytes(i);
// Currently all planes must share a data type, gettable as SkYUVAPixmapInfo::dataType().
auto [numChannels, planeDataType] = SkYUVAPixmapInfo::NumChannelsAndDataType(planeCT);
REPORTER_ASSERT(reporter, planeDataType == yuvaPixmapInfo.dataType());
}
for (int i = numPlanes; i < SkYUVAInfo::kMaxPlanes; ++i) {
const SkImageInfo& planeInfo = yuvaPixmapInfo.planeInfo(i);

View File

@ -444,7 +444,7 @@ int DDLPromiseImageHelper::addImage(SkImage* image) {
auto codec = SkCodecImageGenerator::MakeFromEncodedCodec(ib->refEncodedData());
SkYUVAPixmapInfo yuvaInfo;
if (codec && codec->queryYUVAInfo(&yuvaInfo)) {
if (codec && codec->queryYUVAInfo(fSupportedYUVADataTypes, &yuvaInfo)) {
auto yuvaPixmaps = SkYUVAPixmaps::Allocate(yuvaInfo);
SkAssertResult(codec->getYUVAPlanes(yuvaPixmaps));
SkASSERT(yuvaPixmaps.isValid());

View File

@ -124,7 +124,8 @@ private:
// all the replaying is complete. This will pin the GrBackendTextures in VRAM.
class DDLPromiseImageHelper {
public:
DDLPromiseImageHelper() = default;
DDLPromiseImageHelper(const SkYUVAPixmapInfo::SupportedDataTypes& supportedYUVADataTypes)
: fSupportedYUVADataTypes(supportedYUVADataTypes) {}
~DDLPromiseImageHelper() = default;
// Convert the SkPicture into SkData replacing all the SkImages with an index.
@ -270,6 +271,7 @@ private:
// returns -1 on failure
int findOrDefineImage(SkImage* image);
SkYUVAPixmapInfo::SupportedDataTypes fSupportedYUVADataTypes;
SkTArray<PromiseImageInfo> fImageInfo;
};

View File

@ -48,7 +48,7 @@ bool LazyYUVImage::reset(sk_sp<SkData> data, GrMipmapped mipmapped) {
}
SkYUVAPixmapInfo yuvaPixmapInfo;
if (!codec->queryYUVAInfo(&yuvaPixmapInfo)) {
if (!codec->queryYUVAInfo(SkYUVAPixmapInfo::SupportedDataTypes::All(), &yuvaPixmapInfo)) {
return false;
}
fPixmaps = SkYUVAPixmaps::Allocate(yuvaPixmapInfo);

View File

@ -258,7 +258,8 @@ static void run_ddl_benchmark(sk_gpu_test::TestContext* testContext, GrDirectCon
SkIRect viewport = dstSurface->imageInfo().bounds();
DDLPromiseImageHelper promiseImageHelper;
SkYUVAPixmapInfo::SupportedDataTypes supportedYUVADataTypes(*context);
DDLPromiseImageHelper promiseImageHelper(supportedYUVADataTypes);
sk_sp<SkData> compressedPictureData = promiseImageHelper.deflateSKP(inputPicture);
if (!compressedPictureData) {
exitf(ExitErr::kUnavailable, "DDL: conversion of skp failed");