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