1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTDArray.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrMemoryPool.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
13*c8dee2aaSAndroid Build Coastguard Worker
14*c8dee2aaSAndroid Build Coastguard Worker #include <array>
15*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
16*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
17*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
18*c8dee2aaSAndroid Build Coastguard Worker
19*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
20*c8dee2aaSAndroid Build Coastguard Worker
21*c8dee2aaSAndroid Build Coastguard Worker // A is the top of an inheritance tree of classes that overload op new and
22*c8dee2aaSAndroid Build Coastguard Worker // and delete to use a GrMemoryPool. The objects have values of different types
23*c8dee2aaSAndroid Build Coastguard Worker // that can be set and checked.
24*c8dee2aaSAndroid Build Coastguard Worker class A {
25*c8dee2aaSAndroid Build Coastguard Worker public:
A()26*c8dee2aaSAndroid Build Coastguard Worker A() {}
setValues(int v)27*c8dee2aaSAndroid Build Coastguard Worker virtual void setValues(int v) {
28*c8dee2aaSAndroid Build Coastguard Worker fChar = static_cast<char>(v & 0xFF);
29*c8dee2aaSAndroid Build Coastguard Worker }
checkValues(int v)30*c8dee2aaSAndroid Build Coastguard Worker virtual bool checkValues(int v) {
31*c8dee2aaSAndroid Build Coastguard Worker return fChar == static_cast<char>(v & 0xFF);
32*c8dee2aaSAndroid Build Coastguard Worker }
~A()33*c8dee2aaSAndroid Build Coastguard Worker virtual ~A() {}
34*c8dee2aaSAndroid Build Coastguard Worker
operator new(size_t size)35*c8dee2aaSAndroid Build Coastguard Worker void* operator new(size_t size) {
36*c8dee2aaSAndroid Build Coastguard Worker if (!gPool) {
37*c8dee2aaSAndroid Build Coastguard Worker return ::operator new(size);
38*c8dee2aaSAndroid Build Coastguard Worker } else {
39*c8dee2aaSAndroid Build Coastguard Worker return gPool->allocate(size);
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker }
42*c8dee2aaSAndroid Build Coastguard Worker
operator delete(void * p)43*c8dee2aaSAndroid Build Coastguard Worker void operator delete(void* p) {
44*c8dee2aaSAndroid Build Coastguard Worker if (!gPool) {
45*c8dee2aaSAndroid Build Coastguard Worker ::operator delete(p);
46*c8dee2aaSAndroid Build Coastguard Worker } else {
47*c8dee2aaSAndroid Build Coastguard Worker return gPool->release(p);
48*c8dee2aaSAndroid Build Coastguard Worker }
49*c8dee2aaSAndroid Build Coastguard Worker }
50*c8dee2aaSAndroid Build Coastguard Worker
51*c8dee2aaSAndroid Build Coastguard Worker static A* Create(SkRandom* r);
52*c8dee2aaSAndroid Build Coastguard Worker
SetAllocator(size_t preallocSize,size_t minAllocSize)53*c8dee2aaSAndroid Build Coastguard Worker static void SetAllocator(size_t preallocSize, size_t minAllocSize) {
54*c8dee2aaSAndroid Build Coastguard Worker gPool = GrMemoryPool::Make(preallocSize, minAllocSize);
55*c8dee2aaSAndroid Build Coastguard Worker }
56*c8dee2aaSAndroid Build Coastguard Worker
ResetAllocator()57*c8dee2aaSAndroid Build Coastguard Worker static void ResetAllocator() { gPool.reset(); }
58*c8dee2aaSAndroid Build Coastguard Worker
ValidatePool()59*c8dee2aaSAndroid Build Coastguard Worker static void ValidatePool() {
60*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
61*c8dee2aaSAndroid Build Coastguard Worker gPool->validate();
62*c8dee2aaSAndroid Build Coastguard Worker #endif
63*c8dee2aaSAndroid Build Coastguard Worker }
64*c8dee2aaSAndroid Build Coastguard Worker
65*c8dee2aaSAndroid Build Coastguard Worker private:
66*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<GrMemoryPool> gPool;
67*c8dee2aaSAndroid Build Coastguard Worker char fChar;
68*c8dee2aaSAndroid Build Coastguard Worker };
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrMemoryPool> A::gPool;
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker class B : public A {
73*c8dee2aaSAndroid Build Coastguard Worker public:
B()74*c8dee2aaSAndroid Build Coastguard Worker B() {}
setValues(int v)75*c8dee2aaSAndroid Build Coastguard Worker void setValues(int v) override {
76*c8dee2aaSAndroid Build Coastguard Worker fDouble = static_cast<double>(v);
77*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::setValues(v);
78*c8dee2aaSAndroid Build Coastguard Worker }
checkValues(int v)79*c8dee2aaSAndroid Build Coastguard Worker bool checkValues(int v) override {
80*c8dee2aaSAndroid Build Coastguard Worker return fDouble == static_cast<double>(v) &&
81*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::checkValues(v);
82*c8dee2aaSAndroid Build Coastguard Worker }
83*c8dee2aaSAndroid Build Coastguard Worker
84*c8dee2aaSAndroid Build Coastguard Worker private:
85*c8dee2aaSAndroid Build Coastguard Worker double fDouble;
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = A;
88*c8dee2aaSAndroid Build Coastguard Worker };
89*c8dee2aaSAndroid Build Coastguard Worker
90*c8dee2aaSAndroid Build Coastguard Worker class C : public A {
91*c8dee2aaSAndroid Build Coastguard Worker public:
C()92*c8dee2aaSAndroid Build Coastguard Worker C() {}
setValues(int v)93*c8dee2aaSAndroid Build Coastguard Worker void setValues(int v) override {
94*c8dee2aaSAndroid Build Coastguard Worker fInt64 = static_cast<int64_t>(v);
95*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::setValues(v);
96*c8dee2aaSAndroid Build Coastguard Worker }
checkValues(int v)97*c8dee2aaSAndroid Build Coastguard Worker bool checkValues(int v) override {
98*c8dee2aaSAndroid Build Coastguard Worker return fInt64 == static_cast<int64_t>(v) &&
99*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::checkValues(v);
100*c8dee2aaSAndroid Build Coastguard Worker }
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker private:
103*c8dee2aaSAndroid Build Coastguard Worker int64_t fInt64;
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = A;
106*c8dee2aaSAndroid Build Coastguard Worker };
107*c8dee2aaSAndroid Build Coastguard Worker
108*c8dee2aaSAndroid Build Coastguard Worker // D derives from C and owns a dynamically created B
109*c8dee2aaSAndroid Build Coastguard Worker class D : public C {
110*c8dee2aaSAndroid Build Coastguard Worker public:
D()111*c8dee2aaSAndroid Build Coastguard Worker D() {
112*c8dee2aaSAndroid Build Coastguard Worker fB = new B();
113*c8dee2aaSAndroid Build Coastguard Worker }
setValues(int v)114*c8dee2aaSAndroid Build Coastguard Worker void setValues(int v) override {
115*c8dee2aaSAndroid Build Coastguard Worker fVoidStar = reinterpret_cast<void*>(static_cast<intptr_t>(v));
116*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::setValues(v);
117*c8dee2aaSAndroid Build Coastguard Worker fB->setValues(v);
118*c8dee2aaSAndroid Build Coastguard Worker }
checkValues(int v)119*c8dee2aaSAndroid Build Coastguard Worker bool checkValues(int v) override {
120*c8dee2aaSAndroid Build Coastguard Worker return fVoidStar == reinterpret_cast<void*>(static_cast<intptr_t>(v)) &&
121*c8dee2aaSAndroid Build Coastguard Worker fB->checkValues(v) &&
122*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::checkValues(v);
123*c8dee2aaSAndroid Build Coastguard Worker }
~D()124*c8dee2aaSAndroid Build Coastguard Worker ~D() override {
125*c8dee2aaSAndroid Build Coastguard Worker delete fB;
126*c8dee2aaSAndroid Build Coastguard Worker }
127*c8dee2aaSAndroid Build Coastguard Worker private:
128*c8dee2aaSAndroid Build Coastguard Worker void* fVoidStar;
129*c8dee2aaSAndroid Build Coastguard Worker B* fB;
130*c8dee2aaSAndroid Build Coastguard Worker
131*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = C;
132*c8dee2aaSAndroid Build Coastguard Worker };
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker class E : public A {
135*c8dee2aaSAndroid Build Coastguard Worker public:
E()136*c8dee2aaSAndroid Build Coastguard Worker E() {}
setValues(int v)137*c8dee2aaSAndroid Build Coastguard Worker void setValues(int v) override {
138*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(fIntArray); ++i) {
139*c8dee2aaSAndroid Build Coastguard Worker fIntArray[i] = v;
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::setValues(v);
142*c8dee2aaSAndroid Build Coastguard Worker }
checkValues(int v)143*c8dee2aaSAndroid Build Coastguard Worker bool checkValues(int v) override {
144*c8dee2aaSAndroid Build Coastguard Worker bool ok = true;
145*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; ok && i < std::size(fIntArray); ++i) {
146*c8dee2aaSAndroid Build Coastguard Worker if (fIntArray[i] != v) {
147*c8dee2aaSAndroid Build Coastguard Worker ok = false;
148*c8dee2aaSAndroid Build Coastguard Worker }
149*c8dee2aaSAndroid Build Coastguard Worker }
150*c8dee2aaSAndroid Build Coastguard Worker return ok && this->INHERITED::checkValues(v);
151*c8dee2aaSAndroid Build Coastguard Worker }
152*c8dee2aaSAndroid Build Coastguard Worker private:
153*c8dee2aaSAndroid Build Coastguard Worker int fIntArray[20];
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = A;
156*c8dee2aaSAndroid Build Coastguard Worker };
157*c8dee2aaSAndroid Build Coastguard Worker
Create(SkRandom * r)158*c8dee2aaSAndroid Build Coastguard Worker A* A::Create(SkRandom* r) {
159*c8dee2aaSAndroid Build Coastguard Worker switch (r->nextRangeU(0, 4)) {
160*c8dee2aaSAndroid Build Coastguard Worker case 0:
161*c8dee2aaSAndroid Build Coastguard Worker return new A;
162*c8dee2aaSAndroid Build Coastguard Worker case 1:
163*c8dee2aaSAndroid Build Coastguard Worker return new B;
164*c8dee2aaSAndroid Build Coastguard Worker case 2:
165*c8dee2aaSAndroid Build Coastguard Worker return new C;
166*c8dee2aaSAndroid Build Coastguard Worker case 3:
167*c8dee2aaSAndroid Build Coastguard Worker return new D;
168*c8dee2aaSAndroid Build Coastguard Worker case 4:
169*c8dee2aaSAndroid Build Coastguard Worker return new E;
170*c8dee2aaSAndroid Build Coastguard Worker default:
171*c8dee2aaSAndroid Build Coastguard Worker // suppress warning
172*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
173*c8dee2aaSAndroid Build Coastguard Worker }
174*c8dee2aaSAndroid Build Coastguard Worker }
175*c8dee2aaSAndroid Build Coastguard Worker
176*c8dee2aaSAndroid Build Coastguard Worker struct Rec {
177*c8dee2aaSAndroid Build Coastguard Worker A* fInstance;
178*c8dee2aaSAndroid Build Coastguard Worker int fValue;
179*c8dee2aaSAndroid Build Coastguard Worker };
180*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(GrMemoryPool,reporter)181*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(GrMemoryPool, reporter) {
182*c8dee2aaSAndroid Build Coastguard Worker // prealloc and min alloc sizes for the pool
183*c8dee2aaSAndroid Build Coastguard Worker static const size_t gSizes[][2] = {
184*c8dee2aaSAndroid Build Coastguard Worker {0, 0},
185*c8dee2aaSAndroid Build Coastguard Worker {10 * sizeof(A), 20 * sizeof(A)},
186*c8dee2aaSAndroid Build Coastguard Worker {100 * sizeof(A), 100 * sizeof(A)},
187*c8dee2aaSAndroid Build Coastguard Worker {500 * sizeof(A), 500 * sizeof(A)},
188*c8dee2aaSAndroid Build Coastguard Worker {10000 * sizeof(A), 0},
189*c8dee2aaSAndroid Build Coastguard Worker {1, 100 * sizeof(A)},
190*c8dee2aaSAndroid Build Coastguard Worker };
191*c8dee2aaSAndroid Build Coastguard Worker
192*c8dee2aaSAndroid Build Coastguard Worker // different percentages of creation vs deletion
193*c8dee2aaSAndroid Build Coastguard Worker static const float gCreateFraction[] = {1.f, .95f, 0.75f, .5f};
194*c8dee2aaSAndroid Build Coastguard Worker // number of create/destroys per test
195*c8dee2aaSAndroid Build Coastguard Worker static const int kNumIters = 20000;
196*c8dee2aaSAndroid Build Coastguard Worker // check that all the values stored in A objects are correct after this
197*c8dee2aaSAndroid Build Coastguard Worker // number of iterations
198*c8dee2aaSAndroid Build Coastguard Worker static const int kCheckPeriod = 500;
199*c8dee2aaSAndroid Build Coastguard Worker
200*c8dee2aaSAndroid Build Coastguard Worker SkRandom r;
201*c8dee2aaSAndroid Build Coastguard Worker for (size_t s = 0; s < std::size(gSizes); ++s) {
202*c8dee2aaSAndroid Build Coastguard Worker A::SetAllocator(gSizes[s][0], gSizes[s][1]);
203*c8dee2aaSAndroid Build Coastguard Worker A::ValidatePool();
204*c8dee2aaSAndroid Build Coastguard Worker for (size_t c = 0; c < std::size(gCreateFraction); ++c) {
205*c8dee2aaSAndroid Build Coastguard Worker SkTDArray<Rec> instanceRecs;
206*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kNumIters; ++i) {
207*c8dee2aaSAndroid Build Coastguard Worker float createOrDestroy = r.nextUScalar1();
208*c8dee2aaSAndroid Build Coastguard Worker if (createOrDestroy < gCreateFraction[c] ||
209*c8dee2aaSAndroid Build Coastguard Worker 0 == instanceRecs.size()) {
210*c8dee2aaSAndroid Build Coastguard Worker Rec* rec = instanceRecs.append();
211*c8dee2aaSAndroid Build Coastguard Worker rec->fInstance = A::Create(&r);
212*c8dee2aaSAndroid Build Coastguard Worker rec->fValue = static_cast<int>(r.nextU());
213*c8dee2aaSAndroid Build Coastguard Worker rec->fInstance->setValues(rec->fValue);
214*c8dee2aaSAndroid Build Coastguard Worker } else {
215*c8dee2aaSAndroid Build Coastguard Worker int d = r.nextRangeU(0, instanceRecs.size() - 1);
216*c8dee2aaSAndroid Build Coastguard Worker Rec& rec = instanceRecs[d];
217*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue));
218*c8dee2aaSAndroid Build Coastguard Worker delete rec.fInstance;
219*c8dee2aaSAndroid Build Coastguard Worker instanceRecs.removeShuffle(d);
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker if (0 == i % kCheckPeriod) {
222*c8dee2aaSAndroid Build Coastguard Worker A::ValidatePool();
223*c8dee2aaSAndroid Build Coastguard Worker for (Rec& rec : instanceRecs) {
224*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue));
225*c8dee2aaSAndroid Build Coastguard Worker }
226*c8dee2aaSAndroid Build Coastguard Worker }
227*c8dee2aaSAndroid Build Coastguard Worker }
228*c8dee2aaSAndroid Build Coastguard Worker for (Rec& rec : instanceRecs) {
229*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue));
230*c8dee2aaSAndroid Build Coastguard Worker delete rec.fInstance;
231*c8dee2aaSAndroid Build Coastguard Worker }
232*c8dee2aaSAndroid Build Coastguard Worker }
233*c8dee2aaSAndroid Build Coastguard Worker }
234*c8dee2aaSAndroid Build Coastguard Worker }
235*c8dee2aaSAndroid Build Coastguard Worker
236*c8dee2aaSAndroid Build Coastguard Worker // GrMemoryPool requires that it's empty at the point of destruction. This helps
237*c8dee2aaSAndroid Build Coastguard Worker // achieving that by releasing all added memory in the destructor.
238*c8dee2aaSAndroid Build Coastguard Worker class AutoPoolReleaser {
239*c8dee2aaSAndroid Build Coastguard Worker public:
AutoPoolReleaser(GrMemoryPool & pool)240*c8dee2aaSAndroid Build Coastguard Worker AutoPoolReleaser(GrMemoryPool& pool): fPool(pool) {
241*c8dee2aaSAndroid Build Coastguard Worker }
~AutoPoolReleaser()242*c8dee2aaSAndroid Build Coastguard Worker ~AutoPoolReleaser() {
243*c8dee2aaSAndroid Build Coastguard Worker for (void* ptr: fAllocated) {
244*c8dee2aaSAndroid Build Coastguard Worker fPool.release(ptr);
245*c8dee2aaSAndroid Build Coastguard Worker }
246*c8dee2aaSAndroid Build Coastguard Worker }
add(void * ptr)247*c8dee2aaSAndroid Build Coastguard Worker void add(void* ptr) {
248*c8dee2aaSAndroid Build Coastguard Worker fAllocated.push_back(ptr);
249*c8dee2aaSAndroid Build Coastguard Worker }
250*c8dee2aaSAndroid Build Coastguard Worker private:
251*c8dee2aaSAndroid Build Coastguard Worker GrMemoryPool& fPool;
252*c8dee2aaSAndroid Build Coastguard Worker TArray<void*> fAllocated;
253*c8dee2aaSAndroid Build Coastguard Worker };
254*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(GrMemoryPoolAPI,reporter)255*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(GrMemoryPoolAPI, reporter) {
256*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t kSmallestMinAllocSize = GrMemoryPool::kMinAllocationSize;
257*c8dee2aaSAndroid Build Coastguard Worker
258*c8dee2aaSAndroid Build Coastguard Worker // Allocates memory until pool adds a new block (pool->size() changes).
259*c8dee2aaSAndroid Build Coastguard Worker auto allocateMemory = [](GrMemoryPool& pool, AutoPoolReleaser& r) {
260*c8dee2aaSAndroid Build Coastguard Worker size_t origPoolSize = pool.size();
261*c8dee2aaSAndroid Build Coastguard Worker while (pool.size() == origPoolSize) {
262*c8dee2aaSAndroid Build Coastguard Worker r.add(pool.allocate(31));
263*c8dee2aaSAndroid Build Coastguard Worker }
264*c8dee2aaSAndroid Build Coastguard Worker };
265*c8dee2aaSAndroid Build Coastguard Worker
266*c8dee2aaSAndroid Build Coastguard Worker // Effective prealloc space capacity is >= kMinAllocationSize.
267*c8dee2aaSAndroid Build Coastguard Worker {
268*c8dee2aaSAndroid Build Coastguard Worker auto pool = GrMemoryPool::Make(0, 0);
269*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->preallocSize() == kSmallestMinAllocSize);
270*c8dee2aaSAndroid Build Coastguard Worker }
271*c8dee2aaSAndroid Build Coastguard Worker
272*c8dee2aaSAndroid Build Coastguard Worker // Effective block size capacity >= kMinAllocationSize.
273*c8dee2aaSAndroid Build Coastguard Worker {
274*c8dee2aaSAndroid Build Coastguard Worker auto pool = GrMemoryPool::Make(kSmallestMinAllocSize, kSmallestMinAllocSize / 2);
275*c8dee2aaSAndroid Build Coastguard Worker AutoPoolReleaser r(*pool);
276*c8dee2aaSAndroid Build Coastguard Worker
277*c8dee2aaSAndroid Build Coastguard Worker allocateMemory(*pool, r);
278*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->size() == kSmallestMinAllocSize);
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker
281*c8dee2aaSAndroid Build Coastguard Worker // Pool allocates exactly preallocSize on creation.
282*c8dee2aaSAndroid Build Coastguard Worker {
283*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t kPreallocSize = kSmallestMinAllocSize * 5;
284*c8dee2aaSAndroid Build Coastguard Worker auto pool = GrMemoryPool::Make(kPreallocSize, 0);
285*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->preallocSize() == kPreallocSize);
286*c8dee2aaSAndroid Build Coastguard Worker }
287*c8dee2aaSAndroid Build Coastguard Worker
288*c8dee2aaSAndroid Build Coastguard Worker // Pool allocates exactly minAllocSize when it expands.
289*c8dee2aaSAndroid Build Coastguard Worker {
290*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t kMinAllocSize = kSmallestMinAllocSize * 7;
291*c8dee2aaSAndroid Build Coastguard Worker auto pool = GrMemoryPool::Make(0, kMinAllocSize);
292*c8dee2aaSAndroid Build Coastguard Worker AutoPoolReleaser r(*pool);
293*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->size() == 0);
294*c8dee2aaSAndroid Build Coastguard Worker
295*c8dee2aaSAndroid Build Coastguard Worker allocateMemory(*pool, r);
296*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->size() == kMinAllocSize);
297*c8dee2aaSAndroid Build Coastguard Worker
298*c8dee2aaSAndroid Build Coastguard Worker allocateMemory(*pool, r);
299*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->size() == 2 * kMinAllocSize);
300*c8dee2aaSAndroid Build Coastguard Worker }
301*c8dee2aaSAndroid Build Coastguard Worker
302*c8dee2aaSAndroid Build Coastguard Worker // When asked to allocate amount > minAllocSize, pool allocates larger block
303*c8dee2aaSAndroid Build Coastguard Worker // to accommodate all internal structures.
304*c8dee2aaSAndroid Build Coastguard Worker {
305*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t kMinAllocSize = kSmallestMinAllocSize * 2;
306*c8dee2aaSAndroid Build Coastguard Worker auto pool = GrMemoryPool::Make(kSmallestMinAllocSize, kMinAllocSize);
307*c8dee2aaSAndroid Build Coastguard Worker AutoPoolReleaser r(*pool);
308*c8dee2aaSAndroid Build Coastguard Worker
309*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->size() == 0);
310*c8dee2aaSAndroid Build Coastguard Worker
311*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t hugeSize = 10 * kMinAllocSize;
312*c8dee2aaSAndroid Build Coastguard Worker r.add(pool->allocate(hugeSize));
313*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->size() > hugeSize);
314*c8dee2aaSAndroid Build Coastguard Worker
315*c8dee2aaSAndroid Build Coastguard Worker // Block size allocated to accommodate huge request doesn't include any extra
316*c8dee2aaSAndroid Build Coastguard Worker // space, so next allocation request allocates a new block.
317*c8dee2aaSAndroid Build Coastguard Worker size_t hugeBlockSize = pool->size();
318*c8dee2aaSAndroid Build Coastguard Worker r.add(pool->allocate(0));
319*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, pool->size() == hugeBlockSize + kMinAllocSize);
320*c8dee2aaSAndroid Build Coastguard Worker }
321*c8dee2aaSAndroid Build Coastguard Worker }
322