320ff00f1404c2e2c5da63bbf2630e44b4532d79
[platform/upstream/libSkiaSharp.git] / bench / GrMemoryPoolBench.cpp
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 // This tests a Gr class
9 #if SK_SUPPORT_GPU
10
11 #include "Benchmark.h"
12 #include "GrMemoryPool.h"
13 #include "SkRandom.h"
14 #include "SkTDArray.h"
15 #include "SkTemplates.h"
16
17 // change this to 0 to compare GrMemoryPool to default new / delete
18 #define OVERRIDE_NEW    1
19
20 struct A {
21     int gStuff[10];
22 #if OVERRIDE_NEW
23     void* operator new (size_t size) { return gBenchPool.allocate(size); }
24     void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
25 #endif
26     static GrMemoryPool gBenchPool;
27 };
28 GrMemoryPool A::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
29
30 /**
31  * This benchmark creates and deletes objects in stack order
32  */
33 class GrMemoryPoolBenchStack : public Benchmark {
34 public:
35     bool isSuitableFor(Backend backend) SK_OVERRIDE {
36         return backend == kNonRendering_Backend;
37     }
38
39 protected:
40     virtual const char* onGetName() {
41         return "grmemorypool_stack";
42     }
43
44     virtual void onDraw(const int loops, SkCanvas*) {
45         SkRandom r;
46         enum {
47             kMaxObjects = 4 * (1 << 10),
48         };
49         A* objects[kMaxObjects];
50
51         // We delete if a random [-1, 1] fixed pt is < the thresh. Otherwise,
52         // we allocate. We start allocate-biased and ping-pong to delete-biased
53         SkFixed delThresh = -SK_FixedHalf;
54         const int kSwitchThreshPeriod = loops / (2 * kMaxObjects);
55         int s = 0;
56
57         int count = 0;
58         for (int i = 0; i < loops; i++, ++s) {
59             if (kSwitchThreshPeriod == s) {
60                 delThresh = -delThresh;
61                 s = 0;
62             }
63             SkFixed del = r.nextSFixed1();
64             if (count &&
65                 (kMaxObjects == count || del < delThresh)) {
66                 delete objects[count-1];
67                 --count;
68             } else {
69                 objects[count] = new A;
70                 ++count;
71             }
72         }
73         for (int i = 0; i < count; ++i) {
74             delete objects[i];
75         }
76     }
77
78 private:
79     typedef Benchmark INHERITED;
80 };
81
82 struct B {
83     int gStuff[10];
84 #if OVERRIDE_NEW
85     void* operator new (size_t size) { return gBenchPool.allocate(size); }
86     void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
87 #endif
88     static GrMemoryPool gBenchPool;
89 };
90 GrMemoryPool B::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
91
92 /**
93  * This benchmark creates objects and deletes them in random order
94  */
95 class GrMemoryPoolBenchRandom : public Benchmark {
96 public:
97     bool isSuitableFor(Backend backend) SK_OVERRIDE {
98         return backend == kNonRendering_Backend;
99     }
100
101 protected:
102     virtual const char* onGetName() {
103         return "grmemorypool_random";
104     }
105
106     virtual void onDraw(const int loops, SkCanvas*) {
107         SkRandom r;
108         enum {
109             kMaxObjects = 4 * (1 << 10),
110         };
111         SkAutoTDelete<B> objects[kMaxObjects];
112
113         for (int i = 0; i < loops; i++) {
114             uint32_t idx = r.nextRangeU(0, kMaxObjects-1);
115             if (NULL == objects[idx].get()) {
116                 objects[idx].reset(new B);
117             } else {
118                 objects[idx].free();
119             }
120         }
121     }
122
123 private:
124     typedef Benchmark INHERITED;
125 };
126
127 struct C {
128     int gStuff[10];
129 #if OVERRIDE_NEW
130     void* operator new (size_t size) { return gBenchPool.allocate(size); }
131     void operator delete (void* mem) { if (mem) { return gBenchPool.release(mem); } }
132 #endif
133     static GrMemoryPool gBenchPool;
134 };
135 GrMemoryPool C::gBenchPool(10 * (1 << 10), 10 * (1 << 10));
136
137 /**
138  * This benchmark creates objects and deletes them in queue order
139  */
140 class GrMemoryPoolBenchQueue : public Benchmark {
141     enum {
142         M = 4 * (1 << 10),
143     };
144 public:
145     bool isSuitableFor(Backend backend) SK_OVERRIDE {
146         return backend == kNonRendering_Backend;
147     }
148
149 protected:
150     virtual const char* onGetName() {
151         return "grmemorypool_queue";
152     }
153
154     virtual void onDraw(const int loops, SkCanvas*) {
155         SkRandom r;
156         C* objects[M];
157         for (int i = 0; i < loops; i++) {
158             uint32_t count = r.nextRangeU(0, M-1);
159             for (uint32_t i = 0; i < count; i++) {
160                 objects[i] = new C;
161             }
162             for (uint32_t i = 0; i < count; i++) {
163                 delete objects[i];
164             }
165         }
166     }
167
168 private:
169     typedef Benchmark INHERITED;
170 };
171
172 ///////////////////////////////////////////////////////////////////////////////
173
174 DEF_BENCH( return new GrMemoryPoolBenchStack(); )
175 DEF_BENCH( return new GrMemoryPoolBenchRandom(); )
176 DEF_BENCH( return new GrMemoryPoolBenchQueue(); )
177
178 #endif