GrResourceCacheBench.cpp revision 644629c1c7913a43ced172b98d56e0f471bc348b
1 2/* 3 * Copyright 2013 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9#if SK_SUPPORT_GPU 10 11#include "GrContext.h" 12#include "GrResource.h" 13#include "GrResourceCache.h" 14#include "GrStencilBuffer.h" 15#include "GrTexture.h" 16#include "SkBenchmark.h" 17#include "SkCanvas.h" 18 19enum { 20 CACHE_SIZE_COUNT = 2048, 21 CACHE_SIZE_BYTES = 2 * 1024 * 1024, 22}; 23 24class StencilResource : public GrResource { 25public: 26 SK_DECLARE_INST_COUNT(StencilResource); 27 StencilResource(GrGpu* gpu, int id) 28 : INHERITED(gpu, false), 29 fID(id) { 30 } 31 ~StencilResource() { 32 this->release(); 33 } 34 35 virtual size_t sizeInBytes() const SK_OVERRIDE { 36 return 100 + ((fID % 1 == 0) ? -5 : 6); 37 } 38 39 static GrResourceKey ComputeKey(int width, int height, int sampleCnt) { 40 return GrStencilBuffer::ComputeKey(width, height, sampleCnt); 41 } 42 43 int fID; 44 45private: 46 typedef GrResource INHERITED; 47}; 48 49class TextureResource : public GrResource { 50public: 51 SK_DECLARE_INST_COUNT(TextureResource); 52 TextureResource(GrGpu* gpu, int id) 53 : INHERITED(gpu, false), 54 fID(id) { 55 } 56 ~TextureResource() { 57 this->release(); 58 } 59 60 virtual size_t sizeInBytes() const SK_OVERRIDE { 61 return 100 + ((fID % 1 == 0) ? -40 : 33); 62 } 63 64 static GrResourceKey ComputeKey(const GrTextureDesc& desc) { 65 return GrTexture::ComputeScratchKey(desc); 66 } 67 68 int fID; 69 70private: 71 typedef GrResource INHERITED; 72}; 73 74SK_DEFINE_INST_COUNT(StencilResource) 75SK_DEFINE_INST_COUNT(TextureResource) 76 77static void get_stencil(int i, int* w, int* h, int* s) { 78 *w = i % 1024; 79 *h = i * 2 % 1024; 80 *s = i % 1 == 0 ? 0 : 4; 81} 82 83static void get_texture_desc(int i, GrTextureDesc* desc) { 84 desc->fFlags = kRenderTarget_GrTextureFlagBit | 85 kNoStencil_GrTextureFlagBit; 86 desc->fWidth = i % 1024; 87 desc->fHeight = i * 2 % 1024; 88 desc->fConfig = static_cast<GrPixelConfig>(i % (kLast_GrPixelConfig + 1)); 89 desc->fSampleCnt = i % 1 == 0 ? 0 : 4; 90} 91 92static void populate_cache(GrResourceCache* cache, GrGpu* gpu, int resourceCount) { 93 for (int i = 0; i < resourceCount; ++i) { 94 int w, h, s; 95 get_stencil(i, &w, &h, &s); 96 GrResourceKey key = GrStencilBuffer::ComputeKey(w, h, s); 97 GrResource* resource = SkNEW_ARGS(StencilResource, (gpu, i)); 98 cache->purgeAsNeeded(1, resource->sizeInBytes()); 99 cache->addResource(key, resource); 100 resource->unref(); 101 } 102 103 for (int i = 0; i < resourceCount; ++i) { 104 GrTextureDesc desc; 105 get_texture_desc(i, &desc); 106 GrResourceKey key = TextureResource::ComputeKey(desc); 107 GrResource* resource = SkNEW_ARGS(TextureResource, (gpu, i)); 108 cache->purgeAsNeeded(1, resource->sizeInBytes()); 109 cache->addResource(key, resource); 110 resource->unref(); 111 } 112} 113 114static void check_cache_contents_or_die(GrResourceCache* cache, int k) { 115 // Benchmark find calls that succeed. 116 { 117 GrTextureDesc desc; 118 get_texture_desc(k, &desc); 119 GrResourceKey key = TextureResource::ComputeKey(desc); 120 GrResource* item = cache->find(key); 121 if (NULL == item) { 122 GrCrash("cache add does not work as expected"); 123 return; 124 } 125 if (static_cast<TextureResource*>(item)->fID != k) { 126 GrCrash("cache add does not work as expected"); 127 return; 128 } 129 } 130 { 131 int w, h, s; 132 get_stencil(k, &w, &h, &s); 133 GrResourceKey key = StencilResource::ComputeKey(w, h, s); 134 GrResource* item = cache->find(key); 135 if (NULL == item) { 136 GrCrash("cache add does not work as expected"); 137 return; 138 } 139 if (static_cast<TextureResource*>(item)->fID != k) { 140 GrCrash("cache add does not work as expected"); 141 return; 142 } 143 } 144 145 // Benchmark also find calls that always fail. 146 { 147 GrTextureDesc desc; 148 get_texture_desc(k, &desc); 149 desc.fHeight |= 1; 150 GrResourceKey key = TextureResource::ComputeKey(desc); 151 GrResource* item = cache->find(key); 152 if (NULL != item) { 153 GrCrash("cache add does not work as expected"); 154 return; 155 } 156 } 157 { 158 int w, h, s; 159 get_stencil(k, &w, &h, &s); 160 h |= 1; 161 GrResourceKey key = StencilResource::ComputeKey(w, h, s); 162 GrResource* item = cache->find(key); 163 if (NULL != item) { 164 GrCrash("cache add does not work as expected"); 165 return; 166 } 167 } 168} 169 170class GrResourceCacheBenchAdd : public SkBenchmark { 171 enum { 172 RESOURCE_COUNT = CACHE_SIZE_COUNT / 2, 173 DUPLICATE_COUNT = CACHE_SIZE_COUNT / 4, 174 }; 175 176public: 177 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { 178 return backend == kGPU_Backend; 179 } 180 181protected: 182 virtual const char* onGetName() SK_OVERRIDE { 183 return "grresourcecache_add"; 184 } 185 186 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 187 GrGpu* gpu = canvas->getGrContext()->getGpu(); 188 189 for (int i = 0; i < this->getLoops(); ++i) { 190 GrResourceCache cache(CACHE_SIZE_COUNT, CACHE_SIZE_BYTES); 191 populate_cache(&cache, gpu, DUPLICATE_COUNT); 192 populate_cache(&cache, gpu, RESOURCE_COUNT); 193 194 // Check that cache works. 195 for (int k = 0; k < RESOURCE_COUNT; k += 33) { 196 check_cache_contents_or_die(&cache, k); 197 } 198 cache.purgeAllUnlocked(); 199 } 200 } 201 202private: 203 typedef SkBenchmark INHERITED; 204}; 205 206class GrResourceCacheBenchFind : public SkBenchmark { 207 enum { 208 RESOURCE_COUNT = (CACHE_SIZE_COUNT / 2) - 100, 209 DUPLICATE_COUNT = 100 210 }; 211 212public: 213 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { 214 return backend == kGPU_Backend; 215 } 216 217protected: 218 virtual const char* onGetName() SK_OVERRIDE { 219 return "grresourcecache_find"; 220 } 221 222 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 223 GrGpu* gpu = canvas->getGrContext()->getGpu(); 224 GrResourceCache cache(CACHE_SIZE_COUNT, CACHE_SIZE_BYTES); 225 populate_cache(&cache, gpu, DUPLICATE_COUNT); 226 populate_cache(&cache, gpu, RESOURCE_COUNT); 227 228 for (int i = 0; i < this->getLoops(); ++i) { 229 for (int k = 0; k < RESOURCE_COUNT; ++k) { 230 check_cache_contents_or_die(&cache, k); 231 } 232 } 233 } 234 235private: 236 typedef SkBenchmark INHERITED; 237}; 238 239DEF_BENCH( return new GrResourceCacheBenchAdd(); ) 240DEF_BENCH( return new GrResourceCacheBenchFind(); ) 241 242#endif 243