diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-19 15:40:27 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-19 15:40:27 +0000 |
commit | 4da34e36cb7a07c3a28ae2a135b1837c26fc7aea (patch) | |
tree | 36ba4b63893a5621fe1eb377ea7cb3f4692c42b3 /tests | |
parent | 50e4ce05521b0d95890e894691819882113aae86 (diff) |
Add GrMemoryPool as a helper to override operators new/delete
Review URL: http://codereview.appspot.com/6306090/
git-svn-id: http://skia.googlecode.com/svn/trunk@4282 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests')
-rw-r--r-- | tests/GrMemoryPoolTest.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/tests/GrMemoryPoolTest.cpp b/tests/GrMemoryPoolTest.cpp new file mode 100644 index 0000000000..f5527e9b35 --- /dev/null +++ b/tests/GrMemoryPoolTest.cpp @@ -0,0 +1,239 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Test.h" +#include "GrMemoryPool.h" +#include "SkRandom.h" +#include "SkTDArray.h" +#include "SkTScopedPtr.h" +#include "SkInstCnt.h" + +namespace { +// A is the top of an inheritance tree of classes that overload op new and +// and delete to use a GrMemoryPool. The objects have values of different types +// that can be set and checked. +class A { +public: + A() {}; + virtual void setValues(int v) { + fChar = static_cast<char>(v); + } + virtual bool checkValues(int v) { + return fChar == static_cast<char>(v); + } + virtual ~A() {}; + + void* operator new(size_t size) { + if (!gPool.get()) { + return ::operator new(size); + } else { + return gPool->allocate(size); + } + } + + void operator delete(void* p) { + if (!gPool.get()) { + ::operator delete(p); + } else { + return gPool->release(p); + } + } + + SK_DECLARE_INST_COUNT_ROOT(A); + + static A* Create(SkRandom* r); + + static void SetAllocator(size_t preallocSize, size_t minAllocSize) { + SkASSERT(0 == GetInstanceCount()); + GrMemoryPool* pool = new GrMemoryPool(preallocSize, minAllocSize); + gPool.reset(pool); + } + + static void ResetAllocator() { + SkASSERT(0 == GetInstanceCount()); + gPool.reset(NULL); + } + +private: + static SkTScopedPtr<GrMemoryPool> gPool; + char fChar; +}; +SK_DEFINE_INST_COUNT(A); +SkTScopedPtr<GrMemoryPool> A::gPool; + +class B : public A { +public: + B() {}; + virtual void setValues(int v) { + fDouble = static_cast<double>(v); + this->INHERITED::setValues(v); + } + virtual bool checkValues(int v) { + return fDouble == static_cast<double>(v) && + this->INHERITED::checkValues(v); + } + virtual ~B() {}; + +private: + double fDouble; + + typedef A INHERITED; +}; + +class C : public A { +public: + C() {}; + virtual void setValues(int v) { + fInt64 = static_cast<int64_t>(v); + this->INHERITED::setValues(v); + } + virtual bool checkValues(int v) { + return fInt64 == static_cast<int64_t>(v) && + this->INHERITED::checkValues(v); + } + virtual ~C() {}; + +private: + int64_t fInt64; + + typedef A INHERITED; +}; + +// D derives from C and owns a dynamically created B +class D : public C { +public: + D() { + fB = new B(); + } + virtual void setValues(int v) { + fVoidStar = reinterpret_cast<void*>(v); + this->INHERITED::setValues(v); + fB->setValues(v); + } + virtual bool checkValues(int v) { + return fVoidStar == reinterpret_cast<void*>(v) && + fB->checkValues(v) && + this->INHERITED::checkValues(v); + } + virtual ~D() { + delete fB; + } +private: + void* fVoidStar; + B* fB; + + typedef C INHERITED; +}; + +class E : public A { +public: + E() {} + virtual void setValues(int v) { + for (size_t i = 0; i < SK_ARRAY_COUNT(fIntArray); ++i) { + fIntArray[i] = v; + } + this->INHERITED::setValues(v); + } + virtual bool checkValues(int v) { + bool ok = true; + for (size_t i = 0; ok && i < SK_ARRAY_COUNT(fIntArray); ++i) { + if (fIntArray[i] != v) { + ok = false; + } + } + return ok && this->INHERITED::checkValues(v); + } + virtual ~E() {} +private: + int fIntArray[20]; + + typedef A INHERITED; +}; + +A* A::Create(SkRandom* r) { + switch (r->nextRangeU(0, 4)) { + case 0: + return new A; + case 1: + return new B; + case 2: + return new C; + case 3: + return new D; + case 4: + return new E; + default: + // suppress warning + return NULL; + } +} +} +struct Rec { + A* fInstance; + int fValue; +}; + +static void test_memory_pool(skiatest::Reporter* reporter) { + // prealloc and min alloc sizes for the pool + static const size_t gSizes[][2] = { + {0, 0}, + {10 * sizeof(A), 20 * sizeof(A)}, + {100 * sizeof(A), 100 * sizeof(A)}, + {500 * sizeof(A), 500 * sizeof(A)}, + {10000 * sizeof(A), 0}, + {1, 100 * sizeof(A)}, + }; + // different percentages of creation vs deletion + static const float gCreateFraction[] = {1.f, .95f, 0.75f, .5f}; + // number of create/destroys per test + static const int kNumIters = 20000; + // check that all the values stored in A objects are correct after this + // number of iterations + static const int kCheckPeriod = 500; + + SkRandom r; + for (size_t s = 0; s < SK_ARRAY_COUNT(gSizes); ++s) { + A::SetAllocator(gSizes[s][0], gSizes[s][1]); + for (size_t c = 0; c < SK_ARRAY_COUNT(gCreateFraction); ++c) { + SkTDArray<Rec> instanceRecs; + for (int i = 0; i < kNumIters; ++i) { + float createOrDestroy = r.nextUScalar1(); + if (createOrDestroy < gCreateFraction[c] || + 0 == instanceRecs.count()) { + Rec* rec = instanceRecs.append(); + rec->fInstance = A::Create(&r); + rec->fValue = static_cast<int>(r.nextU()); + rec->fInstance->setValues(rec->fValue); + } else { + int d = r.nextRangeU(0, instanceRecs.count() - 1); + Rec& rec = instanceRecs[d]; + REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue)); + delete rec.fInstance; + instanceRecs.removeShuffle(d); + } + if (0 == i % kCheckPeriod) { + for (int r = 0; r < instanceRecs.count(); ++r) { + Rec& rec = instanceRecs[r]; + REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue)); + } + } + } + for (int i = 0; i < instanceRecs.count(); ++i) { + Rec& rec = instanceRecs[i]; + REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue)); + delete rec.fInstance; + } +#ifdef SK_DEBUG + REPORTER_ASSERT(reporter, !A::GetInstanceCount()); +#endif + } + } +} + +#include "TestClassDef.h" +DEFINE_TESTCLASS("GrMemoryPool", GrMemoryPoolClass, test_memory_pool) + |