diff options
Diffstat (limited to 'chromium/third_party/skia/src/core/SkScaledImageCache.cpp')
-rw-r--r-- | chromium/third_party/skia/src/core/SkScaledImageCache.cpp | 106 |
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; } |