summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/src/core/SkScaledImageCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/src/core/SkScaledImageCache.cpp')
-rw-r--r--chromium/third_party/skia/src/core/SkScaledImageCache.cpp106
1 files changed, 50 insertions, 56 deletions
diff --git a/chromium/third_party/skia/src/core/SkScaledImageCache.cpp b/chromium/third_party/skia/src/core/SkScaledImageCache.cpp
index 2529b5f8ec6..a030248197a 100644
--- a/chromium/third_party/skia/src/core/SkScaledImageCache.cpp
+++ b/chromium/third_party/skia/src/core/SkScaledImageCache.cpp
@@ -7,7 +7,6 @@
#include "SkScaledImageCache.h"
#include "SkMipMap.h"
-#include "SkOnce.h"
#include "SkPixelRef.h"
#include "SkRect.h"
@@ -116,6 +115,9 @@ struct SkScaledImageCache::Rec {
SkSafeUnref(fMip);
}
+ static const Key& GetKey(const Rec& rec) { return rec.fKey; }
+ static uint32_t Hash(const Key& key) { return key.fHash; }
+
size_t bytesUsed() const {
return fMip ? fMip->getSize() : fBitmap.getSize();
}
@@ -135,25 +137,9 @@ struct SkScaledImageCache::Rec {
#include "SkTDynamicHash.h"
-namespace { // can't use static functions w/ template parameters
-const SkScaledImageCache::Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
- return rec.fKey;
-}
-
-uint32_t hash_from_key(const SkScaledImageCache::Key& key) {
- return key.fHash;
-}
-
-bool eq_rec_key(const SkScaledImageCache::Rec& rec, const SkScaledImageCache::Key& key) {
- return rec.fKey == key;
-}
-}
+class SkScaledImageCache::Hash :
+ public SkTDynamicHash<SkScaledImageCache::Rec, SkScaledImageCache::Key> {};
-class SkScaledImageCache::Hash : public SkTDynamicHash<SkScaledImageCache::Rec,
- SkScaledImageCache::Key,
- key_from_rec,
- hash_from_key,
- eq_rec_key> {};
///////////////////////////////////////////////////////////////////////////////
@@ -192,6 +178,7 @@ void SkScaledImageCache::init() {
class SkOneShotDiscardablePixelRef : public SkPixelRef {
public:
+ SK_DECLARE_INST_COUNT(SkOneShotDiscardablePixelRef)
// Ownership of the discardablememory is transfered to the pixelref
SkOneShotDiscardablePixelRef(const SkImageInfo&, SkDiscardableMemory*, size_t rowBytes);
~SkOneShotDiscardablePixelRef();
@@ -199,13 +186,11 @@ public:
SK_DECLARE_UNFLATTENABLE_OBJECT()
protected:
- virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE;
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
virtual void onUnlockPixels() SK_OVERRIDE;
virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
private:
- SkImageInfo fInfo; // remove when SkPixelRef gets this in baseclass
-
SkDiscardableMemory* fDM;
size_t fRB;
bool fFirstTime;
@@ -220,8 +205,6 @@ SkOneShotDiscardablePixelRef::SkOneShotDiscardablePixelRef(const SkImageInfo& in
, fDM(dm)
, fRB(rowBytes)
{
- fInfo = info; // remove this redundant field when SkPixelRef has info
-
SkASSERT(dm->data());
fFirstTime = true;
}
@@ -230,26 +213,31 @@ SkOneShotDiscardablePixelRef::~SkOneShotDiscardablePixelRef() {
SkDELETE(fDM);
}
-void* SkOneShotDiscardablePixelRef::onLockPixels(SkColorTable** ctable) {
+bool SkOneShotDiscardablePixelRef::onNewLockPixels(LockRec* rec) {
if (fFirstTime) {
// we're already locked
SkASSERT(fDM->data());
fFirstTime = false;
- return fDM->data();
+ goto SUCCESS;
}
// A previous call to onUnlock may have deleted our DM, so check for that
if (NULL == fDM) {
- return NULL;
+ return false;
}
if (!fDM->lock()) {
// since it failed, we delete it now, to free-up the resource
delete fDM;
fDM = NULL;
- return NULL;
+ return false;
}
- return fDM->data();
+
+SUCCESS:
+ rec->fPixels = fDM->data();
+ rec->fColorTable = NULL;
+ rec->fRowBytes = fRB;
+ return true;
}
void SkOneShotDiscardablePixelRef::onUnlockPixels() {
@@ -258,7 +246,7 @@ void SkOneShotDiscardablePixelRef::onUnlockPixels() {
}
size_t SkOneShotDiscardablePixelRef::getAllocatedSizeInBytes() const {
- return fInfo.fHeight * fRB;
+ return this->info().getSafeSize(fRB);
}
class SkScaledImageCacheDiscardableAllocator : public SkBitmap::Allocator {
@@ -278,7 +266,8 @@ private:
bool SkScaledImageCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap,
SkColorTable* ctable) {
size_t size = bitmap->getSize();
- if (0 == size) {
+ uint64_t size64 = bitmap->computeSize64();
+ if (0 == size || size64 > (uint64_t)size) {
return false;
}
@@ -287,18 +276,12 @@ bool SkScaledImageCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap,
return false;
}
- // can relax when we have bitmap::asImageInfo
- if (SkBitmap::kARGB_8888_Config != bitmap->config()) {
+ // can we relax this?
+ if (kN32_SkColorType != bitmap->colorType()) {
return false;
}
- SkImageInfo info = {
- bitmap->width(),
- bitmap->height(),
- kPMColor_SkColorType,
- bitmap->alphaType()
- };
-
+ SkImageInfo info = bitmap->info();
bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef,
(info, dm, bitmap->rowBytes())))->unref();
bitmap->lockPixels();
@@ -368,10 +351,8 @@ static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
if (!(bm.pixelRef())) {
return SkIRect::MakeEmpty();
}
- size_t x, y;
- SkTDivMod(bm.pixelRefOffset(), bm.rowBytes(), &y, &x);
- x >>= bm.shiftPerPixel();
- return SkIRect::MakeXYWH(x, y, bm.width(), bm.height());
+ SkIPoint origin = bm.pixelRefOrigin();
+ return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
}
@@ -428,7 +409,11 @@ SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec*
SkASSERT(rec);
// See if we already have this key (racy inserts, etc.)
Rec* existing = this->findAndLock(rec->fKey);
- if (existing != NULL) {
+ if (NULL != existing) {
+ // Since we already have a matching entry, just delete the new one and return.
+ // Call sites cannot assume the passed in object will live past this call.
+ existing->fBitmap = rec->fBitmap;
+ SkDELETE(rec);
return rec_to_id(existing);
}
@@ -685,21 +670,30 @@ void SkScaledImageCache::dump() const {
#include "SkThread.h"
SK_DECLARE_STATIC_MUTEX(gMutex);
-
-static void create_cache(SkScaledImageCache** cache) {
-#ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE
- *cache = SkNEW_ARGS(SkScaledImageCache, (SkDiscardableMemory::Create));
-#else
- *cache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT));
+static SkScaledImageCache* gScaledImageCache = NULL;
+static void cleanup_gScaledImageCache() {
+ // We'll clean this up in our own tests, but disable for clients.
+ // Chrome seems to have funky multi-process things going on in unit tests that
+ // makes this unsafe to delete when the main process atexit()s.
+ // SkLazyPtr does the same sort of thing.
+#if SK_DEVELOPER
+ SkDELETE(gScaledImageCache);
#endif
}
+/** Must hold gMutex when calling. */
static SkScaledImageCache* get_cache() {
- static SkScaledImageCache* gCache(NULL);
- SK_DECLARE_STATIC_ONCE(create_cache_once);
- SkOnce(&create_cache_once, create_cache, &gCache);
- SkASSERT(NULL != gCache);
- return gCache;
+ // gMutex is always held when this is called, so we don't need to be fancy in here.
+ gMutex.assertHeld();
+ if (NULL == gScaledImageCache) {
+#ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE
+ gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SkDiscardableMemory::Create));
+#else
+ gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT));
+#endif
+ atexit(cleanup_gScaledImageCache);
+ }
+ return gScaledImageCache;
}