Shared image generator
Introduce a new ref counted class (SharedGenerator), to facilitate SkImageGenerator sharing among multiple cacherators. Plumbing only for now, no actual sharing. R=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2451273006 Review-Url: https://codereview.chromium.org/2451273006
This commit is contained in:
parent
a70558e2bb
commit
f0c38f5fe6
@ -10,6 +10,7 @@
|
||||
#include "SkImage_Base.h"
|
||||
#include "SkImageCacherator.h"
|
||||
#include "SkMallocPixelRef.h"
|
||||
#include "SkMutex.h"
|
||||
#include "SkNextID.h"
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkResourceCache.h"
|
||||
@ -32,18 +33,58 @@
|
||||
// see skbug.com/ 4971, 5128, ...
|
||||
//#define SK_SUPPORT_COMPRESSED_TEXTURES_IN_CACHERATOR
|
||||
|
||||
// Ref-counted tuple(SkImageGenerator, SkMutex) which allows sharing of one generator
|
||||
// among several cacherators.
|
||||
class SkImageCacherator::SharedGenerator final : public SkNVRefCnt<SharedGenerator> {
|
||||
public:
|
||||
static sk_sp<SharedGenerator> Make(SkImageGenerator* gen) {
|
||||
return gen ? sk_sp<SharedGenerator>(new SharedGenerator(gen)) : nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit SharedGenerator(SkImageGenerator* gen) : fGenerator(gen) { SkASSERT(gen); }
|
||||
|
||||
friend class ScopedGenerator;
|
||||
|
||||
std::unique_ptr<SkImageGenerator> fGenerator;
|
||||
SkMutex fMutex;
|
||||
};
|
||||
|
||||
|
||||
// Helper for exclusive access to a shared generator.
|
||||
class SkImageCacherator::ScopedGenerator {
|
||||
public:
|
||||
ScopedGenerator(const sk_sp<SharedGenerator>& gen)
|
||||
: fSharedGenerator(gen)
|
||||
, fAutoAquire(gen->fMutex) {}
|
||||
|
||||
SkImageGenerator* operator->() const {
|
||||
fSharedGenerator->fMutex.assertHeld();
|
||||
return fSharedGenerator->fGenerator.get();
|
||||
}
|
||||
|
||||
operator SkImageGenerator*() const {
|
||||
fSharedGenerator->fMutex.assertHeld();
|
||||
return fSharedGenerator->fGenerator.get();
|
||||
}
|
||||
|
||||
private:
|
||||
const sk_sp<SharedGenerator>& fSharedGenerator;
|
||||
SkAutoExclusive fAutoAquire;
|
||||
};
|
||||
|
||||
SkImageCacherator::Validator::Validator(SkImageGenerator* gen, const SkIRect* subset)
|
||||
// We are required to take ownership of gen, regardless of whether we instantiate a cacherator
|
||||
// or not. On instantiation, the client is responsible for transferring ownership.
|
||||
: fGenerator(gen) {
|
||||
: fSharedGenerator(SkImageCacherator::SharedGenerator::Make(gen)) {
|
||||
|
||||
if (!gen) {
|
||||
if (!fSharedGenerator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SkImageInfo& info = gen->getInfo();
|
||||
if (info.isEmpty()) {
|
||||
fGenerator.reset();
|
||||
fSharedGenerator.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -51,7 +92,7 @@ SkImageCacherator::Validator::Validator(SkImageGenerator* gen, const SkIRect* su
|
||||
const SkIRect bounds = SkIRect::MakeWH(info.width(), info.height());
|
||||
if (subset) {
|
||||
if (!bounds.contains(*subset)) {
|
||||
fGenerator.reset();
|
||||
fSharedGenerator.reset();
|
||||
return;
|
||||
}
|
||||
if (*subset != bounds) {
|
||||
@ -66,6 +107,8 @@ SkImageCacherator::Validator::Validator(SkImageGenerator* gen, const SkIRect* su
|
||||
fOrigin = SkIPoint::Make(subset->x(), subset->y());
|
||||
}
|
||||
|
||||
SkImageCacherator::Validator::~Validator() {}
|
||||
|
||||
SkImageCacherator* SkImageCacherator::NewFromGenerator(SkImageGenerator* gen,
|
||||
const SkIRect* subset) {
|
||||
Validator validator(gen, subset);
|
||||
@ -74,16 +117,18 @@ SkImageCacherator* SkImageCacherator::NewFromGenerator(SkImageGenerator* gen,
|
||||
}
|
||||
|
||||
SkImageCacherator::SkImageCacherator(Validator* validator)
|
||||
: fNotThreadSafeGenerator(validator->fGenerator.release()) // we take ownership
|
||||
: fSharedGenerator(std::move(validator->fSharedGenerator)) // we take ownership
|
||||
, fInfo(validator->fInfo)
|
||||
, fOrigin(validator->fOrigin)
|
||||
, fUniqueID(validator->fUniqueID)
|
||||
{
|
||||
SkASSERT(fNotThreadSafeGenerator);
|
||||
SkASSERT(fSharedGenerator);
|
||||
}
|
||||
|
||||
SkImageCacherator::~SkImageCacherator() {}
|
||||
|
||||
SkData* SkImageCacherator::refEncoded(GrContext* ctx) {
|
||||
ScopedGenerator generator(this);
|
||||
ScopedGenerator generator(fSharedGenerator);
|
||||
return generator->refEncodedData(ctx);
|
||||
}
|
||||
|
||||
@ -100,7 +145,7 @@ static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) {
|
||||
bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) {
|
||||
SkBitmap::Allocator* allocator = SkResourceCache::GetAllocator();
|
||||
|
||||
ScopedGenerator generator(this);
|
||||
ScopedGenerator generator(fSharedGenerator);
|
||||
const SkImageInfo& genInfo = generator->getInfo();
|
||||
if (fInfo.dimensions() == genInfo.dimensions()) {
|
||||
SkASSERT(fOrigin.x() == 0 && fOrigin.y() == 0);
|
||||
@ -124,7 +169,7 @@ bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) {
|
||||
|
||||
bool SkImageCacherator::directGeneratePixels(const SkImageInfo& info, void* pixels, size_t rb,
|
||||
int srcX, int srcY) {
|
||||
ScopedGenerator generator(this);
|
||||
ScopedGenerator generator(fSharedGenerator);
|
||||
const SkImageInfo& genInfo = generator->getInfo();
|
||||
// Currently generators do not natively handle subsets, so check that first.
|
||||
if (srcX || srcY || genInfo.width() != info.width() || genInfo.height() != info.height()) {
|
||||
@ -169,7 +214,7 @@ bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client,
|
||||
SkAutoTUnref<GrTexture> tex;
|
||||
|
||||
{
|
||||
ScopedGenerator generator(this);
|
||||
ScopedGenerator generator(fSharedGenerator);
|
||||
SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width(), fInfo.height());
|
||||
tex.reset(generator->generateTexture(nullptr, &subset));
|
||||
}
|
||||
@ -281,7 +326,7 @@ GrTexture* SkImageCacherator::lockTexture(GrContext* ctx, const GrUniqueKey& key
|
||||
|
||||
// 2. Ask the generator to natively create one
|
||||
{
|
||||
ScopedGenerator generator(this);
|
||||
ScopedGenerator generator(fSharedGenerator);
|
||||
SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width(), fInfo.height());
|
||||
if (GrTexture* tex = generator->generateTexture(ctx, &subset)) {
|
||||
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kNative_LockTexturePath,
|
||||
@ -307,7 +352,7 @@ GrTexture* SkImageCacherator::lockTexture(GrContext* ctx, const GrUniqueKey& key
|
||||
|
||||
// 4. Ask the generator to return YUV planes, which the GPU can convert
|
||||
{
|
||||
ScopedGenerator generator(this);
|
||||
ScopedGenerator generator(fSharedGenerator);
|
||||
Generator_GrYUVProvider provider(generator);
|
||||
sk_sp<GrTexture> tex = provider.refAsTexture(ctx, desc, true);
|
||||
if (tex) {
|
||||
|
@ -9,7 +9,6 @@
|
||||
#define SkImageCacherator_DEFINED
|
||||
|
||||
#include "SkImageGenerator.h"
|
||||
#include "SkMutex.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
class GrContext;
|
||||
@ -26,6 +25,8 @@ public:
|
||||
// Takes ownership of the generator
|
||||
static SkImageCacherator* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
|
||||
|
||||
~SkImageCacherator();
|
||||
|
||||
const SkImageInfo& info() const { return fInfo; }
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
|
||||
@ -68,15 +69,19 @@ public:
|
||||
int srcX, int srcY);
|
||||
|
||||
private:
|
||||
class SharedGenerator;
|
||||
class ScopedGenerator;
|
||||
|
||||
struct Validator {
|
||||
Validator(SkImageGenerator*, const SkIRect* subset);
|
||||
~Validator();
|
||||
|
||||
operator bool() const { return fGenerator.get(); }
|
||||
operator bool() const { return fSharedGenerator.get(); }
|
||||
|
||||
std::unique_ptr<SkImageGenerator> fGenerator;
|
||||
SkImageInfo fInfo;
|
||||
SkIPoint fOrigin;
|
||||
uint32_t fUniqueID;
|
||||
sk_sp<SharedGenerator> fSharedGenerator;
|
||||
SkImageInfo fInfo;
|
||||
SkIPoint fOrigin;
|
||||
uint32_t fUniqueID;
|
||||
};
|
||||
|
||||
SkImageCacherator(Validator*);
|
||||
@ -90,25 +95,10 @@ private:
|
||||
SkImage::CachingHint, bool willBeMipped, SkSourceGammaTreatment);
|
||||
#endif
|
||||
|
||||
class ScopedGenerator {
|
||||
SkImageCacherator* fCacher;
|
||||
public:
|
||||
ScopedGenerator(SkImageCacherator* cacher) : fCacher(cacher) {
|
||||
fCacher->fMutexForGenerator.acquire();
|
||||
}
|
||||
~ScopedGenerator() {
|
||||
fCacher->fMutexForGenerator.release();
|
||||
}
|
||||
SkImageGenerator* operator->() const { return fCacher->fNotThreadSafeGenerator; }
|
||||
operator SkImageGenerator*() const { return fCacher->fNotThreadSafeGenerator; }
|
||||
};
|
||||
|
||||
SkMutex fMutexForGenerator;
|
||||
SkAutoTDelete<SkImageGenerator> fNotThreadSafeGenerator;
|
||||
|
||||
const SkImageInfo fInfo;
|
||||
const SkIPoint fOrigin;
|
||||
const uint32_t fUniqueID;
|
||||
sk_sp<SharedGenerator> fSharedGenerator;
|
||||
const SkImageInfo fInfo;
|
||||
const SkIPoint fOrigin;
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
friend class GrImageTextureMaker;
|
||||
friend class SkImage;
|
||||
|
Loading…
Reference in New Issue
Block a user