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 virtual 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 virtual 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 virtual 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 179