blob: d8e63d530a6ce41e349e00f3e5d37d83f256ade5 [file] [log] [blame]
commit-bot@chromium.org644629c2013-11-21 06:21:58 +00001
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
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000186 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000187 GrGpu* gpu = canvas->getGrContext()->getGpu();
188
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000189 for (int i = 0; i < loops; ++i) {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000190 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
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000222 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000223 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
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000228 for (int i = 0; i < loops; ++i) {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000229 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