12c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com/* 22c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com * Copyright 2013 Google Inc. 32c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com * 42c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com * Use of this source code is governed by a BSD-style license that can be 52c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com * found in the LICENSE file. 62c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com */ 72c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 8cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org#include "SkDiscardableMemory.h" 92c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com#include "SkDiscardableMemoryPool.h" 10fa37a21be54444189187584ce09c9a431abf1911halcanary#include "SkImageGenerator.h" 1178358bf624c7e7c09ffccf638c50870808d884d6mtklein#include "SkLazyPtr.h" 12cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org#include "SkTInternalLList.h" 13cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org#include "SkThread.h" 142c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 152c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com// Note: 162c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com// A PoolDiscardableMemory is memory that is counted in a pool. 172c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com// A DiscardableMemoryPool is a pool of PoolDiscardableMemorys. 182c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 19cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgnamespace { 20cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 21cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgclass PoolDiscardableMemory; 22cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 232c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com/** 24cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * This non-global pool can be used for unit tests to verify that the 25cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * pool works. 262c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com */ 27cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgclass DiscardableMemoryPool : public SkDiscardableMemoryPool { 282c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.compublic: 29cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** 30cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * Without mutex, will be not be thread safe. 31cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org */ 32cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org DiscardableMemoryPool(size_t budget, SkBaseMutex* mutex = NULL); 33cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual ~DiscardableMemoryPool(); 34cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 35cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual SkDiscardableMemory* create(size_t bytes) SK_OVERRIDE; 36cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 37cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual size_t getRAMUsed() SK_OVERRIDE; 38cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual void setRAMBudget(size_t budget) SK_OVERRIDE; 39cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual size_t getRAMBudget() SK_OVERRIDE { return fBudget; } 40cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 41cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** purges all unlocked DMs */ 42cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual void dumpPool() SK_OVERRIDE; 43cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 44cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS // Defined in SkDiscardableMemoryPool.h 45cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual int getCacheHits() SK_OVERRIDE { return fCacheHits; } 46cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual int getCacheMisses() SK_OVERRIDE { return fCacheMisses; } 47cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual void resetCacheHitsAndMisses() SK_OVERRIDE { 48cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org fCacheHits = fCacheMisses = 0; 49cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org } 50cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org int fCacheHits; 51cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org int fCacheMisses; 52cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 53cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 54cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgprivate: 55cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SkBaseMutex* fMutex; 56cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org size_t fBudget; 57cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org size_t fUsed; 58cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SkTInternalLList<PoolDiscardableMemory> fList; 59cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 60cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** Function called to free memory if needed */ 61cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void dumpDownTo(size_t budget); 62cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** called by DiscardableMemoryPool upon destruction */ 63cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void free(PoolDiscardableMemory* dm); 64cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** called by DiscardableMemoryPool::lock() */ 65cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org bool lock(PoolDiscardableMemory* dm); 66cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** called by DiscardableMemoryPool::unlock() */ 67cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void unlock(PoolDiscardableMemory* dm); 68cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 69cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org friend class PoolDiscardableMemory; 70cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 71cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org typedef SkDiscardableMemory::Factory INHERITED; 72cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org}; 73cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 74cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org/** 75cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * A PoolDiscardableMemory is a SkDiscardableMemory that relies on 76cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * a DiscardableMemoryPool object to manage the memory. 77cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org */ 78cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgclass PoolDiscardableMemory : public SkDiscardableMemory { 79cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgpublic: 80cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory(DiscardableMemoryPool* pool, 812c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com void* pointer, size_t bytes); 82cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual ~PoolDiscardableMemory(); 832c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com virtual bool lock() SK_OVERRIDE; 842c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com virtual void* data() SK_OVERRIDE; 852c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com virtual void unlock() SK_OVERRIDE; 86cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org friend class DiscardableMemoryPool; 872c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.comprivate: 88cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SK_DECLARE_INTERNAL_LLIST_INTERFACE(PoolDiscardableMemory); 89cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org DiscardableMemoryPool* const fPool; 90cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org bool fLocked; 91cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void* fPointer; 92cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org const size_t fBytes; 932c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com}; 942c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 95cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgPoolDiscardableMemory::PoolDiscardableMemory(DiscardableMemoryPool* pool, 96cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void* pointer, 97cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org size_t bytes) 982c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com : fPool(pool) 992c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fLocked(true) 1002c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fPointer(pointer) 1012c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fBytes(bytes) { 1022c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fPool != NULL); 1032c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fPointer != NULL); 1042c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fBytes > 0); 1052c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->ref(); 1062c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1072c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 108cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgPoolDiscardableMemory::~PoolDiscardableMemory() { 1091d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(!fLocked); // contract for SkDiscardableMemory 1102c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->free(this); 1112c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->unref(); 1122c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1132c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 114cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgbool PoolDiscardableMemory::lock() { 1151d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(!fLocked); // contract for SkDiscardableMemory 1162c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return fPool->lock(this); 1172c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1182c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 119cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid* PoolDiscardableMemory::data() { 1201d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(fLocked); // contract for SkDiscardableMemory 1211d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com return fPointer; 1222c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1232c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 124cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid PoolDiscardableMemory::unlock() { 1251d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(fLocked); // contract for SkDiscardableMemory 1262c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->unlock(this); 1272c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1282c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 1292c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com//////////////////////////////////////////////////////////////////////////////// 1302c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 131cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgDiscardableMemoryPool::DiscardableMemoryPool(size_t budget, 132cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SkBaseMutex* mutex) 1332c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com : fMutex(mutex) 1342c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fBudget(budget) 1352c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fUsed(0) { 136cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 1372c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fCacheHits = 0; 1382c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fCacheMisses = 0; 139cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 1402c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 141cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgDiscardableMemoryPool::~DiscardableMemoryPool() { 142cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org // PoolDiscardableMemory objects that belong to this pool are 1432c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // always deleted before deleting this pool since each one has a 1442c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // ref to the pool. 1452c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fList.isEmpty()); 1462c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1472c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 148cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::dumpDownTo(size_t budget) { 1499b7906672eb6794497d560761aa8bab824a13a90halcanary if (fMutex != NULL) { 1509b7906672eb6794497d560761aa8bab824a13a90halcanary fMutex->assertHeld(); 1519b7906672eb6794497d560761aa8bab824a13a90halcanary } 1522c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (fUsed <= budget) { 1532c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return; 1542c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 155cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org typedef SkTInternalLList<PoolDiscardableMemory>::Iter Iter; 1562c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com Iter iter; 157cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory* cur = iter.init(fList, Iter::kTail_IterStart); 15849f085dddff10473b6ebf832a974288300224e60bsalomon while ((fUsed > budget) && (cur)) { 1592c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (!cur->fLocked) { 160cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory* dm = cur; 1612c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(dm->fPointer != NULL); 1622c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com sk_free(dm->fPointer); 1632c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fPointer = NULL; 1642c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fUsed >= dm->fBytes); 1652c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fUsed -= dm->fBytes; 1662c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com cur = iter.prev(); 1672c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // Purged DMs are taken out of the list. This saves times 1682c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // looking them up. Purged DMs are NOT deleted. 1692c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.remove(dm); 1702c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } else { 1712c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com cur = iter.prev(); 1722c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 1732c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 1742c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1752c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 176cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgSkDiscardableMemory* DiscardableMemoryPool::create(size_t bytes) { 1772c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com void* addr = sk_malloc_flags(bytes, 0); 1782c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (NULL == addr) { 1792c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return NULL; 1802c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 181cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory* dm = SkNEW_ARGS(PoolDiscardableMemory, 1822c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com (this, addr, bytes)); 1832c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 1842c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.addToHead(dm); 1852c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fUsed += bytes; 1862c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(fBudget); 1872c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return dm; 1882c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1892c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 190cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::free(PoolDiscardableMemory* dm) { 1912c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // This is called by dm's destructor. 1922c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (dm->fPointer != NULL) { 1932c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 1942c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com sk_free(dm->fPointer); 1952c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fPointer = NULL; 1962c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fUsed >= dm->fBytes); 1972c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fUsed -= dm->fBytes; 1982c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.remove(dm); 1992c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } else { 2002c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(!fList.isInList(dm)); 2012c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 2022c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2032c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 204cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgbool DiscardableMemoryPool::lock(PoolDiscardableMemory* dm) { 2052c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(dm != NULL); 2062c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (NULL == dm->fPointer) { 207cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 2082c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2092c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com ++fCacheMisses; 210cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 2112c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return false; 2122c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 2132c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2142c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (NULL == dm->fPointer) { 2152c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // May have been purged while waiting for lock. 216cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 2172c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com ++fCacheMisses; 218cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 2192c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return false; 2202c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 2212c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fLocked = true; 2222c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.remove(dm); 2232c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.addToHead(dm); 224cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 2252c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com ++fCacheHits; 226cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 2272c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return true; 2282c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2292c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 230cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::unlock(PoolDiscardableMemory* dm) { 2312c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(dm != NULL); 2322c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2332c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fLocked = false; 2342c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(fBudget); 2352c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2362c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 237cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgsize_t DiscardableMemoryPool::getRAMUsed() { 2382c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return fUsed; 2392c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 240cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::setRAMBudget(size_t budget) { 2412c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2422c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fBudget = budget; 2432c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(fBudget); 2442c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 245cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::dumpPool() { 2462c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2472c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(0); 2482c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2492c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 2502c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com//////////////////////////////////////////////////////////////////////////////// 2512c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.comSK_DECLARE_STATIC_MUTEX(gMutex); 25278358bf624c7e7c09ffccf638c50870808d884d6mtkleinSkDiscardableMemoryPool* create_global_pool() { 25378358bf624c7e7c09ffccf638c50870808d884d6mtklein return SkDiscardableMemoryPool::Create(SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE, 25478358bf624c7e7c09ffccf638c50870808d884d6mtklein &gMutex); 2552c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 25678358bf624c7e7c09ffccf638c50870808d884d6mtklein 257cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org} // namespace 258cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 25978358bf624c7e7c09ffccf638c50870808d884d6mtkleinSkDiscardableMemoryPool* SkDiscardableMemoryPool::Create(size_t size, SkBaseMutex* mutex) { 260cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org return SkNEW_ARGS(DiscardableMemoryPool, (size, mutex)); 261cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org} 262cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 2632c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.comSkDiscardableMemoryPool* SkGetGlobalDiscardableMemoryPool() { 26478358bf624c7e7c09ffccf638c50870808d884d6mtklein SK_DECLARE_STATIC_LAZY_PTR(SkDiscardableMemoryPool, global, create_global_pool); 26578358bf624c7e7c09ffccf638c50870808d884d6mtklein return global.get(); 2662c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2672c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 2682c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com//////////////////////////////////////////////////////////////////////////////// 269