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#include "Benchmark.h" 10 11#if SK_SUPPORT_GPU 12 13#include "GrGpuResource.h" 14#include "GrGpuResourcePriv.h" 15#include "GrContext.h" 16#include "GrGpu.h" 17#include "GrResourceCache.h" 18#include "SkCanvas.h" 19 20enum { 21 CACHE_SIZE_COUNT = 4096, 22}; 23 24class BenchResource : public GrGpuResource { 25public: 26 BenchResource (GrGpu* gpu) 27 : INHERITED(gpu, kCached_LifeCycle) { 28 this->registerWithCache(); 29 } 30 31 static void ComputeKey(int i, int keyData32Count, GrUniqueKey* key) { 32 static GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 33 GrUniqueKey::Builder builder(key, kDomain, keyData32Count); 34 for (int j = 0; j < keyData32Count; ++j) { 35 builder[j] = i + j; 36 } 37 } 38 39private: 40 size_t onGpuMemorySize() const override { return 100; } 41 typedef GrGpuResource INHERITED; 42}; 43 44static void populate_cache(GrGpu* gpu, int resourceCount, int keyData32Count) { 45 for (int i = 0; i < resourceCount; ++i) { 46 GrUniqueKey key; 47 BenchResource::ComputeKey(i, keyData32Count, &key); 48 GrGpuResource* resource = new BenchResource(gpu); 49 resource->resourcePriv().setUniqueKey(key); 50 resource->unref(); 51 } 52} 53 54class GrResourceCacheBenchAdd : public Benchmark { 55public: 56 GrResourceCacheBenchAdd(int keyData32Count) 57 : fFullName("grresourcecache_add") 58 , fKeyData32Count(keyData32Count) { 59 if (keyData32Count > 1) { 60 fFullName.appendf("_%d", fKeyData32Count); 61 } 62 } 63 64 bool isSuitableFor(Backend backend) override { 65 return backend == kNonRendering_Backend; 66 } 67protected: 68 const char* onGetName() override { 69 return fFullName.c_str(); 70 } 71 72 void onDraw(int loops, SkCanvas* canvas) override { 73 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); 74 if (nullptr == context) { 75 return; 76 } 77 // Set the cache budget to be very large so no purging occurs. 78 context->setResourceCacheLimits(CACHE_SIZE_COUNT, 1 << 30); 79 80 GrResourceCache* cache = context->getResourceCache(); 81 82 // Make sure the cache is empty. 83 cache->purgeAllUnlocked(); 84 SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes()); 85 86 GrGpu* gpu = context->getGpu(); 87 88 for (int i = 0; i < loops; ++i) { 89 populate_cache(gpu, CACHE_SIZE_COUNT, fKeyData32Count); 90 SkASSERT(CACHE_SIZE_COUNT == cache->getResourceCount()); 91 } 92 } 93 94private: 95 SkString fFullName; 96 int fKeyData32Count; 97 typedef Benchmark INHERITED; 98}; 99 100class GrResourceCacheBenchFind : public Benchmark { 101public: 102 GrResourceCacheBenchFind(int keyData32Count) 103 : fFullName("grresourcecache_find") 104 , fKeyData32Count(keyData32Count) { 105 if (keyData32Count > 1) { 106 fFullName.appendf("_%d", fKeyData32Count); 107 } 108 } 109 110 bool isSuitableFor(Backend backend) override { 111 return backend == kNonRendering_Backend; 112 } 113protected: 114 const char* onGetName() override { 115 return fFullName.c_str(); 116 } 117 118 void onDelayedSetup() override { 119 fContext.reset(GrContext::CreateMockContext()); 120 if (!fContext) { 121 return; 122 } 123 // Set the cache budget to be very large so no purging occurs. 124 fContext->setResourceCacheLimits(CACHE_SIZE_COUNT, 1 << 30); 125 126 GrResourceCache* cache = fContext->getResourceCache(); 127 128 // Make sure the cache is empty. 129 cache->purgeAllUnlocked(); 130 SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes()); 131 132 GrGpu* gpu = fContext->getGpu(); 133 134 populate_cache(gpu, CACHE_SIZE_COUNT, fKeyData32Count); 135 } 136 137 void onDraw(int loops, SkCanvas* canvas) override { 138 if (!fContext) { 139 return; 140 } 141 GrResourceCache* cache = fContext->getResourceCache(); 142 SkASSERT(CACHE_SIZE_COUNT == cache->getResourceCount()); 143 for (int i = 0; i < loops; ++i) { 144 for (int k = 0; k < CACHE_SIZE_COUNT; ++k) { 145 GrUniqueKey key; 146 BenchResource::ComputeKey(k, fKeyData32Count, &key); 147 SkAutoTUnref<GrGpuResource> resource(cache->findAndRefUniqueResource(key)); 148 SkASSERT(resource); 149 } 150 } 151 } 152 153private: 154 SkAutoTUnref<GrContext> fContext; 155 SkString fFullName; 156 int fKeyData32Count; 157 typedef Benchmark INHERITED; 158}; 159 160DEF_BENCH( return new GrResourceCacheBenchAdd(1); ) 161#ifdef SK_RELEASE 162// Only on release because on debug the SkTDynamicHash validation is too slow. 163DEF_BENCH( return new GrResourceCacheBenchAdd(2); ) 164DEF_BENCH( return new GrResourceCacheBenchAdd(3); ) 165DEF_BENCH( return new GrResourceCacheBenchAdd(4); ) 166DEF_BENCH( return new GrResourceCacheBenchAdd(5); ) 167DEF_BENCH( return new GrResourceCacheBenchAdd(10); ) 168DEF_BENCH( return new GrResourceCacheBenchAdd(25); ) 169DEF_BENCH( return new GrResourceCacheBenchAdd(54); ) 170DEF_BENCH( return new GrResourceCacheBenchAdd(55); ) 171DEF_BENCH( return new GrResourceCacheBenchAdd(56); ) 172#endif 173 174DEF_BENCH( return new GrResourceCacheBenchFind(1); ) 175#ifdef SK_RELEASE 176DEF_BENCH( return new GrResourceCacheBenchFind(2); ) 177DEF_BENCH( return new GrResourceCacheBenchFind(3); ) 178DEF_BENCH( return new GrResourceCacheBenchFind(4); ) 179DEF_BENCH( return new GrResourceCacheBenchFind(5); ) 180DEF_BENCH( return new GrResourceCacheBenchFind(10); ) 181DEF_BENCH( return new GrResourceCacheBenchFind(25); ) 182DEF_BENCH( return new GrResourceCacheBenchFind(54); ) 183DEF_BENCH( return new GrResourceCacheBenchFind(55); ) 184DEF_BENCH( return new GrResourceCacheBenchFind(56); ) 185#endif 186 187#endif 188