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