3 * Copyright 2013 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
11 #include "Benchmark.h"
12 #include "GrGpuResource.h"
13 #include "GrContext.h"
14 #include "GrResourceCache.h"
15 #include "GrStencilBuffer.h"
16 #include "GrTexture.h"
20 CACHE_SIZE_COUNT = 2048,
21 CACHE_SIZE_BYTES = 2 * 1024 * 1024,
24 class StencilResource : public GrGpuResource {
26 SK_DECLARE_INST_COUNT(StencilResource);
27 StencilResource(GrGpu* gpu, int id)
28 : INHERITED(gpu, false)
32 virtual ~StencilResource() { this->release(); }
34 virtual size_t gpuMemorySize() const SK_OVERRIDE {
35 return 100 + ((fID % 1 == 0) ? -5 : 6);
38 static GrResourceKey ComputeKey(int width, int height, int sampleCnt) {
39 return GrStencilBuffer::ComputeKey(width, height, sampleCnt);
45 typedef GrGpuResource INHERITED;
48 class TextureResource : public GrGpuResource {
50 SK_DECLARE_INST_COUNT(TextureResource);
51 TextureResource(GrGpu* gpu, int id)
52 : INHERITED(gpu, false)
56 virtual ~TextureResource() { this->release(); }
58 virtual size_t gpuMemorySize() const SK_OVERRIDE {
59 return 100 + ((fID % 1 == 0) ? -40 : 33);
62 static GrResourceKey ComputeKey(const GrTextureDesc& desc) {
63 return GrTextureImpl::ComputeScratchKey(desc);
69 typedef GrGpuResource INHERITED;
72 static void get_stencil(int i, int* w, int* h, int* s) {
75 *s = i % 1 == 0 ? 0 : 4;
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;
87 static void populate_cache(GrResourceCache* cache, GrGpu* gpu, int resourceCount) {
88 for (int i = 0; i < resourceCount; ++i) {
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);
98 for (int i = 0; i < resourceCount; ++i) {
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);
109 static void check_cache_contents_or_die(GrResourceCache* cache, int k) {
110 // Benchmark find calls that succeed.
113 get_texture_desc(k, &desc);
114 GrResourceKey key = TextureResource::ComputeKey(desc);
115 GrGpuResource* item = cache->find(key);
117 SkFAIL("cache add does not work as expected");
120 if (static_cast<TextureResource*>(item)->fID != k) {
121 SkFAIL("cache add does not work as expected");
127 get_stencil(k, &w, &h, &s);
128 GrResourceKey key = StencilResource::ComputeKey(w, h, s);
129 GrGpuResource* item = cache->find(key);
131 SkFAIL("cache add does not work as expected");
134 if (static_cast<TextureResource*>(item)->fID != k) {
135 SkFAIL("cache add does not work as expected");
140 // Benchmark also find calls that always fail.
143 get_texture_desc(k, &desc);
145 GrResourceKey key = TextureResource::ComputeKey(desc);
146 GrGpuResource* item = cache->find(key);
148 SkFAIL("cache add does not work as expected");
154 get_stencil(k, &w, &h, &s);
156 GrResourceKey key = StencilResource::ComputeKey(w, h, s);
157 GrGpuResource* item = cache->find(key);
159 SkFAIL("cache add does not work as expected");
165 class GrResourceCacheBenchAdd : public Benchmark {
167 RESOURCE_COUNT = CACHE_SIZE_COUNT / 2,
168 DUPLICATE_COUNT = CACHE_SIZE_COUNT / 4,
172 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
173 return backend == kGPU_Backend;
177 virtual const char* onGetName() SK_OVERRIDE {
178 return "grresourcecache_add";
181 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
182 GrGpu* gpu = canvas->getGrContext()->getGpu();
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);
189 // Check that cache works.
190 for (int k = 0; k < RESOURCE_COUNT; k += 33) {
191 check_cache_contents_or_die(&cache, k);
193 cache.purgeAllUnlocked();
198 typedef Benchmark INHERITED;
201 class GrResourceCacheBenchFind : public Benchmark {
203 RESOURCE_COUNT = (CACHE_SIZE_COUNT / 2) - 100,
204 DUPLICATE_COUNT = 100
208 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
209 return backend == kGPU_Backend;
213 virtual const char* onGetName() SK_OVERRIDE {
214 return "grresourcecache_find";
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);
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);
231 typedef Benchmark INHERITED;
234 DEF_BENCH( return new GrResourceCacheBenchAdd(); )
235 DEF_BENCH( return new GrResourceCacheBenchFind(); )