Index: src/core/SkImageCacherator.cpp |
diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b225612a17f77ab1f7f2f88b3692fcb6475adbba |
--- /dev/null |
+++ b/src/core/SkImageCacherator.cpp |
@@ -0,0 +1,144 @@ |
+/* |
+ * 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 "SkBitmap.h" |
+#include "SkBitmapCache.h" |
+#include "SkImageCacherator.h" |
+#include "SkPixelRef.h" |
+ |
+#if SK_SUPPORT_GPU |
+#include "GrContext.h" |
+#include "GrGpuResourcePriv.h" |
+#include "GrResourceKey.h" |
+#include "GrTextureAccess.h" |
+#include "SkGr.h" |
+#include "SkGrPriv.h" |
+#endif |
+ |
+SkImageCacherator::SkImageCacherator(SkImageGenerator* gen) : fGenerator(gen) {} |
+ |
+SkImageCacherator::~SkImageCacherator() { |
+ delete fGenerator; |
+} |
+ |
+static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) { |
+ 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(); |
+ |
+ if (this->tryLockAsBitmap(bitmap)) { |
+ return check_output_bitmap(*bitmap, uniqueID); |
+ } |
+ |
+#if SK_SUPPORT_GPU |
+ // Try to get a texture and read it back to raster (and then cache that with our ID) |
+ |
+ SkAutoTUnref<GrTexture> tex(fGenerator->generateTexture(nullptr, kUntiled_SkImageUsageType)); |
+ if (!tex) { |
+ bitmap->reset(); |
+ return false; |
+ } |
+ |
+ const SkImageInfo& info = this->info(); |
+ 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); |
+#else |
+ return false; |
+#endif |
+} |
+ |
+////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+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 |
+} |
+ |