Chromium Code Reviews| Index: src/core/SkImageCacherator.cpp |
| diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f829119cdcebe593b2a87b840ad11848f06b09a2 |
| --- /dev/null |
| +++ b/src/core/SkImageCacherator.cpp |
| @@ -0,0 +1,143 @@ |
| +/* |
| + * Copyright 2015 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "SkTypes.h" |
| + |
| +#if SK_SUPPORT_GPU |
| +#include "GrContext.h" |
| +#include "GrGpuResourcePriv.h" |
| +#include "GrResourceKey.h" |
| +#include "GrTextureAccess.h" |
| +#endif |
| + |
| +#include "SkBitmap.h" |
| +#include "SkBitmapCache.h" |
| +#include "SkGr.h" |
| +#include "SkGrPriv.h" |
| +#include "SkImageCacherator.h" |
| +#include "SkPixelRef.h" |
| + |
| + |
| +SkImageCacherator::SkImageCacherator(SkImageGenerator* gen) : fGenerator(gen) {} |
| + |
| +SkImageCacherator::~SkImageCacherator() { |
| + delete fGenerator; |
|
scroggo
2015/08/13 19:59:13
SkDELETE?
reed1
2015/08/13 20:57:08
Done.
|
| +} |
| + |
| +static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) { |
|
scroggo
2015/08/13 19:59:13
This always returns true, so maybe it should retur
reed1
2015/08/13 20:57:08
Acknowledged.
|
| + SkASSERT(bitmap.getGenerationID() == expectedID); |
| + SkASSERT(bitmap.isImmutable()); |
| + SkASSERT(bitmap.getPixels()); |
| + return true; |
| +} |
| + |
| +static bool generate_bitmap(SkImageGenerator* generator, SkBitmap* bitmap) { |
| + if (!bitmap->tryAllocPixels(generator->getInfo()) || |
| + !generator->getPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes())) |
| + { |
| + bitmap->reset(); |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap) { |
| + const uint32_t uniqueID = fGenerator->uniqueID(); |
| + |
| + if (SkBitmapCache::Find(uniqueID, bitmap)) { |
| + return check_output_bitmap(*bitmap, uniqueID); |
| + } |
| + if (!generate_bitmap(fGenerator, bitmap)) { |
| + return false; |
| + } |
| + |
| + bitmap->pixelRef()->setImmutableWithID(uniqueID); |
| + SkBitmapCache::Add(uniqueID, *bitmap); |
| + return true; |
| +} |
| + |
| +bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap) { |
| + const uint32_t uniqueID = fGenerator->uniqueID(); |
| + const SkImageInfo& info = this->info(); |
|
scroggo
2015/08/13 19:59:13
Maybe move this down closer to where it's used?
reed1
2015/08/13 20:57:08
Done.
|
| + |
| + if (this->tryLockAsBitmap(bitmap)) { |
| + return check_output_bitmap(*bitmap, uniqueID); |
| + } |
| + |
| + // Try to get a texture and read it back to raster (and then cache that with our ID) |
|
scroggo
2015/08/13 19:59:13
A read back is potentially expensive, right? Shoul
reed1
2015/08/13 20:57:08
Calling the generator itself can be very expensive
|
| + |
| + SkAutoTUnref<GrTexture> tex(fGenerator->generateTexture(nullptr, kUntiled_SkImageUsageType)); |
| + if (!tex) { |
| + bitmap->reset(); |
| + return false; |
| + } |
| + |
| + if (!bitmap->tryAllocPixels(info)) { |
| + bitmap->reset(); |
| + return false; |
| + } |
| + |
| + const uint32_t pixelOpsFlags = 0; |
| + if (!tex->readPixels(0, 0, bitmap->width(), bitmap->height(), SkImageInfo2GrPixelConfig(info), |
| + bitmap->getPixels(), bitmap->rowBytes(), pixelOpsFlags)) { |
| + bitmap->reset(); |
| + return false; |
| + } |
| + |
| + bitmap->pixelRef()->setImmutableWithID(uniqueID); |
| + SkBitmapCache::Add(uniqueID, *bitmap); |
| + return check_output_bitmap(*bitmap, uniqueID); |
| +} |
| + |
| +////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +GrTexture* SkImageCacherator::tryLockAsTexture(GrContext* ctx, SkImageUsageType usage) { |
| +#if SK_SUPPORT_GPU |
| + const uint32_t uniqueID = fGenerator->uniqueID(); |
| + const SkImageInfo& info = this->info(); |
| + |
| + GrUniqueKey key; |
| + GrMakeKeyFromImageID(&key, uniqueID, info.width(), info.height(), SkIPoint::Make(0, 0), |
| + *ctx->caps(), usage); |
| + GrTexture* tex = ctx->textureProvider()->findAndRefTextureByUniqueKey(key); |
| + if (tex) { |
| + return tex; // we got a cache hit! |
| + } |
| + |
| + tex = fGenerator->generateTexture(ctx, usage); |
| + if (tex) { |
| + tex->resourcePriv().setUniqueKey(key); |
| + } |
| + return tex; |
| +#else |
| + return nullptr; |
| +#endif |
| +} |
| + |
| +GrTexture* SkImageCacherator::lockAsTexture(GrContext* ctx, SkImageUsageType usage) { |
| +#if SK_SUPPORT_GPU |
| + if (!ctx) { |
| + return nullptr; |
| + } |
| + if (GrTexture* tex = this->tryLockAsTexture(ctx, usage)) { |
| + return tex; |
| + } |
| + |
| + // Try to get a bitmap and then upload/cache it as a texture |
| + |
| + SkBitmap bitmap; |
| + if (!generate_bitmap(fGenerator, &bitmap)) { |
| + return nullptr; |
| + } |
| + return GrRefCachedBitmapTexture(ctx, bitmap, usage); |
| +#else |
| + return nullptr; |
| +#endif |
| +} |
| + |