| Index: src/core/SkImageCacherator.cpp
|
| diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp
|
| index 71afc0e68aa7a29608e82ebcc887b10f03f5d10e..959a84fa07651d39cc8b00b4f5361c7b89833754 100644
|
| --- a/src/core/SkImageCacherator.cpp
|
| +++ b/src/core/SkImageCacherator.cpp
|
| @@ -13,6 +13,7 @@
|
| #include "SkNextID.h"
|
| #include "SkPixelRef.h"
|
| #include "SkResourceCache.h"
|
| +#include <SkCanvas.h>
|
|
|
| #if SK_SUPPORT_GPU
|
| #include "GrContext.h"
|
| @@ -83,19 +84,28 @@ static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) {
|
| // Note, this returns a new, mutable, bitmap, with a new genID.
|
| // If you want the immutable bitmap with the same ID as our cacherator, call tryLockAsBitmap()
|
| //
|
| -bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) {
|
| +bool SkImageCacherator::generateBitmap(SkBitmap* bitmap, SkScalar scaleHint) {
|
| SkBitmap::Allocator* allocator = SkResourceCache::GetAllocator();
|
|
|
| ScopedGenerator generator(this);
|
| - const SkImageInfo& genInfo = generator->getInfo();
|
| + SkImageInfo genInfo = generator->getInfo();
|
| if (fInfo.dimensions() == genInfo.dimensions()) {
|
| SkASSERT(fOrigin.x() == 0 && fOrigin.y() == 0);
|
| - // fast-case, no copy needed
|
| - return generator->tryGenerateBitmap(bitmap, fInfo, allocator);
|
| + SkISize size;
|
| + SkImageGenerator::Result res = generator->canDecodeAndScale(kRGB_565_SkColorType, scaleHint, &size, nullptr);
|
| + if (!(res & SkImageGenerator::kScale))
|
| + size = genInfo.dimensions();
|
| + if (res & SkImageGenerator::kDecode) {
|
| + genInfo = genInfo.Make(size.width(), size.height(), kRGB_565_SkColorType,
|
| + kOpaque_SkAlphaType, genInfo.profileType());
|
| + } else {
|
| + genInfo = genInfo.makeWH(size.width(), size.height());
|
| + }
|
| + return generator->tryGenerateBitmap(bitmap, genInfo, allocator);
|
| } else {
|
| // need to handle subsetting, so we first generate the full size version, and then
|
| // "read" from it to get our subset. See skbug.com/4213
|
| -
|
| + // TODO SkImageGenerator::getPixels with smaller size implies downscalling, not a subset
|
| SkBitmap full;
|
| if (!generator->tryGenerateBitmap(&full, genInfo, allocator)) {
|
| return false;
|
| @@ -110,16 +120,31 @@ bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) {
|
|
|
| //////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
| -bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client) {
|
| - if (SkBitmapCache::Find(fUniqueID, bitmap)) {
|
| - return check_output_bitmap(*bitmap, fUniqueID);
|
| +static bool bitmap_fits_scale(const SkISize &fullSize, const SkBitmap *scaled, const SkScalar scaleHint) {
|
| + // This optimization is about memory and required quality - it is not about sample cost of large textures on GPU:
|
| + // if the bitmap is already available and larger than hinted, use it.
|
| + if (scaled->width() < SkScalarFloorToInt(scaleHint * SkIntToScalar(fullSize.width())))
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| +bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client, const SkScalar scaleHint) {
|
| + bool foundInCache = SkBitmapCache::Find(fUniqueID, bitmap);
|
| + if (foundInCache) {
|
| + if (bitmap_fits_scale(info().dimensions(), bitmap, scaleHint)) {
|
| + return check_output_bitmap(*bitmap, fUniqueID);
|
| + }
|
| + // if it doesn't fit the size, generate new one
|
| }
|
|
|
| - if (!this->generateBitmap(bitmap)) {
|
| + if (!this->generateBitmap(bitmap, scaleHint)) {
|
| return false;
|
| }
|
|
|
| bitmap->pixelRef()->setImmutableWithID(fUniqueID);
|
| + // if inadequate scale was in cache, remove it from cache first
|
| + if (foundInCache)
|
| + SkNotifyBitmapGenIDIsStale(fUniqueID);
|
| SkBitmapCache::Add(fUniqueID, *bitmap);
|
| if (client) {
|
| as_IB(client)->notifyAddedToCache();
|
| @@ -128,8 +153,8 @@ bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client)
|
| return true;
|
| }
|
|
|
| -bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client) {
|
| - if (this->tryLockAsBitmap(bitmap, client)) {
|
| +bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client, SkScalar scaleHint) {
|
| + if (this->tryLockAsBitmap(bitmap, client, scaleHint)) {
|
| return check_output_bitmap(*bitmap, fUniqueID);
|
| }
|
|
|
| @@ -184,6 +209,7 @@ static GrTexture* load_compressed_into_texture(GrContext* ctx, SkData* data, GrS
|
| }
|
|
|
| desc.fConfig = config;
|
| +
|
| return ctx->textureProvider()->createTexture(desc, true, rawStart, 0);
|
| }
|
|
|
|
|