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 "GrMemoryPool.h" 12 #include "SkBenchmark.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 namespace { 21 struct A { 22 int gStuff[10]; 23 #if OVERRIDE_NEW 24 void* operator new (size_t size) { return gPool.allocate(size); } 25 void operator delete (void* mem) { if (mem) { return gPool.release(mem); } } 26 #endif 27 static GrMemoryPool gPool; 28 }; 29 GrMemoryPool A::gPool(10 * (1 << 10), 10 * (1 << 10)); 30 } 31 32 33 /** 34 * This benchmark creates and deletes objects in stack order 35 */ 36 class GrMemoryPoolBenchStack : public SkBenchmark { 37 enum { 38 N = SkBENCHLOOP(1 * (1 << 20)), 39 }; 40 public: 41 GrMemoryPoolBenchStack(void* param) : INHERITED(param) { 42 fIsRendering = false; 43 } 44 protected: 45 virtual const char* onGetName() { 46 return "grmemorypool_stack"; 47 } 48 49 virtual void onDraw(SkCanvas*) { 50 SkRandom r; 51 enum { 52 kMaxObjects = 4 * (1 << 10), 53 }; 54 A* objects[kMaxObjects]; 55 56 // We delete if a random [-1, 1] fixed pt is < the thresh. Otherwise, 57 // we allocate. We start allocate-biased and ping-pong to delete-biased 58 SkFixed delThresh = -SK_FixedHalf; 59 enum { 60 kSwitchThreshPeriod = N / (2 * kMaxObjects), 61 }; 62 int s = 0; 63 64 int count = 0; 65 for (int i = 0; i < N; i++, ++s) { 66 if (kSwitchThreshPeriod == s) { 67 delThresh = -delThresh; 68 s = 0; 69 } 70 SkFixed del = r.nextSFixed1(); 71 if (count && 72 (kMaxObjects == count || del < delThresh)) { 73 delete objects[count-1]; 74 --count; 75 } else { 76 objects[count] = new A; 77 ++count; 78 } 79 } 80 for (int i = 0; i < count; ++i) { 81 delete objects[i]; 82 } 83 } 84 85 private: 86 typedef SkBenchmark INHERITED; 87 }; 88 89 /** 90 * This benchmark creates objects and deletes them in random order 91 */ 92 class GrMemoryPoolBenchRandom : public SkBenchmark { 93 enum { 94 N = SkBENCHLOOP(1 * (1 << 20)), 95 }; 96 public: 97 GrMemoryPoolBenchRandom(void* param) : INHERITED(param) { 98 fIsRendering = false; 99 } 100 protected: 101 virtual const char* onGetName() { 102 return "grmemorypool_random"; 103 } 104 105 virtual void onDraw(SkCanvas*) { 106 SkRandom r; 107 enum { 108 kMaxObjects = 4 * (1 << 10), 109 }; 110 SkAutoTDelete<A> objects[kMaxObjects]; 111 112 for (int i = 0; i < N; i++) { 113 uint32_t idx = r.nextRangeU(0, kMaxObjects-1); 114 if (NULL == objects[idx].get()) { 115 objects[idx].reset(new A); 116 } else { 117 objects[idx].free(); 118 } 119 } 120 } 121 122 private: 123 typedef SkBenchmark INHERITED; 124 }; 125 126 /** 127 * This benchmark creates objects and deletes them in queue order 128 */ 129 class GrMemoryPoolBenchQueue : public SkBenchmark { 130 enum { 131 N = SkBENCHLOOP((1 << 8)), 132 M = SkBENCHLOOP(4 * (1 << 10)), 133 }; 134 public: 135 GrMemoryPoolBenchQueue(void* param) : INHERITED(param) { 136 fIsRendering = false; 137 } 138 protected: 139 virtual const char* onGetName() { 140 return "grmemorypool_queue"; 141 } 142 143 virtual void onDraw(SkCanvas*) { 144 SkRandom r; 145 A* objects[M]; 146 for (int i = 0; i < N; i++) { 147 uint32_t count = r.nextRangeU(0, M-1); 148 for (uint32_t i = 0; i < count; i++) { 149 objects[i] = new A; 150 } 151 for (uint32_t i = 0; i < count; i++) { 152 delete objects[i]; 153 } 154 } 155 } 156 157 private: 158 typedef SkBenchmark INHERITED; 159 }; 160 161 /////////////////////////////////////////////////////////////////////////////// 162 163 static SkBenchmark* Fact1(void* p) { return new GrMemoryPoolBenchStack(p); } 164 static SkBenchmark* Fact2(void* p) { return new GrMemoryPoolBenchRandom(p); } 165 static SkBenchmark* Fact3(void* p) { return new GrMemoryPoolBenchQueue(p); } 166 167 static BenchRegistry gReg01(Fact1); 168 static BenchRegistry gReg02(Fact2); 169 static BenchRegistry gReg03(Fact3); 170 171 #endif 172