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" 1078358bf624c7e7c09ffccf638c50870808d884d6mtklein#include "SkLazyPtr.h" 11cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org#include "SkTInternalLList.h" 12cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org#include "SkThread.h" 132c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 142c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com// Note: 152c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com// A PoolDiscardableMemory is memory that is counted in a pool. 162c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com// A DiscardableMemoryPool is a pool of PoolDiscardableMemorys. 172c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 18cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgnamespace { 19cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 20cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgclass PoolDiscardableMemory; 21cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 222c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com/** 23cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * This non-global pool can be used for unit tests to verify that the 24cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * pool works. 252c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com */ 26cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgclass DiscardableMemoryPool : public SkDiscardableMemoryPool { 272c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.compublic: 28cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** 29cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * Without mutex, will be not be thread safe. 30cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org */ 31cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org DiscardableMemoryPool(size_t budget, SkBaseMutex* mutex = NULL); 32cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual ~DiscardableMemoryPool(); 33cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 34cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual SkDiscardableMemory* create(size_t bytes) SK_OVERRIDE; 35cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 36cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual size_t getRAMUsed() SK_OVERRIDE; 37cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual void setRAMBudget(size_t budget) SK_OVERRIDE; 38cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual size_t getRAMBudget() SK_OVERRIDE { return fBudget; } 39cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 40cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** purges all unlocked DMs */ 41cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual void dumpPool() SK_OVERRIDE; 42cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 43cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS // Defined in SkDiscardableMemoryPool.h 44cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual int getCacheHits() SK_OVERRIDE { return fCacheHits; } 45cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual int getCacheMisses() SK_OVERRIDE { return fCacheMisses; } 46cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual void resetCacheHitsAndMisses() SK_OVERRIDE { 47cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org fCacheHits = fCacheMisses = 0; 48cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org } 49cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org int fCacheHits; 50cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org int fCacheMisses; 51cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 52cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 53cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgprivate: 54cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SkBaseMutex* fMutex; 55cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org size_t fBudget; 56cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org size_t fUsed; 57cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SkTInternalLList<PoolDiscardableMemory> fList; 58cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 59cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** Function called to free memory if needed */ 60cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void dumpDownTo(size_t budget); 61cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** called by DiscardableMemoryPool upon destruction */ 62cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void free(PoolDiscardableMemory* dm); 63cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** called by DiscardableMemoryPool::lock() */ 64cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org bool lock(PoolDiscardableMemory* dm); 65cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org /** called by DiscardableMemoryPool::unlock() */ 66cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void unlock(PoolDiscardableMemory* dm); 67cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 68cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org friend class PoolDiscardableMemory; 69cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 70cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org typedef SkDiscardableMemory::Factory INHERITED; 71cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org}; 72cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 73cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org/** 74cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * A PoolDiscardableMemory is a SkDiscardableMemory that relies on 75cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org * a DiscardableMemoryPool object to manage the memory. 76cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org */ 77cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgclass PoolDiscardableMemory : public SkDiscardableMemory { 78cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgpublic: 79cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory(DiscardableMemoryPool* pool, 802c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com void* pointer, size_t bytes); 81cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org virtual ~PoolDiscardableMemory(); 822c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com virtual bool lock() SK_OVERRIDE; 832c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com virtual void* data() SK_OVERRIDE; 842c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com virtual void unlock() SK_OVERRIDE; 85cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org friend class DiscardableMemoryPool; 862c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.comprivate: 87cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SK_DECLARE_INTERNAL_LLIST_INTERFACE(PoolDiscardableMemory); 88cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org DiscardableMemoryPool* const fPool; 89cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org bool fLocked; 90cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void* fPointer; 91cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org const size_t fBytes; 922c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com}; 932c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 94cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgPoolDiscardableMemory::PoolDiscardableMemory(DiscardableMemoryPool* pool, 95cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org void* pointer, 96cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org size_t bytes) 972c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com : fPool(pool) 982c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fLocked(true) 992c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fPointer(pointer) 1002c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fBytes(bytes) { 1012c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fPool != NULL); 1022c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fPointer != NULL); 1032c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fBytes > 0); 1042c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->ref(); 1052c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1062c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 107cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgPoolDiscardableMemory::~PoolDiscardableMemory() { 1081d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(!fLocked); // contract for SkDiscardableMemory 1092c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->free(this); 1102c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->unref(); 1112c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1122c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 113cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgbool PoolDiscardableMemory::lock() { 1141d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(!fLocked); // contract for SkDiscardableMemory 1152c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return fPool->lock(this); 1162c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1172c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 118cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid* PoolDiscardableMemory::data() { 1191d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(fLocked); // contract for SkDiscardableMemory 1201d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com return fPointer; 1212c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1222c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 123cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid PoolDiscardableMemory::unlock() { 1241d0654f69d1d0c3bb565fba018a11c77f25bc55ereed@google.com SkASSERT(fLocked); // contract for SkDiscardableMemory 1252c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fPool->unlock(this); 1262c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1272c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 1282c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com//////////////////////////////////////////////////////////////////////////////// 1292c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 130cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgDiscardableMemoryPool::DiscardableMemoryPool(size_t budget, 131cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org SkBaseMutex* mutex) 1322c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com : fMutex(mutex) 1332c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fBudget(budget) 1342c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com , fUsed(0) { 135cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 1362c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fCacheHits = 0; 1372c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fCacheMisses = 0; 138cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 1392c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 140cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgDiscardableMemoryPool::~DiscardableMemoryPool() { 141cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org // PoolDiscardableMemory objects that belong to this pool are 1422c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // always deleted before deleting this pool since each one has a 1432c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // ref to the pool. 1442c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fList.isEmpty()); 1452c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1462c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 147cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::dumpDownTo(size_t budget) { 1489b7906672eb6794497d560761aa8bab824a13a90halcanary if (fMutex != NULL) { 1499b7906672eb6794497d560761aa8bab824a13a90halcanary fMutex->assertHeld(); 1509b7906672eb6794497d560761aa8bab824a13a90halcanary } 1512c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (fUsed <= budget) { 1522c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return; 1532c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 154cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org typedef SkTInternalLList<PoolDiscardableMemory>::Iter Iter; 1552c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com Iter iter; 156cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory* cur = iter.init(fList, Iter::kTail_IterStart); 1572c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com while ((fUsed > budget) && (NULL != cur)) { 1582c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (!cur->fLocked) { 159cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory* dm = cur; 1602c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(dm->fPointer != NULL); 1612c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com sk_free(dm->fPointer); 1622c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fPointer = NULL; 1632c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fUsed >= dm->fBytes); 1642c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fUsed -= dm->fBytes; 1652c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com cur = iter.prev(); 1662c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // Purged DMs are taken out of the list. This saves times 1672c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // looking them up. Purged DMs are NOT deleted. 1682c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.remove(dm); 1692c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } else { 1702c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com cur = iter.prev(); 1712c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 1722c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 1732c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1742c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 175cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgSkDiscardableMemory* DiscardableMemoryPool::create(size_t bytes) { 1762c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com void* addr = sk_malloc_flags(bytes, 0); 1772c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (NULL == addr) { 1782c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return NULL; 1792c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 180cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org PoolDiscardableMemory* dm = SkNEW_ARGS(PoolDiscardableMemory, 1812c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com (this, addr, bytes)); 1822c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 1832c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.addToHead(dm); 1842c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fUsed += bytes; 1852c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(fBudget); 1862c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return dm; 1872c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 1882c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 189cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::free(PoolDiscardableMemory* dm) { 1902c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // This is called by dm's destructor. 1912c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (dm->fPointer != NULL) { 1922c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 1932c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com sk_free(dm->fPointer); 1942c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fPointer = NULL; 1952c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(fUsed >= dm->fBytes); 1962c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fUsed -= dm->fBytes; 1972c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.remove(dm); 1982c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } else { 1992c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(!fList.isInList(dm)); 2002c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 2012c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2022c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 203cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgbool DiscardableMemoryPool::lock(PoolDiscardableMemory* dm) { 2042c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(dm != NULL); 2052c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (NULL == dm->fPointer) { 206cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 2072c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2082c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com ++fCacheMisses; 209cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 2102c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return false; 2112c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 2122c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2132c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com if (NULL == dm->fPointer) { 2142c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // May have been purged while waiting for lock. 215cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 2162c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com ++fCacheMisses; 217cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 2182c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return false; 2192c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com } 2202c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fLocked = true; 2212c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.remove(dm); 2222c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fList.addToHead(dm); 223cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #if SK_LAZY_CACHE_STATS 2242c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com ++fCacheHits; 225cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org #endif // SK_LAZY_CACHE_STATS 2262c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return true; 2272c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2282c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 229cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::unlock(PoolDiscardableMemory* dm) { 2302c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkASSERT(dm != NULL); 2312c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2322c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com dm->fLocked = false; 2332c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(fBudget); 2342c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2352c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 236cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgsize_t DiscardableMemoryPool::getRAMUsed() { 2372c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com return fUsed; 2382c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 239cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::setRAMBudget(size_t budget) { 2402c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2412c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com fBudget = budget; 2422c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(fBudget); 2432c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 244cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.orgvoid DiscardableMemoryPool::dumpPool() { 2452c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com SkAutoMutexAcquire autoMutexAcquire(fMutex); 2462c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com this->dumpDownTo(0); 2472c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2482c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 2492c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com//////////////////////////////////////////////////////////////////////////////// 2502c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.comSK_DECLARE_STATIC_MUTEX(gMutex); 25178358bf624c7e7c09ffccf638c50870808d884d6mtkleinSkDiscardableMemoryPool* create_global_pool() { 25278358bf624c7e7c09ffccf638c50870808d884d6mtklein return SkDiscardableMemoryPool::Create(SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE, 25378358bf624c7e7c09ffccf638c50870808d884d6mtklein &gMutex); 2542c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 25578358bf624c7e7c09ffccf638c50870808d884d6mtklein 256cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org} // namespace 257cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 25878358bf624c7e7c09ffccf638c50870808d884d6mtkleinSkDiscardableMemoryPool* SkDiscardableMemoryPool::Create(size_t size, SkBaseMutex* mutex) { 259cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org return SkNEW_ARGS(DiscardableMemoryPool, (size, mutex)); 260cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org} 261cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org 2622c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.comSkDiscardableMemoryPool* SkGetGlobalDiscardableMemoryPool() { 26378358bf624c7e7c09ffccf638c50870808d884d6mtklein SK_DECLARE_STATIC_LAZY_PTR(SkDiscardableMemoryPool, global, create_global_pool); 26478358bf624c7e7c09ffccf638c50870808d884d6mtklein return global.get(); 2652c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com} 2662c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com 2677e2b0f3b06351cf5bd9f6130f6bfb950cfc2cb75commit-bot@chromium.org// defined in SkImageGenerator.h 2687e2b0f3b06351cf5bd9f6130f6bfb950cfc2cb75commit-bot@chromium.orgvoid SkPurgeGlobalDiscardableMemoryPool() { 2697e2b0f3b06351cf5bd9f6130f6bfb950cfc2cb75commit-bot@chromium.org SkGetGlobalDiscardableMemoryPool()->dumpPool(); 2707e2b0f3b06351cf5bd9f6130f6bfb950cfc2cb75commit-bot@chromium.org} 2712c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com//////////////////////////////////////////////////////////////////////////////// 272