Remove legacy SkImageGenerator YUV planes interface

Bug: skia:10632
Change-Id: Iaed6b51e03ef9023a74d77f3262104c1677c416f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/327917
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Brian Salomon 2020-10-19 13:31:49 -04:00 committed by Skia Commit-Bot
parent 4964300530
commit 9f8ee0dbb1
10 changed files with 110 additions and 250 deletions

View File

@ -9,10 +9,15 @@ Milestone 88
* <insert new release notes here>
* Legacy 8-bit YUV interface removed from SkImageGenerator. Use more flexible SkYUVAPixmaps-
based interface instead.
https://review.skia.org/327917
* New variant of SkImage::MakeFromYUVATextures. Takes a new type GrYUVATextures
which wraps an SkYUVAInfo and compatible set of GrBackendTextures. The provides
a more complete and structured specification of the planar configuration. Previous
version is deprecated.
https://review.skia.org/317762
* Add field to GrContextOptions to disable mipmap support even if the backend
supports it.

View File

@ -22,7 +22,6 @@ class SkImage;
class SkPromiseImageTexture;
class SkSurface;
struct SkYUVAIndex;
struct SkYUVASizeInfo;
/*
* This class is intended to be used as:

View File

@ -113,39 +113,6 @@ public:
*/
bool getYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps);
/**
* Deprecated. Use queryYUVAInfo instead for more structured YUVA plane specification.
*
* If decoding to YUV is supported, this returns true. Otherwise, this
* returns false and does not modify any of the parameters.
*
* @param sizeInfo Output parameter indicating the sizes and required
* allocation widths of the Y, U, V, and A planes.
* @param yuvaIndices How the YUVA planes are organized/used
* @param colorSpace Output parameter.
*/
bool queryYUVA8(SkYUVASizeInfo* sizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* colorSpace) const;
/**
* Deprecated. Use getYUVAPlanes instead for more structured YUVA plane retrieval.
*
* Returns true on success and false on failure.
* This always attempts to perform a full decode. If the client only
* wants size, it should call queryYUVA8().
*
* @param sizeInfo Needs to exactly match the values returned by the
* query, except the WidthBytes may be larger than the
* recommendation (but not smaller).
* @param yuvaIndices Needs to exactly match the values returned by the query.
* @param planes Memory for the Y, U, V, and A planes. Note that, depending on the
* settings in yuvaIndices, anywhere from 1..4 planes could be returned.
*/
bool getYUVA8Planes(const SkYUVASizeInfo& sizeInfo,
const SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
void* planes[]);
#if SK_SUPPORT_GPU
/**
* If the generator can natively/efficiently return its pixels as a GPU image (backed by a
@ -212,10 +179,6 @@ protected:
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; }
virtual bool onGetYUVA8Planes(const SkYUVASizeInfo&, const SkYUVAIndex[SkYUVAIndex::kIndexCount],
void*[4] /*planes*/) { return false; }
#if SK_SUPPORT_GPU
// returns nullptr
virtual GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&,

View File

@ -42,34 +42,6 @@ bool SkImageGenerator::getYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {
return this->onGetYUVAPlanes(yuvaPixmaps);
}
bool SkImageGenerator::queryYUVA8(SkYUVASizeInfo* sizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* colorSpace) const {
SkASSERT(sizeInfo);
return this->onQueryYUVA8(sizeInfo, yuvaIndices, colorSpace);
}
bool SkImageGenerator::getYUVA8Planes(const SkYUVASizeInfo& sizeInfo,
const SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
void* planes[SkYUVASizeInfo::kMaxCount]) {
for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
SkASSERT(sizeInfo.fSizes[i].fWidth >= 0);
SkASSERT(sizeInfo.fSizes[i].fHeight >= 0);
SkASSERT(sizeInfo.fWidthBytes[i] >= (size_t) sizeInfo.fSizes[i].fWidth);
}
int numPlanes = 0;
SkASSERT(SkYUVAIndex::AreValidIndices(yuvaIndices, &numPlanes));
SkASSERT(planes);
for (int i = 0; i < numPlanes; ++i) {
SkASSERT(planes[i]);
}
return this->onGetYUVA8Planes(sizeInfo, yuvaIndices, planes);
}
#if SK_SUPPORT_GPU
#include "src/gpu/GrSurfaceProxyView.h"

View File

@ -5,10 +5,13 @@
* found in the LICENSE file.
*/
#include "src/core/SkBitmapCache.h"
#include "src/core/SkResourceCache.h"
#include "src/core/SkYUVPlanesCache.h"
#include "include/core/SkYUVAPixmaps.h"
#include "src/core/SkBitmapCache.h"
#include "src/core/SkCachedData.h"
#include "src/core/SkResourceCache.h"
#define CHECK_LOCAL(localCache, localName, globalName, ...) \
((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__))
@ -16,8 +19,8 @@ namespace {
static unsigned gYUVPlanesKeyNamespaceLabel;
struct YUVValue {
SkYUVPlanesCache::Info fInfo;
SkCachedData* fData;
SkYUVAPixmaps fPixmaps;
SkCachedData* fData;
};
struct YUVPlanesKey : public SkResourceCache::Key {
@ -32,11 +35,11 @@ struct YUVPlanesKey : public SkResourceCache::Key {
};
struct YUVPlanesRec : public SkResourceCache::Rec {
YUVPlanesRec(YUVPlanesKey key, SkCachedData* data, SkYUVPlanesCache::Info* info)
YUVPlanesRec(YUVPlanesKey key, SkCachedData* data, const SkYUVAPixmaps& pixmaps)
: fKey(key)
{
fValue.fData = data;
fValue.fInfo = *info;
fValue.fPixmaps = pixmaps;
fValue.fData->attachToCacheAndRef();
}
~YUVPlanesRec() override {
@ -64,13 +67,14 @@ struct YUVPlanesRec : public SkResourceCache::Rec {
return false;
}
result->fData = tmpData;
result->fInfo = rec.fValue.fInfo;
result->fPixmaps = rec.fValue.fPixmaps;
return true;
}
};
} // namespace
SkCachedData* SkYUVPlanesCache::FindAndRef(uint32_t genID, Info* info,
SkCachedData* SkYUVPlanesCache::FindAndRef(uint32_t genID,
SkYUVAPixmaps* pixmaps,
SkResourceCache* localCache) {
YUVValue result;
YUVPlanesKey key(genID);
@ -78,12 +82,12 @@ SkCachedData* SkYUVPlanesCache::FindAndRef(uint32_t genID, Info* info,
return nullptr;
}
*info = result.fInfo;
*pixmaps = result.fPixmaps;
return result.fData;
}
void SkYUVPlanesCache::Add(uint32_t genID, SkCachedData* data, Info* info,
void SkYUVPlanesCache::Add(uint32_t genID, SkCachedData* data, const SkYUVAPixmaps& pixmaps,
SkResourceCache* localCache) {
YUVPlanesKey key(genID);
return CHECK_LOCAL(localCache, add, Add, new YUVPlanesRec(key, data, info));
return CHECK_LOCAL(localCache, add, Add, new YUVPlanesRec(key, data, pixmaps));
}

View File

@ -8,42 +8,30 @@
#ifndef SkYUVPlanesCache_DEFINED
#define SkYUVPlanesCache_DEFINED
#include "include/core/SkImageInfo.h"
#include "include/core/SkYUVAIndex.h"
#include "include/core/SkYUVASizeInfo.h"
#include "src/core/SkCachedData.h"
#include "include/core/SkTypes.h"
class SkCachedData;
class SkResourceCache;
class SkYUVAPixmaps;
class SkYUVPlanesCache {
public:
/**
* The Info struct contains data about the 4 Y, U, V, and A planes of memory stored
* contiguously, in that order, as a single block of memory within SkYUVPlanesCache.
*
* fSizeInfo: fWidth, fHeight, and fWidthBytes of each of the Y, U, V, and A planes.
* fColorSpace: color space that will be used for the YUV -> RGB conversion.
*
* TODO: Replace this with SkYUVAPixmaps
*/
struct Info {
SkYUVASizeInfo fSizeInfo;
SkYUVAIndex fYUVAIndices[SkYUVAIndex::kIndexCount];
SkYUVColorSpace fColorSpace;
SkPixmap fPlanes[SkYUVASizeInfo::kMaxCount];
};
/**
* On success, return a ref to the SkCachedData that holds the pixels.
* On success, return a ref to the SkCachedData that holds the pixel data. The SkYUVAPixmaps
* contains a description of the YUVA data and has a SkPixmap for each plane that points
* into the SkCachedData.
*
* On failure, return nullptr.
*/
static SkCachedData* FindAndRef(uint32_t genID, Info* info,
static SkCachedData* FindAndRef(uint32_t genID,
SkYUVAPixmaps* pixmaps,
SkResourceCache* localCache = nullptr);
/**
* Add a pixelRef ID and its YUV planes data to the cache.
* Add a pixelRef ID and its YUV planes data to the cache. The SkYUVAPixmaps should contain
* SkPixmaps that store their pixel data in the SkCachedData.
*/
static void Add(uint32_t genID, SkCachedData* data, Info* info,
static void Add(uint32_t genID, SkCachedData* data, const SkYUVAPixmaps& pixmaps,
SkResourceCache* localCache = nullptr);
};

View File

@ -261,50 +261,39 @@ sk_sp<SkImage> SkImage::MakeFromGenerator(std::unique_ptr<SkImageGenerator> gene
GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext* ctx,
SkBudgeted budgeted) const {
SkYUVASizeInfo yuvSizeInfo;
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount];
SkYUVColorSpace yuvColorSpace;
SkPixmap planes[SkYUVASizeInfo::kMaxCount];
SkYUVAPixmapInfo::SupportedDataTypes supportedDataTypes(*ctx);
sk_sp<SkCachedData> dataStorage =
this->getPlanes(supportedDataTypes, &yuvSizeInfo, yuvaIndices, &yuvColorSpace, planes);
SkYUVAPixmaps yuvaPixmaps;
sk_sp<SkCachedData> dataStorage = this->getPlanes(supportedDataTypes, &yuvaPixmaps);
if (!dataStorage) {
return {};
}
GrSurfaceProxyView yuvViews[SkYUVASizeInfo::kMaxCount];
for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
if (yuvSizeInfo.fSizes[i].isEmpty()) {
SkASSERT(!yuvSizeInfo.fWidthBytes[i]);
continue;
}
int componentWidth = yuvSizeInfo.fSizes[i].fWidth;
int componentHeight = yuvSizeInfo.fSizes[i].fHeight;
for (int i = 0; i < yuvaPixmaps.numPlanes(); ++i) {
// If the sizes of the components are not all the same we choose to create exact-match
// textures for the smaller ones rather than add a texture domain to the draw.
// TODO: revisit this decision to improve texture reuse?
SkBackingFit fit =
(componentWidth != yuvSizeInfo.fSizes[0].fWidth) ||
(componentHeight != yuvSizeInfo.fSizes[0].fHeight)
? SkBackingFit::kExact : SkBackingFit::kApprox;
SkBackingFit fit = yuvaPixmaps.plane(i).dimensions() == this->dimensions()
? SkBackingFit::kApprox
: SkBackingFit::kExact;
// We grab a ref to cached yuv data. When the SkBitmap we create below goes away it will
// call the YUVGen_DataReleaseProc which will release this ref.
// call releaseProc which will release this ref.
// DDL TODO: Currently we end up creating a lazy proxy that will hold onto a ref to the
// SkImage in its lambda. This means that we'll keep the ref on the YUV data around for the
// life time of the proxy and not just upload. For non-DDL draws we should look into
// releasing this SkImage after uploads (by deleting the lambda after instantiation).
dataStorage->ref();
auto releaseProc = [](void*, void* data) {
SkCachedData* cachedData = static_cast<SkCachedData*>(data);
auto cachedData = static_cast<SkCachedData*>(data);
SkASSERT(cachedData);
cachedData->unref();
};
SkBitmap bitmap;
bitmap.installPixels(planes[i].info(), planes[i].writable_addr(),
yuvSizeInfo.fWidthBytes[i], releaseProc, dataStorage.get());
bitmap.installPixels(yuvaPixmaps.plane(i).info(),
yuvaPixmaps.plane(i).writable_addr(),
yuvaPixmaps.plane(i).rowBytes(),
releaseProc,
SkRef(dataStorage.get()));
bitmap.setImmutable();
GrBitmapTextureMaker maker(ctx, bitmap, fit);
@ -313,8 +302,6 @@ GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext*
if (!yuvViews[i]) {
return {};
}
SkASSERT(yuvViews[i].proxy()->dimensions() == yuvSizeInfo.fSizes[i]);
}
// TODO: investigate preallocating mip maps here
@ -326,10 +313,15 @@ GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext*
return {};
}
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount];
SkAssertResult(yuvaPixmaps.toYUVAIndices(yuvaIndices));
GrPaint paint;
const auto& caps = *ctx->priv().caps();
std::unique_ptr<GrFragmentProcessor> yuvToRgbProcessor = GrYUVtoRGBEffect::Make(
yuvViews, yuvaIndices, yuvColorSpace, GrSamplerState::Filter::kNearest, caps);
std::unique_ptr<GrFragmentProcessor> yuvToRgbProcessor =
GrYUVtoRGBEffect::Make(yuvViews,
yuvaIndices,
yuvaPixmaps.yuvaInfo().yuvColorSpace(),
GrSamplerState::Filter::kNearest,
*ctx->priv().caps());
// The pixels after yuv->rgb will be in the generator's color space.
// If onMakeColorTypeAndColorSpace has been called then this will not match this image's
@ -353,7 +345,9 @@ GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext*
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
const SkRect r = SkRect::Make(this->dimensions());
SkMatrix m = SkEncodedOriginToMatrix(yuvSizeInfo.fOrigin, this->width(), this->height());
SkMatrix m = SkEncodedOriginToMatrix(yuvaPixmaps.yuvaInfo().origin(),
this->width(),
this->height());
renderTargetContext->drawRect(nullptr, std::move(paint), GrAA::kNo, m, r);
SkASSERT(renderTargetContext->asTextureProxy());
@ -362,79 +356,31 @@ GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext*
sk_sp<SkCachedData> SkImage_Lazy::getPlanes(
const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVASizeInfo* yuvaSizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* yuvColorSpace,
SkPixmap planes[SkYUVASizeInfo::kMaxCount]) const {
SkYUVAPixmaps* yuvaPixmaps) const {
ScopedGenerator generator(fSharedGenerator);
SkYUVPlanesCache::Info yuvInfo;
sk_sp<SkCachedData> data(SkYUVPlanesCache::FindAndRef(generator->uniqueID(), &yuvInfo));
sk_sp<SkCachedData> data(SkYUVPlanesCache::FindAndRef(generator->uniqueID(), yuvaPixmaps));
// Try the new more descriptive SkImageGenerator/SkCodec YUVA interface.
if (SkYUVAPixmapInfo 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());
if (generator->getYUVAPlanes(pixmaps) &&
pixmaps.toLegacy(&yuvInfo.fSizeInfo, yuvInfo.fYUVAIndices)) {
yuvInfo.fColorSpace = yuvaPixmapInfo.yuvColorSpace();
std::copy_n(pixmaps.planes().data(), SkYUVAPixmapInfo::kMaxPlanes, yuvInfo.fPlanes);
// Decoding is done, cache the resulting YUV planes
SkYUVPlanesCache::Add(this->uniqueID(), data.get(), &yuvInfo);
} else {
data.reset();
}
if (data) {
SkASSERT(yuvaPixmaps->isValid());
SkASSERT(yuvaPixmaps->yuvaInfo().dimensions() == this->dimensions());
return data;
}
// Try the legacy SkImageGenerator/SkCodec YUVA interface.
if (!data) {
// Fetch yuv plane sizes for memory allocation.
if (!generator->queryYUVA8(&yuvInfo.fSizeInfo,
yuvInfo.fYUVAIndices,
&yuvInfo.fColorSpace)) {
return nullptr;
}
// Allocate the memory for YUVA
size_t totalSize(0);
for (int i = 0; i < SkYUVASizeInfo::kMaxCount; i++) {
SkASSERT((yuvInfo.fSizeInfo.fWidthBytes[i] && yuvInfo.fSizeInfo.fSizes[i].fHeight) ||
(!yuvInfo.fSizeInfo.fWidthBytes[i] && !yuvInfo.fSizeInfo.fSizes[i].fHeight));
totalSize += yuvInfo.fSizeInfo.fWidthBytes[i] * yuvInfo.fSizeInfo.fSizes[i].fHeight;
}
data.reset(SkResourceCache::NewCachedData(totalSize));
char* addr = static_cast<char*>(data->writable_data());
void* planePtrs[SkYUVASizeInfo::kMaxCount] = {};
for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
if (yuvInfo.fSizeInfo.fWidthBytes[i]) {
auto info = SkImageInfo::MakeA8(yuvInfo.fSizeInfo.fSizes[i]);
planePtrs[i] = addr;
yuvInfo.fPlanes[i].reset(info, addr, yuvInfo.fSizeInfo.fWidthBytes[i]);
addr += yuvInfo.fPlanes[i].rowBytes() * yuvInfo.fPlanes[i].height();
}
}
// Get the YUV planes.
if (!generator->getYUVA8Planes(yuvInfo.fSizeInfo, yuvInfo.fYUVAIndices, planePtrs)) {
return nullptr;
}
// Decoding is done, cache the resulting YUV planes
SkYUVPlanesCache::Add(this->uniqueID(), data.get(), &yuvInfo);
}
if (!data) {
SkYUVAPixmapInfo yuvaPixmapInfo;
if (!generator->queryYUVAInfo(supportedDataTypes, &yuvaPixmapInfo) ||
yuvaPixmapInfo.yuvaInfo().dimensions() != this->dimensions()) {
return nullptr;
}
*yuvaSizeInfo = yuvInfo.fSizeInfo;
std::copy_n(yuvInfo.fYUVAIndices, SkYUVAIndex::kIndexCount, yuvaIndices);
*yuvColorSpace = yuvInfo.fColorSpace;
std::copy_n(yuvInfo.fPlanes, SkYUVASizeInfo::kMaxCount, planes);
data.reset(SkResourceCache::NewCachedData(yuvaPixmapInfo.computeTotalBytes()));
SkYUVAPixmaps tempPixmaps = SkYUVAPixmaps::FromExternalMemory(yuvaPixmapInfo,
data->writable_data());
SkASSERT(tempPixmaps.isValid());
if (!generator->getYUVAPlanes(tempPixmaps)) {
return nullptr;
}
// Decoding is done, cache the resulting YUV planes
*yuvaPixmaps = tempPixmaps;
SkYUVPlanesCache::Add(this->uniqueID(), data.get(), *yuvaPixmaps);
return data;
}

View File

@ -70,10 +70,7 @@ private:
void addUniqueIDListener(sk_sp<SkIDChangeListener>) const;
#if SK_SUPPORT_GPU
sk_sp<SkCachedData> getPlanes(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVASizeInfo* yuvaSizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* yuvColorSpace,
SkPixmap planes[SkYUVASizeInfo::kMaxCount]) const;
SkYUVAPixmaps* pixmaps) const;
GrSurfaceProxyView textureProxyViewFromPlanes(GrRecordingContext*, SkBudgeted) const;
#endif

View File

@ -62,33 +62,18 @@ public:
DEF_TEST(ImageGenerator, reporter) {
MyImageGenerator ig;
SkYUVASizeInfo sizeInfo;
sizeInfo.fSizes[0] = SkISize::Make(200, 200);
sizeInfo.fSizes[1] = SkISize::Make(100, 100);
sizeInfo.fSizes[2] = SkISize::Make( 50, 50);
sizeInfo.fSizes[3] = SkISize::Make( 25, 25);
sizeInfo.fWidthBytes[0] = 0;
sizeInfo.fWidthBytes[1] = 0;
sizeInfo.fWidthBytes[2] = 0;
sizeInfo.fWidthBytes[3] = 0;
void* planes[4] = { nullptr };
SkYUVAIndex yuvaIndices[4];
SkYUVColorSpace colorSpace;
SkYUVAPixmapInfo yuvaPixmapInfo;
// Check that the YUV decoding API does not cause any crashes
ig.queryYUVA8(&sizeInfo, yuvaIndices, nullptr);
ig.queryYUVA8(&sizeInfo, yuvaIndices, &colorSpace);
sizeInfo.fWidthBytes[0] = 250;
sizeInfo.fWidthBytes[1] = 250;
sizeInfo.fWidthBytes[2] = 250;
sizeInfo.fWidthBytes[3] = 250;
yuvaIndices[0] = { 0, SkColorChannel::kR };
yuvaIndices[1] = { 1, SkColorChannel::kR };
yuvaIndices[2] = { 2, SkColorChannel::kR };
yuvaIndices[3] = { 3, SkColorChannel::kR };
int dummy;
planes[0] = planes[1] = planes[2] = planes[3] = &dummy;
ig.getYUVA8Planes(sizeInfo, yuvaIndices, planes);
ig.queryYUVAInfo(SkYUVAPixmapInfo::SupportedDataTypes::All(), &yuvaPixmapInfo);
SkYUVAInfo yuvaInfo({250, 250},
SkYUVAInfo::PlanarConfig::kY_UV_420,
kJPEG_Full_SkYUVColorSpace);
yuvaPixmapInfo = SkYUVAPixmapInfo(yuvaInfo,
SkYUVAPixmapInfo::DataType::kUnorm8,
/*rowBytes[]*/ nullptr);
SkYUVAPixmaps yuvaPixmaps = SkYUVAPixmaps::Allocate(yuvaPixmapInfo);
ig.getYUVAPlanes(yuvaPixmaps);
// Suppressed due to https://code.google.com/p/skia/issues/detail?id=4339
if (false) {

View File

@ -5,6 +5,8 @@
* found in the LICENSE file.
*/
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
#include "src/core/SkCachedData.h"
#include "src/core/SkResourceCache.h"
#include "src/core/SkYUVPlanesCache.h"
@ -31,47 +33,46 @@ static void check_data(skiatest::Reporter* reporter, SkCachedData* data,
DEF_TEST(YUVPlanesCache, reporter) {
SkResourceCache cache(1024);
SkYUVPlanesCache::Info yuvInfo;
for (int i = 0; i < SkYUVASizeInfo::kMaxCount; i++) {
yuvInfo.fSizeInfo.fSizes[i].fWidth = 20 * (i + 1);
yuvInfo.fSizeInfo.fSizes[i].fHeight = 10 * (i + 1);
yuvInfo.fSizeInfo.fWidthBytes[i] = 80 * (i + 1);
}
for (int i = 0; i < SkYUVAIndex::kIndexCount; ++i) {
yuvInfo.fYUVAIndices[i].fIndex = -1;
yuvInfo.fYUVAIndices[i].fChannel = SkColorChannel::kR;
}
yuvInfo.fColorSpace = kRec601_SkYUVColorSpace;
SkYUVAInfo yuvaInfo({5, 5},
SkYUVAInfo::PlanarConfig::kY_U_V_420,
kRec601_Limited_SkYUVColorSpace);
SkYUVAPixmapInfo yuvaPixmapInfo(yuvaInfo,
SkYUVAPixmapInfo::DataType::kUnorm8,
/*rowBytes[]*/ nullptr);
SkYUVAPixmaps yuvaPixmaps;
const uint32_t genID = 12345678;
SkCachedData* data = SkYUVPlanesCache::FindAndRef(genID, &yuvInfo, &cache);
REPORTER_ASSERT(reporter, nullptr == data);
SkCachedData* data = SkYUVPlanesCache::FindAndRef(genID, &yuvaPixmaps, &cache);
REPORTER_ASSERT(reporter, !data);
size_t size = 256;
size_t size = yuvaPixmapInfo.computeTotalBytes();
data = cache.newCachedData(size);
memset(data->writable_data(), 0xff, size);
SkYUVPlanesCache::Add(genID, data, &yuvInfo, &cache);
SkPixmap pmaps[SkYUVAInfo::kMaxPlanes];
yuvaPixmapInfo.initPixmapsFromSingleAllocation(data->writable_data(), pmaps);
yuvaPixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, pmaps);
SkYUVPlanesCache::Add(genID, data, yuvaPixmaps, &cache);
check_data(reporter, data, 2, kInCache, kLocked);
data->unref();
check_data(reporter, data, 1, kInCache, kUnlocked);
SkYUVPlanesCache::Info yuvInfoRead;
data = SkYUVPlanesCache::FindAndRef(genID, &yuvInfoRead, &cache);
SkYUVAPixmaps yuvaPixmapsRead;
data = SkYUVPlanesCache::FindAndRef(genID, &yuvaPixmapsRead, &cache);
REPORTER_ASSERT(reporter, data);
REPORTER_ASSERT(reporter, data->size() == size);
REPORTER_ASSERT(reporter, yuvInfo.fSizeInfo == yuvInfoRead.fSizeInfo);
REPORTER_ASSERT(reporter, yuvaPixmapsRead.yuvaInfo() == yuvaPixmaps.yuvaInfo());
for (int i = 0; i < SkYUVAIndex::kIndexCount; ++i) {
REPORTER_ASSERT(reporter, yuvInfo.fYUVAIndices[i] == yuvInfoRead.fYUVAIndices[i]);
for (int i = 0; i < yuvaPixmaps.numPlanes(); ++i) {
REPORTER_ASSERT(reporter, yuvaPixmaps.plane(i).info() == yuvaPixmapsRead.plane(i).info());
REPORTER_ASSERT(reporter, yuvaPixmaps.plane(i).addr() == yuvaPixmapsRead.plane(i).addr());
REPORTER_ASSERT(reporter, yuvaPixmaps.plane(i).rowBytes() ==
yuvaPixmapsRead.plane(i).rowBytes());
}
REPORTER_ASSERT(reporter, yuvInfo.fColorSpace == yuvInfoRead.fColorSpace);
check_data(reporter, data, 2, kInCache, kLocked);
cache.purgeAll();