2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 // This is a GPU-backend specific test
11 #include "GrMemoryPool.h"
12 #include "SkInstCnt.h"
14 #include "SkTDArray.h"
15 #include "SkTemplates.h"
17 // A is the top of an inheritance tree of classes that overload op new and
18 // and delete to use a GrMemoryPool. The objects have values of different types
19 // that can be set and checked.
23 virtual void setValues(int v) {
24 fChar = static_cast<char>(v);
26 virtual bool checkValues(int v) {
27 return fChar == static_cast<char>(v);
31 void* operator new(size_t size) {
33 return ::operator new(size);
35 return gPool->allocate(size);
39 void operator delete(void* p) {
43 return gPool->release(p);
47 SK_DECLARE_INST_COUNT_ROOT(A);
49 static A* Create(SkRandom* r);
51 static void SetAllocator(size_t preallocSize, size_t minAllocSize) {
52 #if SK_ENABLE_INST_COUNT
53 SkASSERT(0 == GetInstanceCount());
55 GrMemoryPool* pool = new GrMemoryPool(preallocSize, minAllocSize);
59 static void ResetAllocator() {
60 #if SK_ENABLE_INST_COUNT
61 SkASSERT(0 == GetInstanceCount());
67 static SkAutoTDelete<GrMemoryPool> gPool;
71 SkAutoTDelete<GrMemoryPool> A::gPool;
76 virtual void setValues(int v) {
77 fDouble = static_cast<double>(v);
78 this->INHERITED::setValues(v);
80 virtual bool checkValues(int v) {
81 return fDouble == static_cast<double>(v) &&
82 this->INHERITED::checkValues(v);
95 virtual void setValues(int v) {
96 fInt64 = static_cast<int64_t>(v);
97 this->INHERITED::setValues(v);
99 virtual bool checkValues(int v) {
100 return fInt64 == static_cast<int64_t>(v) &&
101 this->INHERITED::checkValues(v);
111 // D derives from C and owns a dynamically created B
117 virtual void setValues(int v) {
118 fVoidStar = reinterpret_cast<void*>(v);
119 this->INHERITED::setValues(v);
122 virtual bool checkValues(int v) {
123 return fVoidStar == reinterpret_cast<void*>(v) &&
124 fB->checkValues(v) &&
125 this->INHERITED::checkValues(v);
140 virtual void setValues(int v) {
141 for (size_t i = 0; i < SK_ARRAY_COUNT(fIntArray); ++i) {
144 this->INHERITED::setValues(v);
146 virtual bool checkValues(int v) {
148 for (size_t i = 0; ok && i < SK_ARRAY_COUNT(fIntArray); ++i) {
149 if (fIntArray[i] != v) {
153 return ok && this->INHERITED::checkValues(v);
162 A* A::Create(SkRandom* r) {
163 switch (r->nextRangeU(0, 4)) {
185 DEF_TEST(GrMemoryPool, reporter) {
186 // prealloc and min alloc sizes for the pool
187 static const size_t gSizes[][2] = {
189 {10 * sizeof(A), 20 * sizeof(A)},
190 {100 * sizeof(A), 100 * sizeof(A)},
191 {500 * sizeof(A), 500 * sizeof(A)},
192 {10000 * sizeof(A), 0},
193 {1, 100 * sizeof(A)},
195 // different percentages of creation vs deletion
196 static const float gCreateFraction[] = {1.f, .95f, 0.75f, .5f};
197 // number of create/destroys per test
198 static const int kNumIters = 20000;
199 // check that all the values stored in A objects are correct after this
200 // number of iterations
201 static const int kCheckPeriod = 500;
204 for (size_t s = 0; s < SK_ARRAY_COUNT(gSizes); ++s) {
205 A::SetAllocator(gSizes[s][0], gSizes[s][1]);
206 for (size_t c = 0; c < SK_ARRAY_COUNT(gCreateFraction); ++c) {
207 SkTDArray<Rec> instanceRecs;
208 for (int i = 0; i < kNumIters; ++i) {
209 float createOrDestroy = r.nextUScalar1();
210 if (createOrDestroy < gCreateFraction[c] ||
211 0 == instanceRecs.count()) {
212 Rec* rec = instanceRecs.append();
213 rec->fInstance = A::Create(&r);
214 rec->fValue = static_cast<int>(r.nextU());
215 rec->fInstance->setValues(rec->fValue);
217 int d = r.nextRangeU(0, instanceRecs.count() - 1);
218 Rec& rec = instanceRecs[d];
219 REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue));
220 delete rec.fInstance;
221 instanceRecs.removeShuffle(d);
223 if (0 == i % kCheckPeriod) {
224 for (int r = 0; r < instanceRecs.count(); ++r) {
225 Rec& rec = instanceRecs[r];
226 REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue));
230 for (int i = 0; i < instanceRecs.count(); ++i) {
231 Rec& rec = instanceRecs[i];
232 REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue));
233 delete rec.fInstance;
235 #if SK_ENABLE_INST_COUNT
236 REPORTER_ASSERT(reporter, !A::GetInstanceCount());