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:
parent
4964300530
commit
9f8ee0dbb1
@ -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.
|
||||
|
@ -22,7 +22,6 @@ class SkImage;
|
||||
class SkPromiseImageTexture;
|
||||
class SkSurface;
|
||||
struct SkYUVAIndex;
|
||||
struct SkYUVASizeInfo;
|
||||
|
||||
/*
|
||||
* This class is intended to be used as:
|
||||
|
@ -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&,
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user