aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-19 15:40:27 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-19 15:40:27 +0000
commit4da34e36cb7a07c3a28ae2a135b1837c26fc7aea (patch)
tree36ba4b63893a5621fe1eb377ea7cb3f4692c42b3 /tests
parent50e4ce05521b0d95890e894691819882113aae86 (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.cpp239
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)
+