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