| Index: tests/GrMemoryPoolTest.cpp
|
| diff --git a/tests/GrMemoryPoolTest.cpp b/tests/GrMemoryPoolTest.cpp
|
| index 863574a35f70a1f3591f9860431152cab158c90e..4eb5ca786f895d2d178e9f876248b30f5120dcf1 100644
|
| --- a/tests/GrMemoryPoolTest.cpp
|
| +++ b/tests/GrMemoryPoolTest.cpp
|
| @@ -10,6 +10,7 @@
|
| #if SK_SUPPORT_GPU
|
| #include "GrMemoryPool.h"
|
| #include "SkRandom.h"
|
| +#include "SkTArray.h"
|
| #include "SkTDArray.h"
|
| #include "SkTemplates.h"
|
|
|
| @@ -227,4 +228,174 @@ DEF_TEST(GrMemoryPool, reporter) {
|
| }
|
| }
|
|
|
| +// GrMemoryPool requires that it's empty at the point of destruction. This helps
|
| +// achieving that by releasing all added memory in the destructor.
|
| +class AutoPoolReleaser {
|
| +public:
|
| + AutoPoolReleaser(GrMemoryPool& pool): fPool(pool) {
|
| + }
|
| + ~AutoPoolReleaser() {
|
| + for (void* ptr: fAllocated) {
|
| + fPool.release(ptr);
|
| + }
|
| + }
|
| + void add(void* ptr) {
|
| + fAllocated.push_back(ptr);
|
| + }
|
| +private:
|
| + GrMemoryPool& fPool;
|
| + SkTArray<void*> fAllocated;
|
| +};
|
| +
|
| +DEF_TEST(GrMemoryPoolAPI, reporter) {
|
| + constexpr size_t kSmallestMinAllocSize = GrMemoryPool::kSmallestMinAllocSize;
|
| +
|
| + // Allocates memory until pool adds a new block (pool.size() changes).
|
| + auto allocateMemory = [](GrMemoryPool& pool, AutoPoolReleaser& r) {
|
| + size_t origPoolSize = pool.size();
|
| + while (pool.size() == origPoolSize) {
|
| + r.add(pool.allocate(31));
|
| + }
|
| + };
|
| +
|
| + // Effective prealloc space capacity is >= kSmallestMinAllocSize.
|
| + {
|
| + GrMemoryPool pool(0, 0);
|
| + REPORTER_ASSERT(reporter, pool.preallocSize() == kSmallestMinAllocSize);
|
| + }
|
| +
|
| + // Effective prealloc space capacity is >= minAllocSize.
|
| + {
|
| + constexpr size_t kMinAllocSize = kSmallestMinAllocSize * 2;
|
| + GrMemoryPool pool(kSmallestMinAllocSize, kMinAllocSize);
|
| + REPORTER_ASSERT(reporter, pool.preallocSize() == kMinAllocSize);
|
| + }
|
| +
|
| + // Effective block size capacity >= kSmallestMinAllocSize.
|
| + {
|
| + GrMemoryPool pool(kSmallestMinAllocSize, kSmallestMinAllocSize / 2);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + allocateMemory(pool, r);
|
| + REPORTER_ASSERT(reporter, pool.size() == kSmallestMinAllocSize);
|
| + }
|
| +
|
| + // Pool allocates exactly preallocSize on creation.
|
| + {
|
| + constexpr size_t kPreallocSize = kSmallestMinAllocSize * 5;
|
| + GrMemoryPool pool(kPreallocSize, 0);
|
| + REPORTER_ASSERT(reporter, pool.preallocSize() == kPreallocSize);
|
| + }
|
| +
|
| + // Pool allocates exactly minAllocSize when it expands.
|
| + {
|
| + constexpr size_t kMinAllocSize = kSmallestMinAllocSize * 7;
|
| + GrMemoryPool pool(0, kMinAllocSize);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + allocateMemory(pool, r);
|
| + REPORTER_ASSERT(reporter, pool.size() == kMinAllocSize);
|
| +
|
| + allocateMemory(pool, r);
|
| + REPORTER_ASSERT(reporter, pool.size() == 2 * kMinAllocSize);
|
| + }
|
| +
|
| + // When asked to allocate amount > minAllocSize, pool allocates larger block
|
| + // to accommodate all internal structures.
|
| + {
|
| + constexpr size_t kMinAllocSize = kSmallestMinAllocSize * 2;
|
| + GrMemoryPool pool(kSmallestMinAllocSize, kMinAllocSize);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + REPORTER_ASSERT(reporter, pool.size() == 0);
|
| +
|
| + constexpr size_t hugeSize = 10 * kMinAllocSize;
|
| + r.add(pool.allocate(hugeSize));
|
| + REPORTER_ASSERT(reporter, pool.size() > hugeSize);
|
| +
|
| + // Block size allocated to accommodate huge request doesn't include any extra
|
| + // space, so next allocation request allocates a new block.
|
| + size_t hugeBlockSize = pool.size();
|
| + r.add(pool.allocate(0));
|
| + REPORTER_ASSERT(reporter, pool.size() == hugeBlockSize + kMinAllocSize);
|
| + }
|
| +}
|
| +
|
| +DEF_TEST(GrObjectMemoryPoolAPI, reporter) {
|
| + struct Data {
|
| + int value[5];
|
| + };
|
| + using DataObjectPool = GrObjectMemoryPool<Data>;
|
| + constexpr size_t kSmallestMinAllocCount = DataObjectPool::kSmallestMinAllocCount;
|
| +
|
| + // Allocates objects until pool adds a new block (pool.size() changes).
|
| + // Returns number of objects that fit into the current block (i.e. before pool.size()
|
| + // changed; newly allocated block always ends up with one object allocated from it).
|
| + auto allocateObjects = [](DataObjectPool& pool, AutoPoolReleaser& r) -> size_t {
|
| + size_t count = 0;
|
| + size_t origPoolSize = pool.size();
|
| + while (pool.size() == origPoolSize) {
|
| + r.add(pool.allocate());
|
| + count++;
|
| + }
|
| + return count - 1;
|
| + };
|
| +
|
| + // Effective prealloc space capacity is >= kSmallestMinAllocCount.
|
| + {
|
| + DataObjectPool pool(kSmallestMinAllocCount / 3, 0);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + size_t preallocCount = allocateObjects(pool, r);
|
| + REPORTER_ASSERT(reporter, preallocCount == kSmallestMinAllocCount);
|
| + }
|
| +
|
| + // Effective prealloc space capacity is >= minAllocCount.
|
| + {
|
| + DataObjectPool pool(kSmallestMinAllocCount, 2 * kSmallestMinAllocCount);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + size_t preallocCount = allocateObjects(pool, r);
|
| + REPORTER_ASSERT(reporter, preallocCount == 2 * kSmallestMinAllocCount);
|
| + }
|
| +
|
| + // Effective block capacity is >= kSmallestMinAllocCount.
|
| + {
|
| + DataObjectPool pool(kSmallestMinAllocCount, kSmallestMinAllocCount / 2);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + // Fill prealloc space
|
| + allocateObjects(pool, r);
|
| +
|
| + size_t minAllocCount = 1 + allocateObjects(pool, r);
|
| + REPORTER_ASSERT(reporter, minAllocCount == kSmallestMinAllocCount);
|
| + }
|
| +
|
| + // Pool allocates space for exactly preallocCount objects on creation.
|
| + {
|
| + constexpr size_t kPreallocCount = kSmallestMinAllocCount * 7 / 3;
|
| + DataObjectPool pool(kPreallocCount, 0);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + size_t preallocCount = allocateObjects(pool, r);
|
| + REPORTER_ASSERT(reporter, preallocCount == kPreallocCount);
|
| + }
|
| +
|
| + // Pool allocates space for minAllocCount objects when it adds a new block.
|
| + {
|
| + constexpr size_t kMinAllocCount = kSmallestMinAllocCount * 11 / 3;
|
| + DataObjectPool pool(0, kMinAllocCount);
|
| + AutoPoolReleaser r(pool);
|
| +
|
| + // Fill prealloc space
|
| + allocateObjects(pool, r);
|
| +
|
| + size_t firstBlockCount = 1 + allocateObjects(pool, r);
|
| + REPORTER_ASSERT(reporter, firstBlockCount == kMinAllocCount);
|
| +
|
| + size_t secondBlockCount = 1 + allocateObjects(pool, r);
|
| + REPORTER_ASSERT(reporter, secondBlockCount == kMinAllocCount);
|
| + }
|
| +}
|
| +
|
| #endif
|
|
|