expose generalized imagecache key
BUG=skia: R=mtklein@google.com, halcanary@google.com, qiankun.miao@intel.com Author: reed@google.com Review URL: https://codereview.chromium.org/483493003
This commit is contained in:
parent
53fecfb15d
commit
04617139f7
@ -8,6 +8,19 @@
|
||||
#include "Benchmark.h"
|
||||
#include "SkScaledImageCache.h"
|
||||
|
||||
namespace {
|
||||
static void* gGlobalAddress;
|
||||
class TestKey : public SkScaledImageCache::Key {
|
||||
public:
|
||||
void* fPtr;
|
||||
intptr_t fValue;
|
||||
|
||||
TestKey(intptr_t value) : fPtr(&gGlobalAddress), fValue(value) {
|
||||
this->init(sizeof(fPtr) + sizeof(fValue));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class ImageCacheBench : public Benchmark {
|
||||
SkScaledImageCache fCache;
|
||||
SkBitmap fBM;
|
||||
@ -22,12 +35,11 @@ public:
|
||||
}
|
||||
|
||||
void populateCache() {
|
||||
SkScalar scale = 1;
|
||||
for (int i = 0; i < CACHE_COUNT; ++i) {
|
||||
TestKey key(i);
|
||||
SkBitmap tmp;
|
||||
tmp.allocN32Pixels(1, 1);
|
||||
fCache.unlock(fCache.addAndLock(fBM, scale, scale, tmp));
|
||||
scale += 1;
|
||||
fCache.unlock(fCache.addAndLock(key, tmp));
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,10 +53,12 @@ protected:
|
||||
this->populateCache();
|
||||
}
|
||||
|
||||
TestKey key(-1);
|
||||
SkBitmap tmp;
|
||||
// search for a miss (-1 scale)
|
||||
for (int i = 0; i < loops; ++i) {
|
||||
(void)fCache.findAndLock(fBM, -1, -1, &tmp);
|
||||
SkDEBUGCODE(SkScaledImageCache::ID* id =) fCache.findAndLock(key, &tmp);
|
||||
SkASSERT(NULL == id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
'<(skia_src_path)/core/SkBBoxHierarchyRecord.cpp',
|
||||
'<(skia_src_path)/core/SkBBoxHierarchyRecord.h',
|
||||
'<(skia_src_path)/core/SkBitmap.cpp',
|
||||
'<(skia_src_path)/core/SkBitmapCache.cpp',
|
||||
'<(skia_src_path)/core/SkBitmapDevice.cpp',
|
||||
'<(skia_src_path)/core/SkBitmapFilter.h',
|
||||
'<(skia_src_path)/core/SkBitmapFilter.cpp',
|
||||
|
91
src/core/SkBitmapCache.cpp
Normal file
91
src/core/SkBitmapCache.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkBitmapCache.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
/**
|
||||
This function finds the bounds of the bitmap *within its pixelRef*.
|
||||
If the bitmap lacks a pixelRef, it will return an empty rect, since
|
||||
that doesn't make sense. This may be a useful enough function that
|
||||
it should be somewhere else (in SkBitmap?).
|
||||
*/
|
||||
static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
|
||||
if (!(bm.pixelRef())) {
|
||||
return SkIRect::MakeEmpty();
|
||||
}
|
||||
SkIPoint origin = bm.pixelRefOrigin();
|
||||
return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
|
||||
}
|
||||
|
||||
struct BitmapKey : public SkScaledImageCache::Key {
|
||||
public:
|
||||
BitmapKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds)
|
||||
: fGenID(genID)
|
||||
, fScaleX(scaleX)
|
||||
, fScaleY(scaleY)
|
||||
, fBounds(bounds)
|
||||
{
|
||||
this->init(sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(fBounds));
|
||||
}
|
||||
|
||||
uint32_t fGenID;
|
||||
SkScalar fScaleX;
|
||||
SkScalar fScaleY;
|
||||
SkIRect fBounds;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkScaledImageCache::ID* SkBitmapCache::FindAndLock(const SkBitmap& src,
|
||||
SkScalar invScaleX, SkScalar invScaleY,
|
||||
SkBitmap* result) {
|
||||
if (0 == invScaleX || 0 == invScaleY) {
|
||||
// degenerate, and the key we use for mipmaps
|
||||
return NULL;
|
||||
}
|
||||
BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_bitmap(src));
|
||||
return SkScaledImageCache::FindAndLock(key, result);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkBitmapCache::AddAndLock(const SkBitmap& src,
|
||||
SkScalar invScaleX, SkScalar invScaleY,
|
||||
const SkBitmap& result) {
|
||||
if (0 == invScaleX || 0 == invScaleY) {
|
||||
// degenerate, and the key we use for mipmaps
|
||||
return NULL;
|
||||
}
|
||||
BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_bitmap(src));
|
||||
return SkScaledImageCache::AddAndLock(key, result);
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
SkScaledImageCache::ID* SkBitmapCache::FindAndLock(uint32_t genID, int width, int height,
|
||||
SkBitmap* result) {
|
||||
BitmapKey key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
|
||||
return SkScaledImageCache::FindAndLock(key, result);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkBitmapCache::AddAndLock(uint32_t genID, int width, int height,
|
||||
const SkBitmap& result) {
|
||||
BitmapKey key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
|
||||
return SkScaledImageCache::AddAndLock(key, result);
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
SkScaledImageCache::ID* SkMipMapCache::FindAndLock(const SkBitmap& src, const SkMipMap** result) {
|
||||
BitmapKey key(src.getGenerationID(), SK_Scalar1, SK_Scalar1, get_bounds_from_bitmap(src));
|
||||
return SkScaledImageCache::FindAndLock(key, result);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkMipMapCache::AddAndLock(const SkBitmap& src, const SkMipMap* result) {
|
||||
BitmapKey key(src.getGenerationID(), SK_Scalar1, SK_Scalar1, get_bounds_from_bitmap(src));
|
||||
return SkScaledImageCache::AddAndLock(key, result);
|
||||
}
|
||||
|
45
src/core/SkBitmapCache.h
Normal file
45
src/core/SkBitmapCache.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBitmapCache_DEFINED
|
||||
#define SkBitmapCache_DEFINED
|
||||
|
||||
#include "SkScaledImageCache.h"
|
||||
|
||||
class SkBitmapCache {
|
||||
public:
|
||||
typedef SkScaledImageCache::ID ID;
|
||||
|
||||
static void Unlock(ID* id) {
|
||||
SkScaledImageCache::Unlock(id);
|
||||
}
|
||||
|
||||
/* Input: bitmap+inverse_scale */
|
||||
static ID* FindAndLock(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY,
|
||||
SkBitmap* result);
|
||||
static ID* AddAndLock(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY,
|
||||
const SkBitmap& result);
|
||||
|
||||
/* Input: bitmap_genID+width+height */
|
||||
static ID* FindAndLock(uint32_t genID, int width, int height, SkBitmap* result);
|
||||
|
||||
static ID* AddAndLock(uint32_t genID, int width, int height, const SkBitmap& result);
|
||||
};
|
||||
|
||||
class SkMipMapCache {
|
||||
public:
|
||||
typedef SkScaledImageCache::ID ID;
|
||||
|
||||
static void Unlock(ID* id) {
|
||||
SkScaledImageCache::Unlock(id);
|
||||
}
|
||||
|
||||
static ID* FindAndLock(const SkBitmap& src, const SkMipMap** result);
|
||||
static ID* AddAndLock(const SkBitmap& src, const SkMipMap* result);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,10 +1,11 @@
|
||||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkBitmapCache.h"
|
||||
#include "SkBitmapProcState.h"
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkFilterProc.h"
|
||||
@ -14,7 +15,6 @@
|
||||
#include "SkBitmapScaler.h"
|
||||
#include "SkMipMap.h"
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkScaledImageCache.h"
|
||||
#include "SkImageEncoder.h"
|
||||
|
||||
#if !SK_ARM_NEON_IS_NONE
|
||||
@ -183,9 +183,8 @@ bool SkBitmapProcState::possiblyScaleImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
fScaledCacheID = SkScaledImageCache::FindAndLock(fOrigBitmap,
|
||||
invScaleX, invScaleY,
|
||||
&fScaledBitmap);
|
||||
fScaledCacheID = SkBitmapCache::FindAndLock(fOrigBitmap, invScaleX, invScaleY,
|
||||
&fScaledBitmap);
|
||||
if (fScaledCacheID) {
|
||||
fScaledBitmap.lockPixels();
|
||||
if (!fScaledBitmap.getPixels()) {
|
||||
@ -216,10 +215,8 @@ bool SkBitmapProcState::possiblyScaleImage() {
|
||||
}
|
||||
|
||||
SkASSERT(NULL != fScaledBitmap.getPixels());
|
||||
fScaledCacheID = SkScaledImageCache::AddAndLock(fOrigBitmap,
|
||||
invScaleX,
|
||||
invScaleY,
|
||||
fScaledBitmap);
|
||||
fScaledCacheID = SkBitmapCache::AddAndLock(fOrigBitmap, invScaleX, invScaleY,
|
||||
fScaledBitmap);
|
||||
if (!fScaledCacheID) {
|
||||
fScaledBitmap.reset();
|
||||
return false;
|
||||
@ -286,13 +283,12 @@ bool SkBitmapProcState::possiblyScaleImage() {
|
||||
const SkMipMap* mip = NULL;
|
||||
|
||||
SkASSERT(NULL == fScaledCacheID);
|
||||
fScaledCacheID = SkScaledImageCache::FindAndLockMip(fOrigBitmap, &mip);
|
||||
fScaledCacheID = SkMipMapCache::FindAndLock(fOrigBitmap, &mip);
|
||||
if (!fScaledCacheID) {
|
||||
SkASSERT(NULL == mip);
|
||||
mip = SkMipMap::Build(fOrigBitmap);
|
||||
if (mip) {
|
||||
fScaledCacheID = SkScaledImageCache::AddAndLockMip(fOrigBitmap,
|
||||
mip);
|
||||
fScaledCacheID = SkMipMapCache::AddAndLock(fOrigBitmap, mip);
|
||||
SkASSERT(mip->getRefCnt() > 1);
|
||||
mip->unref(); // the cache took a ref
|
||||
SkASSERT(fScaledCacheID);
|
||||
@ -354,9 +350,7 @@ bool SkBitmapProcState::lockBaseBitmap() {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
fScaledCacheID = SkScaledImageCache::FindAndLock(fOrigBitmap,
|
||||
SK_Scalar1, SK_Scalar1,
|
||||
&fScaledBitmap);
|
||||
fScaledCacheID = SkBitmapCache::FindAndLock(fOrigBitmap, 1, 1, &fScaledBitmap);
|
||||
if (fScaledCacheID) {
|
||||
fScaledBitmap.lockPixels();
|
||||
if (!fScaledBitmap.getPixels()) {
|
||||
@ -376,9 +370,7 @@ bool SkBitmapProcState::lockBaseBitmap() {
|
||||
// TODO: if fScaled comes back at a different width/height than fOrig,
|
||||
// we need to update the matrix we are using to sample from this guy.
|
||||
|
||||
fScaledCacheID = SkScaledImageCache::AddAndLock(fOrigBitmap,
|
||||
SK_Scalar1, SK_Scalar1,
|
||||
fScaledBitmap);
|
||||
fScaledCacheID = SkBitmapCache::AddAndLock(fOrigBitmap, 1, 1, fScaledBitmap);
|
||||
if (!fScaledCacheID) {
|
||||
fScaledBitmap.reset();
|
||||
return false;
|
||||
|
@ -260,32 +260,10 @@ SkScaledImageCache::~SkScaledImageCache() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct GenWHKey : public SkScaledImageCache::Key {
|
||||
public:
|
||||
GenWHKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds)
|
||||
: fGenID(genID)
|
||||
, fScaleX(scaleX)
|
||||
, fScaleY(scaleY)
|
||||
, fBounds(bounds) {
|
||||
this->init(7 * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
uint32_t fGenID;
|
||||
SkScalar fScaleX;
|
||||
SkScalar fScaleY;
|
||||
SkIRect fBounds;
|
||||
};
|
||||
|
||||
SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(uint32_t genID,
|
||||
SkScalar scaleX,
|
||||
SkScalar scaleY,
|
||||
const SkIRect& bounds) {
|
||||
return this->findAndLock(GenWHKey(genID, scaleX, scaleY, bounds));
|
||||
}
|
||||
|
||||
/**
|
||||
This private method is the fully general record finder. All other
|
||||
record finders should call this function or the one above. */
|
||||
record finders should call this function or the one above.
|
||||
*/
|
||||
SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCache::Key& key) {
|
||||
#ifdef USE_HASH
|
||||
Rec* rec = fHash->find(key);
|
||||
@ -299,56 +277,18 @@ SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCach
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
This function finds the bounds of the bitmap *within its pixelRef*.
|
||||
If the bitmap lacks a pixelRef, it will return an empty rect, since
|
||||
that doesn't make sense. This may be a useful enough function that
|
||||
it should be somewhere else (in SkBitmap?). */
|
||||
static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
|
||||
if (!(bm.pixelRef())) {
|
||||
return SkIRect::MakeEmpty();
|
||||
}
|
||||
SkIPoint origin = bm.pixelRefOrigin();
|
||||
return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
|
||||
}
|
||||
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::findAndLock(uint32_t genID,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
SkBitmap* bitmap) {
|
||||
Rec* rec = this->findAndLock(genID, SK_Scalar1, SK_Scalar1,
|
||||
SkIRect::MakeWH(width, height));
|
||||
SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const Key& key, SkBitmap* result) {
|
||||
Rec* rec = this->findAndLock(key);
|
||||
if (rec) {
|
||||
SkASSERT(NULL == rec->fMip);
|
||||
SkASSERT(rec->fBitmap.pixelRef());
|
||||
*bitmap = rec->fBitmap;
|
||||
*result = rec->fBitmap;
|
||||
}
|
||||
return rec_to_id(rec);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig,
|
||||
SkScalar scaleX,
|
||||
SkScalar scaleY,
|
||||
SkBitmap* scaled) {
|
||||
if (0 == scaleX || 0 == scaleY) {
|
||||
// degenerate, and the key we use for mipmaps
|
||||
return NULL;
|
||||
}
|
||||
Rec* rec = this->findAndLock(orig.getGenerationID(), scaleX,
|
||||
scaleY, get_bounds_from_bitmap(orig));
|
||||
if (rec) {
|
||||
SkASSERT(NULL == rec->fMip);
|
||||
SkASSERT(rec->fBitmap.pixelRef());
|
||||
*scaled = rec->fBitmap;
|
||||
}
|
||||
return rec_to_id(rec);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig,
|
||||
SkMipMap const ** mip) {
|
||||
Rec* rec = this->findAndLock(orig.getGenerationID(), 0, 0,
|
||||
get_bounds_from_bitmap(orig));
|
||||
SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const Key& key, const SkMipMap** mip) {
|
||||
Rec* rec = this->findAndLock(key);
|
||||
if (rec) {
|
||||
SkASSERT(rec->fMip);
|
||||
SkASSERT(NULL == rec->fBitmap.pixelRef());
|
||||
@ -385,39 +325,12 @@ SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec*
|
||||
return rec_to_id(rec);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
const SkBitmap& bitmap) {
|
||||
GenWHKey key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
|
||||
Rec* rec = SkNEW_ARGS(Rec, (key, bitmap));
|
||||
return this->addAndLock(rec);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
|
||||
SkScalar scaleX,
|
||||
SkScalar scaleY,
|
||||
const SkBitmap& scaled) {
|
||||
if (0 == scaleX || 0 == scaleY) {
|
||||
// degenerate, and the key we use for mipmaps
|
||||
return NULL;
|
||||
}
|
||||
SkIRect bounds = get_bounds_from_bitmap(orig);
|
||||
if (bounds.isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
GenWHKey key(orig.getGenerationID(), scaleX, scaleY, bounds);
|
||||
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const Key& key, const SkBitmap& scaled) {
|
||||
Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
|
||||
return this->addAndLock(rec);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig,
|
||||
const SkMipMap* mip) {
|
||||
SkIRect bounds = get_bounds_from_bitmap(orig);
|
||||
if (bounds.isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
GenWHKey key(orig.getGenerationID(), 0, 0, bounds);
|
||||
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const Key& key, const SkMipMap* mip) {
|
||||
Rec* rec = SkNEW_ARGS(Rec, (key, mip));
|
||||
return this->addAndLock(rec);
|
||||
}
|
||||
@ -663,52 +576,24 @@ static SkScaledImageCache* get_cache() {
|
||||
return gScaledImageCache;
|
||||
}
|
||||
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(
|
||||
uint32_t pixelGenerationID,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
SkBitmap* scaled) {
|
||||
SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const Key& key, SkBitmap* result) {
|
||||
SkAutoMutexAcquire am(gMutex);
|
||||
return get_cache()->findAndLock(pixelGenerationID, width, height, scaled);
|
||||
return get_cache()->findAndLock(key, result);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(
|
||||
uint32_t pixelGenerationID,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
const SkBitmap& scaled) {
|
||||
SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const Key& key, SkMipMap const ** mip) {
|
||||
SkAutoMutexAcquire am(gMutex);
|
||||
return get_cache()->addAndLock(pixelGenerationID, width, height, scaled);
|
||||
return get_cache()->findAndLock(key, mip);
|
||||
}
|
||||
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig,
|
||||
SkScalar scaleX,
|
||||
SkScalar scaleY,
|
||||
SkBitmap* scaled) {
|
||||
SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const Key& key, const SkBitmap& scaled) {
|
||||
SkAutoMutexAcquire am(gMutex);
|
||||
return get_cache()->findAndLock(orig, scaleX, scaleY, scaled);
|
||||
return get_cache()->addAndLock(key, scaled);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig,
|
||||
SkMipMap const ** mip) {
|
||||
SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const Key& key, const SkMipMap* mip) {
|
||||
SkAutoMutexAcquire am(gMutex);
|
||||
return get_cache()->findAndLockMip(orig, mip);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const SkBitmap& orig,
|
||||
SkScalar scaleX,
|
||||
SkScalar scaleY,
|
||||
const SkBitmap& scaled) {
|
||||
SkAutoMutexAcquire am(gMutex);
|
||||
return get_cache()->addAndLock(orig, scaleX, scaleY, scaled);
|
||||
}
|
||||
|
||||
SkScaledImageCache::ID* SkScaledImageCache::AddAndLockMip(const SkBitmap& orig,
|
||||
const SkMipMap* mip) {
|
||||
SkAutoMutexAcquire am(gMutex);
|
||||
return get_cache()->addAndLockMip(orig, mip);
|
||||
return get_cache()->addAndLock(key, mip);
|
||||
}
|
||||
|
||||
void SkScaledImageCache::Unlock(SkScaledImageCache::ID* id) {
|
||||
|
@ -73,26 +73,12 @@ public:
|
||||
* instance of this cache.
|
||||
*/
|
||||
|
||||
static ID* FindAndLock(uint32_t pixelGenerationID,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
SkBitmap* returnedBitmap);
|
||||
|
||||
static ID* FindAndLock(const SkBitmap& original, SkScalar scaleX,
|
||||
SkScalar scaleY, SkBitmap* returnedBitmap);
|
||||
static ID* FindAndLockMip(const SkBitmap& original,
|
||||
SkMipMap const** returnedMipMap);
|
||||
|
||||
|
||||
static ID* AddAndLock(uint32_t pixelGenerationID,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
const SkBitmap& bitmap);
|
||||
|
||||
static ID* AddAndLock(const SkBitmap& original, SkScalar scaleX,
|
||||
SkScalar scaleY, const SkBitmap& bitmap);
|
||||
static ID* AddAndLockMip(const SkBitmap& original, const SkMipMap* mipMap);
|
||||
|
||||
static ID* FindAndLock(const Key&, SkBitmap* result);
|
||||
static ID* AddAndLock(const Key&, const SkBitmap& result);
|
||||
|
||||
static ID* FindAndLock(const Key&, const SkMipMap** result);
|
||||
static ID* AddAndLock(const Key&, const SkMipMap* result);
|
||||
|
||||
static void Unlock(ID*);
|
||||
|
||||
static size_t GetTotalBytesUsed();
|
||||
@ -126,39 +112,17 @@ public:
|
||||
* that pushes the total bytesUsed over the limit. Note: The limit can be
|
||||
* changed at runtime with setTotalByteLimit.
|
||||
*/
|
||||
SkScaledImageCache(size_t byteLimit);
|
||||
|
||||
explicit SkScaledImageCache(size_t byteLimit);
|
||||
~SkScaledImageCache();
|
||||
|
||||
/**
|
||||
* Search the cache for a matching bitmap (using generationID,
|
||||
* width, and height as a search key). If found, return it in
|
||||
* returnedBitmap, and return its ID pointer. Use the returned
|
||||
* ptr to unlock the cache when you are done using
|
||||
* returnedBitmap.
|
||||
* Search the cache for a matching key. If found, return its bitmap and return its ID pointer.
|
||||
* Use the returned ID to unlock the cache when you are done using outBitmap.
|
||||
*
|
||||
* If a match is not found, returnedBitmap will be unmodifed, and
|
||||
* NULL will be returned.
|
||||
*
|
||||
* This is used if there is no scaling or subsetting, for example
|
||||
* by SkLazyPixelRef.
|
||||
* If a match is not found, outBitmap will be unmodifed, and NULL will be returned.
|
||||
*/
|
||||
ID* findAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height,
|
||||
SkBitmap* returnedBitmap);
|
||||
|
||||
/**
|
||||
* Search the cache for a scaled version of original. If found,
|
||||
* return it in returnedBitmap, and return its ID pointer. Use
|
||||
* the returned ptr to unlock the cache when you are done using
|
||||
* returnedBitmap.
|
||||
*
|
||||
* If a match is not found, returnedBitmap will be unmodifed, and
|
||||
* NULL will be returned.
|
||||
*/
|
||||
ID* findAndLock(const SkBitmap& original, SkScalar scaleX,
|
||||
SkScalar scaleY, SkBitmap* returnedBitmap);
|
||||
ID* findAndLockMip(const SkBitmap& original,
|
||||
SkMipMap const** returnedMipMap);
|
||||
ID* findAndLock(const Key& key, SkBitmap* outBitmap);
|
||||
ID* findAndLock(const Key& key, const SkMipMap** returnedMipMap);
|
||||
|
||||
/**
|
||||
* To add a new bitmap (or mipMap) to the cache, call
|
||||
@ -168,11 +132,8 @@ public:
|
||||
* Use (generationID, width, and height) or (original, scaleX,
|
||||
* scaleY) or (original) as a search key
|
||||
*/
|
||||
ID* addAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height,
|
||||
const SkBitmap& bitmap);
|
||||
ID* addAndLock(const SkBitmap& original, SkScalar scaleX,
|
||||
SkScalar scaleY, const SkBitmap& bitmap);
|
||||
ID* addAndLockMip(const SkBitmap& original, const SkMipMap* mipMap);
|
||||
ID* addAndLock(const Key&, const SkBitmap& bitmap);
|
||||
ID* addAndLock(const Key&, const SkMipMap* mipMap);
|
||||
|
||||
/**
|
||||
* Given a non-null ID ptr returned by either findAndLock or addAndLock,
|
||||
@ -224,8 +185,6 @@ private:
|
||||
size_t fSingleAllocationByteLimit;
|
||||
int fCount;
|
||||
|
||||
Rec* findAndLock(uint32_t generationID, SkScalar sx, SkScalar sy,
|
||||
const SkIRect& bounds);
|
||||
Rec* findAndLock(const Key& key);
|
||||
ID* addAndLock(Rec* rec);
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "SkCachingPixelRef.h"
|
||||
#include "SkScaledImageCache.h"
|
||||
#include "SkBitmapCache.h"
|
||||
|
||||
bool SkCachingPixelRef::Install(SkImageGenerator* generator,
|
||||
SkBitmap* dst) {
|
||||
@ -48,10 +48,8 @@ bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) {
|
||||
const SkImageInfo& info = this->info();
|
||||
SkBitmap bitmap;
|
||||
SkASSERT(NULL == fScaledCacheId);
|
||||
fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(),
|
||||
info.fWidth,
|
||||
info.fHeight,
|
||||
&bitmap);
|
||||
fScaledCacheId = SkBitmapCache::FindAndLock(this->getGenerationID(), info.fWidth, info.fHeight,
|
||||
&bitmap);
|
||||
if (NULL == fScaledCacheId) {
|
||||
// Cache has been purged, must re-decode.
|
||||
if (!bitmap.allocPixels(info, fRowBytes)) {
|
||||
@ -63,10 +61,8 @@ bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) {
|
||||
fErrorInDecoding = true;
|
||||
return false;
|
||||
}
|
||||
fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(),
|
||||
info.fWidth,
|
||||
info.fHeight,
|
||||
bitmap);
|
||||
fScaledCacheId = SkBitmapCache::AddAndLock(this->getGenerationID(),
|
||||
info.fWidth, info.fHeight, bitmap);
|
||||
SkASSERT(fScaledCacheId != NULL);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,18 @@
|
||||
#include "SkScaledImageCache.h"
|
||||
#include "Test.h"
|
||||
|
||||
namespace {
|
||||
static void* gGlobalAddress;
|
||||
struct TestingKey : public SkScaledImageCache::Key {
|
||||
void* fPtr;
|
||||
intptr_t fValue;
|
||||
|
||||
TestingKey(intptr_t value) : fPtr(&gGlobalAddress), fValue(value) {
|
||||
this->init(sizeof(fPtr) + sizeof(fValue));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void make_bm(SkBitmap* bm, int w, int h) {
|
||||
bm->allocN32Pixels(w, h);
|
||||
}
|
||||
@ -22,24 +34,23 @@ static void test_cache(skiatest::Reporter* reporter, SkScaledImageCache& cache,
|
||||
|
||||
SkBitmap bm[COUNT];
|
||||
|
||||
const SkScalar scale = 2;
|
||||
for (int i = 0; i < COUNT; ++i) {
|
||||
make_bm(&bm[i], DIM, DIM);
|
||||
}
|
||||
|
||||
for (int i = 0; i < COUNT; ++i) {
|
||||
TestingKey key(bm[i].getGenerationID());
|
||||
SkBitmap tmp;
|
||||
|
||||
SkScaledImageCache::ID* id = cache.findAndLock(bm[i], scale, scale, &tmp);
|
||||
SkScaledImageCache::ID* id = cache.findAndLock(key, &tmp);
|
||||
REPORTER_ASSERT(reporter, NULL == id);
|
||||
|
||||
make_bm(&tmp, DIM, DIM);
|
||||
id = cache.addAndLock(bm[i], scale, scale, tmp);
|
||||
id = cache.addAndLock(key, tmp);
|
||||
REPORTER_ASSERT(reporter, NULL != id);
|
||||
|
||||
SkBitmap tmp2;
|
||||
SkScaledImageCache::ID* id2 = cache.findAndLock(bm[i], scale, scale,
|
||||
&tmp2);
|
||||
SkScaledImageCache::ID* id2 = cache.findAndLock(key, &tmp2);
|
||||
REPORTER_ASSERT(reporter, id == id2);
|
||||
REPORTER_ASSERT(reporter, tmp.pixelRef() == tmp2.pixelRef());
|
||||
REPORTER_ASSERT(reporter, tmp.width() == tmp2.width());
|
||||
@ -51,15 +62,12 @@ static void test_cache(skiatest::Reporter* reporter, SkScaledImageCache& cache,
|
||||
|
||||
if (testPurge) {
|
||||
// stress test, should trigger purges
|
||||
float incScale = 2;
|
||||
for (size_t i = 0; i < COUNT * 100; ++i) {
|
||||
incScale += 1;
|
||||
|
||||
TestingKey key(i);
|
||||
SkBitmap tmp;
|
||||
make_bm(&tmp, DIM, DIM);
|
||||
|
||||
SkScaledImageCache::ID* id = cache.addAndLock(bm[0], incScale,
|
||||
incScale, tmp);
|
||||
SkScaledImageCache::ID* id = cache.addAndLock(key, tmp);
|
||||
REPORTER_ASSERT(reporter, NULL != id);
|
||||
cache.unlock(id);
|
||||
}
|
||||
@ -67,8 +75,9 @@ static void test_cache(skiatest::Reporter* reporter, SkScaledImageCache& cache,
|
||||
|
||||
// test the originals after all that purging
|
||||
for (int i = 0; i < COUNT; ++i) {
|
||||
TestingKey key(bm[i].getGenerationID());
|
||||
SkBitmap tmp;
|
||||
id = cache.findAndLock(bm[i], scale, scale, &tmp);
|
||||
id = cache.findAndLock(key, &tmp);
|
||||
if (id) {
|
||||
cache.unlock(id);
|
||||
}
|
||||
@ -118,15 +127,17 @@ DEF_TEST(ImageCache_doubleAdd, r) {
|
||||
SkBitmap scaled2;
|
||||
scaled2.allocN32Pixels(20, 20);
|
||||
|
||||
SkScaledImageCache::ID* id1 = cache.addAndLock(original, 0.5f, 0.5f, scaled1);
|
||||
SkScaledImageCache::ID* id2 = cache.addAndLock(original, 0.5f, 0.5f, scaled2);
|
||||
TestingKey key(original.getGenerationID());
|
||||
|
||||
SkScaledImageCache::ID* id1 = cache.addAndLock(key, scaled1);
|
||||
SkScaledImageCache::ID* id2 = cache.addAndLock(key, scaled2);
|
||||
// We don't really care if id1 == id2 as long as unlocking both works.
|
||||
cache.unlock(id1);
|
||||
cache.unlock(id2);
|
||||
|
||||
SkBitmap tmp;
|
||||
// Lookup should return the value that was added last.
|
||||
SkScaledImageCache::ID* id = cache.findAndLock(original, 0.5f, 0.5f, &tmp);
|
||||
SkScaledImageCache::ID* id = cache.findAndLock(key, &tmp);
|
||||
REPORTER_ASSERT(r, NULL != id);
|
||||
REPORTER_ASSERT(r, tmp.getGenerationID() == scaled2.getGenerationID());
|
||||
cache.unlock(id);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "Test.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkScaledImageCache.h"
|
||||
#include "SkBitmapCache.h"
|
||||
|
||||
static const int kCanvasSize = 1;
|
||||
static const int kBitmapSize = 16;
|
||||
@ -17,7 +17,7 @@ static bool is_in_scaled_image_cache(const SkBitmap& orig,
|
||||
SkScalar xScale,
|
||||
SkScalar yScale) {
|
||||
SkBitmap scaled;
|
||||
SkScaledImageCache::ID* id = SkScaledImageCache::FindAndLock(
|
||||
SkScaledImageCache::ID* id = SkBitmapCache::FindAndLock(
|
||||
orig, SkScalarInvert(xScale), SkScalarInvert(yScale), &scaled);
|
||||
if (id) {
|
||||
SkScaledImageCache::Unlock(id);
|
||||
|
Loading…
Reference in New Issue
Block a user