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 20struct 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}; 28GrMemoryPool A::gBenchPool(10 * (1 << 10), 10 * (1 << 10)); 29 30/** 31 * This benchmark creates and deletes objects in stack order 32 */ 33class GrMemoryPoolBenchStack : public Benchmark { 34public: 35 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { 36 return backend == kNonRendering_Backend; 37 } 38 39protected: 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 78private: 79 typedef Benchmark INHERITED; 80}; 81 82struct 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}; 90GrMemoryPool B::gBenchPool(10 * (1 << 10), 10 * (1 << 10)); 91 92/** 93 * This benchmark creates objects and deletes them in random order 94 */ 95class GrMemoryPoolBenchRandom : public Benchmark { 96public: 97 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { 98 return backend == kNonRendering_Backend; 99 } 100 101protected: 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 123private: 124 typedef Benchmark INHERITED; 125}; 126 127struct 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}; 135GrMemoryPool C::gBenchPool(10 * (1 << 10), 10 * (1 << 10)); 136 137/** 138 * This benchmark creates objects and deletes them in queue order 139 */ 140class GrMemoryPoolBenchQueue : public Benchmark { 141 enum { 142 M = 4 * (1 << 10), 143 }; 144public: 145 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { 146 return backend == kNonRendering_Backend; 147 } 148 149protected: 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 168private: 169 typedef Benchmark INHERITED; 170}; 171 172/////////////////////////////////////////////////////////////////////////////// 173 174DEF_BENCH( return new GrMemoryPoolBenchStack(); ) 175DEF_BENCH( return new GrMemoryPoolBenchRandom(); ) 176DEF_BENCH( return new GrMemoryPoolBenchQueue(); ) 177 178#endif 179