michael@0: michael@0: /* michael@0: * Copyright 2011 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: #include "SkImageRef_GlobalPool.h" michael@0: #include "SkImageRefPool.h" michael@0: #include "SkThread.h" michael@0: michael@0: SK_DECLARE_STATIC_MUTEX(gGlobalPoolMutex); michael@0: michael@0: /* michael@0: * This returns the lazily-allocated global pool. It must be called michael@0: * from inside the guard mutex, so we safely only ever allocate 1. michael@0: */ michael@0: static SkImageRefPool* GetGlobalPool() { michael@0: static SkImageRefPool* gPool; michael@0: if (NULL == gPool) { michael@0: gPool = SkNEW(SkImageRefPool); michael@0: // call sk_atexit(...) when we have that, to free the global pool michael@0: } michael@0: return gPool; michael@0: } michael@0: michael@0: SkImageRef_GlobalPool::SkImageRef_GlobalPool(const SkImageInfo& info, michael@0: SkStreamRewindable* stream, michael@0: int sampleSize) michael@0: : SkImageRef(info, stream, sampleSize, &gGlobalPoolMutex) { michael@0: SkASSERT(&gGlobalPoolMutex == this->mutex()); michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: GetGlobalPool()->addToHead(this); michael@0: } michael@0: michael@0: SkImageRef_GlobalPool::~SkImageRef_GlobalPool() { michael@0: SkASSERT(&gGlobalPoolMutex == this->mutex()); michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: GetGlobalPool()->detach(this); michael@0: } michael@0: michael@0: /* By design, onUnlockPixels() already is inside the mutex-lock, michael@0: * and it is the (indirect) caller of onDecode(), therefore we can assume michael@0: * that we also are already inside the mutex. Hence, we can reference michael@0: * the global-pool directly. michael@0: */ michael@0: bool SkImageRef_GlobalPool::onDecode(SkImageDecoder* codec, SkStreamRewindable* stream, michael@0: SkBitmap* bitmap, SkBitmap::Config config, michael@0: SkImageDecoder::Mode mode) { michael@0: if (!this->INHERITED::onDecode(codec, stream, bitmap, config, mode)) { michael@0: return false; michael@0: } michael@0: if (mode == SkImageDecoder::kDecodePixels_Mode) { michael@0: // no need to grab the mutex here, it has already been acquired. michael@0: GetGlobalPool()->justAddedPixels(this); michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: void SkImageRef_GlobalPool::onUnlockPixels() { michael@0: this->INHERITED::onUnlockPixels(); michael@0: michael@0: // by design, onUnlockPixels() already is inside the mutex-lock michael@0: GetGlobalPool()->canLosePixels(this); michael@0: } michael@0: michael@0: SkImageRef_GlobalPool::SkImageRef_GlobalPool(SkReadBuffer& buffer) michael@0: : INHERITED(buffer, &gGlobalPoolMutex) { michael@0: SkASSERT(&gGlobalPoolMutex == this->mutex()); michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: GetGlobalPool()->addToHead(this); michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: // global imagerefpool wrappers michael@0: michael@0: size_t SkImageRef_GlobalPool::GetRAMBudget() { michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: return GetGlobalPool()->getRAMBudget(); michael@0: } michael@0: michael@0: void SkImageRef_GlobalPool::SetRAMBudget(size_t size) { michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: GetGlobalPool()->setRAMBudget(size); michael@0: } michael@0: michael@0: size_t SkImageRef_GlobalPool::GetRAMUsed() { michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: return GetGlobalPool()->getRAMUsed(); michael@0: } michael@0: michael@0: void SkImageRef_GlobalPool::SetRAMUsed(size_t usage) { michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: GetGlobalPool()->setRAMUsed(usage); michael@0: } michael@0: michael@0: void SkImageRef_GlobalPool::DumpPool() { michael@0: SkAutoMutexAcquire ac(gGlobalPoolMutex); michael@0: GetGlobalPool()->dump(); michael@0: }