SkDiscardableMemoryPool: modernize
* Use unique_ptr, sk_sp, SkAutoFree, using. * Rely on thread-safe static global initializion. Change-Id: I7c14e0e57622163b1b81b97a218b816fe6d02926 Reviewed-on: https://skia-review.googlesource.com/13818 Commit-Queue: Hal Canary <halcanary@google.com> Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
parent
600effbdc7
commit
a294be2404
@ -5,13 +5,13 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkDiscardableMemory.h"
|
||||
#include "SkDiscardableMemoryPool.h"
|
||||
#include "SkImageGenerator.h"
|
||||
#include "SkDiscardableMemory.h"
|
||||
#include "SkMakeUnique.h"
|
||||
#include "SkMalloc.h"
|
||||
#include "SkMutex.h"
|
||||
#include "SkOnce.h"
|
||||
#include "SkTInternalLList.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
// Note:
|
||||
// A PoolDiscardableMemory is memory that is counted in a pool.
|
||||
@ -33,7 +33,10 @@ public:
|
||||
DiscardableMemoryPool(size_t budget, SkBaseMutex* mutex = nullptr);
|
||||
~DiscardableMemoryPool() override;
|
||||
|
||||
SkDiscardableMemory* create(size_t bytes) override;
|
||||
std::unique_ptr<SkDiscardableMemory> make(size_t bytes);
|
||||
SkDiscardableMemory* create(size_t bytes) override {
|
||||
return this->make(bytes).release(); // TODO: change API
|
||||
}
|
||||
|
||||
size_t getRAMUsed() override;
|
||||
void setRAMBudget(size_t budget) override;
|
||||
@ -61,7 +64,7 @@ private:
|
||||
/** Function called to free memory if needed */
|
||||
void dumpDownTo(size_t budget);
|
||||
/** called by DiscardableMemoryPool upon destruction */
|
||||
void free(PoolDiscardableMemory* dm);
|
||||
void removeFromPool(PoolDiscardableMemory* dm);
|
||||
/** called by DiscardableMemoryPool::lock() */
|
||||
bool lock(PoolDiscardableMemory* dm);
|
||||
/** called by DiscardableMemoryPool::unlock() */
|
||||
@ -78,8 +81,7 @@ private:
|
||||
*/
|
||||
class PoolDiscardableMemory : public SkDiscardableMemory {
|
||||
public:
|
||||
PoolDiscardableMemory(DiscardableMemoryPool* pool,
|
||||
void* pointer, size_t bytes);
|
||||
PoolDiscardableMemory(sk_sp<DiscardableMemoryPool> pool, SkAutoFree pointer, size_t bytes);
|
||||
~PoolDiscardableMemory() override;
|
||||
bool lock() override;
|
||||
void* data() override;
|
||||
@ -87,29 +89,24 @@ public:
|
||||
friend class DiscardableMemoryPool;
|
||||
private:
|
||||
SK_DECLARE_INTERNAL_LLIST_INTERFACE(PoolDiscardableMemory);
|
||||
DiscardableMemoryPool* const fPool;
|
||||
sk_sp<DiscardableMemoryPool> fPool;
|
||||
bool fLocked;
|
||||
void* fPointer;
|
||||
SkAutoFree fPointer;
|
||||
const size_t fBytes;
|
||||
};
|
||||
|
||||
PoolDiscardableMemory::PoolDiscardableMemory(DiscardableMemoryPool* pool,
|
||||
void* pointer,
|
||||
PoolDiscardableMemory::PoolDiscardableMemory(sk_sp<DiscardableMemoryPool> pool,
|
||||
SkAutoFree pointer,
|
||||
size_t bytes)
|
||||
: fPool(pool)
|
||||
, fLocked(true)
|
||||
, fPointer(pointer)
|
||||
, fBytes(bytes) {
|
||||
: fPool(std::move(pool)), fLocked(true), fPointer(std::move(pointer)), fBytes(bytes) {
|
||||
SkASSERT(fPool != nullptr);
|
||||
SkASSERT(fPointer != nullptr);
|
||||
SkASSERT(fBytes > 0);
|
||||
fPool->ref();
|
||||
}
|
||||
|
||||
PoolDiscardableMemory::~PoolDiscardableMemory() {
|
||||
SkASSERT(!fLocked); // contract for SkDiscardableMemory
|
||||
fPool->free(this);
|
||||
fPool->unref();
|
||||
fPool->removeFromPool(this);
|
||||
}
|
||||
|
||||
bool PoolDiscardableMemory::lock() {
|
||||
@ -119,7 +116,7 @@ bool PoolDiscardableMemory::lock() {
|
||||
|
||||
void* PoolDiscardableMemory::data() {
|
||||
SkASSERT(fLocked); // contract for SkDiscardableMemory
|
||||
return fPointer;
|
||||
return fPointer.get();
|
||||
}
|
||||
|
||||
void PoolDiscardableMemory::unlock() {
|
||||
@ -153,14 +150,13 @@ void DiscardableMemoryPool::dumpDownTo(size_t budget) {
|
||||
if (fUsed <= budget) {
|
||||
return;
|
||||
}
|
||||
typedef SkTInternalLList<PoolDiscardableMemory>::Iter Iter;
|
||||
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);
|
||||
sk_free(dm->fPointer);
|
||||
dm->fPointer = nullptr;
|
||||
SkASSERT(fUsed >= dm->fBytes);
|
||||
fUsed -= dm->fBytes;
|
||||
@ -174,25 +170,23 @@ void DiscardableMemoryPool::dumpDownTo(size_t budget) {
|
||||
}
|
||||
}
|
||||
|
||||
SkDiscardableMemory* DiscardableMemoryPool::create(size_t bytes) {
|
||||
void* addr = sk_malloc_flags(bytes, 0);
|
||||
std::unique_ptr<SkDiscardableMemory> DiscardableMemoryPool::make(size_t bytes) {
|
||||
SkAutoFree addr(sk_malloc_flags(bytes, 0));
|
||||
if (nullptr == addr) {
|
||||
return nullptr;
|
||||
}
|
||||
PoolDiscardableMemory* dm = new PoolDiscardableMemory(this, addr, bytes);
|
||||
auto dm = skstd::make_unique<PoolDiscardableMemory>(sk_ref_sp(this), std::move(addr), bytes);
|
||||
SkAutoMutexAcquire autoMutexAcquire(fMutex);
|
||||
fList.addToHead(dm);
|
||||
fList.addToHead(dm.get());
|
||||
fUsed += bytes;
|
||||
this->dumpDownTo(fBudget);
|
||||
return dm;
|
||||
return std::move(dm);
|
||||
}
|
||||
|
||||
void DiscardableMemoryPool::free(PoolDiscardableMemory* dm) {
|
||||
void DiscardableMemoryPool::removeFromPool(PoolDiscardableMemory* dm) {
|
||||
SkAutoMutexAcquire autoMutexAcquire(fMutex);
|
||||
// This is called by dm's destructor.
|
||||
if (dm->fPointer != nullptr) {
|
||||
sk_free(dm->fPointer);
|
||||
dm->fPointer = nullptr;
|
||||
SkASSERT(fUsed >= dm->fBytes);
|
||||
fUsed -= dm->fBytes;
|
||||
fList.remove(dm);
|
||||
@ -242,18 +236,14 @@ void DiscardableMemoryPool::dumpPool() {
|
||||
|
||||
} // namespace
|
||||
|
||||
SkDiscardableMemoryPool* SkDiscardableMemoryPool::Create(size_t size, SkBaseMutex* mutex) {
|
||||
return new DiscardableMemoryPool(size, mutex);
|
||||
sk_sp<SkDiscardableMemoryPool> SkDiscardableMemoryPool::Make(size_t size, SkBaseMutex* mutex) {
|
||||
return sk_make_sp<DiscardableMemoryPool>(size, mutex);
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gMutex);
|
||||
|
||||
SkDiscardableMemoryPool* SkGetGlobalDiscardableMemoryPool() {
|
||||
static SkOnce once;
|
||||
static SkDiscardableMemoryPool* global;
|
||||
once([]{
|
||||
global = SkDiscardableMemoryPool::Create(SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE,
|
||||
&gMutex);
|
||||
});
|
||||
static SkBaseMutex gMutex;
|
||||
// Intentionally leak this global pool.
|
||||
static SkDiscardableMemoryPool* global =
|
||||
new DiscardableMemoryPool(SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE, &gMutex);
|
||||
return global;
|
||||
}
|
||||
|
@ -52,8 +52,7 @@ public:
|
||||
* the pool works.
|
||||
* Without mutex, will be not be thread safe.
|
||||
*/
|
||||
static SkDiscardableMemoryPool* Create(
|
||||
size_t size, SkBaseMutex* mutex = nullptr);
|
||||
static sk_sp<SkDiscardableMemoryPool> Make(size_t size, SkBaseMutex* mutex = nullptr);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -72,7 +72,7 @@ static SkCachedData* test_locking(skiatest::Reporter* reporter,
|
||||
* and when the cache is.
|
||||
*/
|
||||
DEF_TEST(CachedData, reporter) {
|
||||
sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Create(1000));
|
||||
sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Make(1000));
|
||||
|
||||
for (int useDiscardable = 0; useDiscardable <= 1; ++useDiscardable) {
|
||||
const size_t size = 100;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
DEF_TEST(DiscardableMemoryPool, reporter) {
|
||||
sk_sp<SkDiscardableMemoryPool> pool(
|
||||
SkDiscardableMemoryPool::Create(1, nullptr));
|
||||
SkDiscardableMemoryPool::Make(1, nullptr));
|
||||
pool->setRAMBudget(3);
|
||||
REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
|
||||
|
||||
|
@ -52,8 +52,8 @@ DEF_TEST(DiscardableMemory_global, reporter) {
|
||||
}
|
||||
|
||||
DEF_TEST(DiscardableMemory_nonglobal, reporter) {
|
||||
std::unique_ptr<SkDiscardableMemoryPool> pool(
|
||||
SkDiscardableMemoryPool::Create(1024, /* mutex = */ nullptr));
|
||||
sk_sp<SkDiscardableMemoryPool> pool(
|
||||
SkDiscardableMemoryPool::Make(1024, /* mutex = */ nullptr));
|
||||
std::unique_ptr<SkDiscardableMemory> dm(pool->create(kTestStringLength));
|
||||
test_dm(reporter, dm.get(), true);
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ DEF_TEST(ImageCache, reporter) {
|
||||
test_cache(reporter, cache, true);
|
||||
}
|
||||
{
|
||||
sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Create(defLimit, nullptr));
|
||||
sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Make(defLimit, nullptr));
|
||||
gPool = pool.get();
|
||||
SkResourceCache cache(pool_factory);
|
||||
test_cache(reporter, cache, true);
|
||||
|
@ -127,7 +127,7 @@ DEF_TEST(BitmapCache_discarded_bitmap, reporter) {
|
||||
testBitmapCache_discarded_bitmap(reporter, &cache, nullptr);
|
||||
}
|
||||
{
|
||||
sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Create(byteLimit, nullptr));
|
||||
sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Make(byteLimit, nullptr));
|
||||
gPool = pool.get();
|
||||
SkResourceCache::DiscardableFactory factory = pool_factory;
|
||||
SkResourceCache cache(factory);
|
||||
|
Loading…
Reference in New Issue
Block a user