Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Unified Diff: src/core/SkImageCacherator.cpp

Issue 2451273006: Shared image generator (Closed)
Patch Set: cleanup Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkImageCacherator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkImageCacherator.cpp
diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp
index 6858a4c09e04f5cc0e2a7a016042eb2aa4e54933..75f8734e838004ac63b3bc393524b2223d69603f 100644
--- a/src/core/SkImageCacherator.cpp
+++ b/src/core/SkImageCacherator.cpp
@@ -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) {
« no previous file with comments | « src/core/SkImageCacherator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698