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