| 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
|
| +}
|
| +
|
|
|