// Note: // A PoolDiscardableMemory is memory that is counted in a pool. // A DiscardableMemoryPool is a pool of PoolDiscardableMemorys.
namespace {
class PoolDiscardableMemory;
/** * This non-global pool can be used for unit tests to verify that the * pool works.
*/ class DiscardableMemoryPool : public SkDiscardableMemoryPool { public:
DiscardableMemoryPool(size_t budget);
~DiscardableMemoryPool() override;
/** Function called to free memory if needed */ void dumpDownTo(size_t budget); /** called by DiscardableMemoryPool upon destruction */ void removeFromPool(PoolDiscardableMemory* dm); /** called by DiscardableMemoryPool::lock() */ bool lock(PoolDiscardableMemory* dm); /** called by DiscardableMemoryPool::unlock() */ void unlock(PoolDiscardableMemory* dm);
friendclass PoolDiscardableMemory;
using INHERITED = SkDiscardableMemory::Factory;
};
/** * A PoolDiscardableMemory is a SkDiscardableMemory that relies on * a DiscardableMemoryPool object to manage the memory.
*/ class PoolDiscardableMemory : public SkDiscardableMemory { public:
PoolDiscardableMemory(sk_sp<DiscardableMemoryPool> pool, UniqueVoidPtr pointer, size_t bytes);
~PoolDiscardableMemory() override; bool lock() override; void* data() override; void unlock() override; friendclass DiscardableMemoryPool; private:
SK_DECLARE_INTERNAL_LLIST_INTERFACE(PoolDiscardableMemory);
sk_sp<DiscardableMemoryPool> fPool; bool fLocked;
UniqueVoidPtr fPointer; const size_t fBytes;
};
DiscardableMemoryPool::DiscardableMemoryPool(size_t budget)
: fBudget(budget)
, fUsed(0) { #if SK_LAZY_CACHE_STATS
fCacheHits = 0;
fCacheMisses = 0; #endif// SK_LAZY_CACHE_STATS
}
DiscardableMemoryPool::~DiscardableMemoryPool() { // PoolDiscardableMemory objects that belong to this pool are // always deleted before deleting this pool since each one has a // ref to the pool.
SkASSERT(fList.isEmpty());
}
void DiscardableMemoryPool::dumpDownTo(size_t budget) {
fMutex.assertHeld(); if (fUsed <= budget) { return;
} using Iter = SkTInternalLList<PoolDiscardableMemory>::Iter;
Iter iter;
PoolDiscardableMemory* cur = iter.init(fList, Iter::kTail_IterStart); while ((fUsed > budget) && (cur)) { if (!cur->fLocked) {
PoolDiscardableMemory* dm = cur;
SkASSERT(dm->fPointer != nullptr);
dm->fPointer = nullptr;
SkASSERT(fUsed >= dm->fBytes);
fUsed -= dm->fBytes;
cur = iter.prev(); // Purged DMs are taken out of the list. This saves times // looking them up. Purged DMs are NOT deleted.
fList.remove(dm);
} else {
cur = iter.prev();
}
}
}
SkDiscardableMemoryPool* SkGetGlobalDiscardableMemoryPool() { // Intentionally leak this global pool. static SkDiscardableMemoryPool* global = new DiscardableMemoryPool(SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE); return global;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.