xref: /aosp_15_r20/external/skia/bench/GrResourceCacheBench.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "bench/Benchmark.h"
9 
10 #include "include/core/SkCanvas.h"
11 #include "include/gpu/ganesh/GrDirectContext.h"
12 #include "src/gpu/ganesh/GrDirectContextPriv.h"
13 #include "src/gpu/ganesh/GrGpu.h"
14 #include "src/gpu/ganesh/GrGpuResource.h"
15 #include "src/gpu/ganesh/GrGpuResourcePriv.h"
16 #include "src/gpu/ganesh/GrResourceCache.h"
17 
18 enum {
19     CACHE_SIZE_COUNT = 4096,
20 };
21 
22 class BenchResource : public GrGpuResource {
23 public:
BenchResource(GrGpu * gpu,std::string_view label)24     BenchResource(GrGpu* gpu, std::string_view label)
25         : INHERITED(gpu, label) {
26         this->registerWithCache(skgpu::Budgeted::kYes);
27     }
28 
ComputeKey(int i,int keyData32Count,skgpu::UniqueKey * key)29     static void ComputeKey(int i, int keyData32Count, skgpu::UniqueKey* key) {
30         static skgpu::UniqueKey::Domain kDomain = skgpu::UniqueKey::GenerateDomain();
31         skgpu::UniqueKey::Builder builder(key, kDomain, keyData32Count);
32         for (int j = 0; j < keyData32Count; ++j) {
33             builder[j] = i + j;
34         }
35     }
36 
37 private:
onGpuMemorySize() const38     size_t onGpuMemorySize() const override { return 100; }
onSetLabel()39     void onSetLabel() override{}
getResourceType() const40     const char* getResourceType() const override { return "bench"; }
41     using INHERITED = GrGpuResource;
42 };
43 
populate_cache(GrGpu * gpu,int resourceCount,int keyData32Count)44 static void populate_cache(GrGpu* gpu, int resourceCount, int keyData32Count) {
45     for (int i = 0; i < resourceCount; ++i) {
46         skgpu::UniqueKey key;
47         BenchResource::ComputeKey(i, keyData32Count, &key);
48         GrGpuResource* resource = new BenchResource(gpu, /*label=*/"BenchResource");
49         resource->resourcePriv().setUniqueKey(key);
50         resource->unref();
51     }
52 }
53 
54 class GrResourceCacheBenchAdd : public Benchmark {
55 public:
GrResourceCacheBenchAdd(int keyData32Count)56     GrResourceCacheBenchAdd(int keyData32Count)
57         : fFullName("grresourcecache_add")
58         , fKeyData32Count(keyData32Count) {
59         if (keyData32Count > 1) {
60             fFullName.appendf("_%d", fKeyData32Count);
61         }
62     }
63 
isSuitableFor(Backend backend)64     bool isSuitableFor(Backend backend) override {
65         return backend == Backend::kNonRendering;
66     }
67 protected:
onGetName()68     const char* onGetName() override {
69         return fFullName.c_str();
70     }
71 
onDraw(int loops,SkCanvas * canvas)72     void onDraw(int loops, SkCanvas* canvas) override {
73         sk_sp<GrDirectContext> context(GrDirectContext::MakeMock(nullptr));
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->priv().getResourceCache();
81 
82         // Make sure the cache is empty.
83         cache->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
84         SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
85 
86         GrGpu* gpu = context->priv().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 
94 private:
95     SkString fFullName;
96     int fKeyData32Count;
97     using INHERITED = Benchmark;
98 };
99 
100 class GrResourceCacheBenchFind : public Benchmark {
101 public:
GrResourceCacheBenchFind(int keyData32Count)102     GrResourceCacheBenchFind(int keyData32Count)
103         : fFullName("grresourcecache_find")
104         , fKeyData32Count(keyData32Count) {
105         if (keyData32Count > 1) {
106             fFullName.appendf("_%d", fKeyData32Count);
107         }
108     }
109 
isSuitableFor(Backend backend)110     bool isSuitableFor(Backend backend) override {
111         return backend == Backend::kNonRendering;
112     }
113 protected:
onGetName()114     const char* onGetName() override {
115         return fFullName.c_str();
116     }
117 
onDelayedSetup()118     void onDelayedSetup() override {
119         fContext = GrDirectContext::MakeMock(nullptr);
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->priv().getResourceCache();
127 
128         // Make sure the cache is empty.
129         cache->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
130         SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
131 
132         GrGpu* gpu = fContext->priv().getGpu();
133 
134         populate_cache(gpu, CACHE_SIZE_COUNT, fKeyData32Count);
135     }
136 
onDraw(int loops,SkCanvas * canvas)137     void onDraw(int loops, SkCanvas* canvas) override {
138         if (!fContext) {
139             return;
140         }
141         GrResourceCache* cache = fContext->priv().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                 skgpu::UniqueKey key;
146                 BenchResource::ComputeKey(k, fKeyData32Count, &key);
147                 sk_sp<GrGpuResource> resource(cache->findAndRefUniqueResource(key));
148                 SkASSERT(resource);
149             }
150         }
151     }
152 
153 private:
154     sk_sp<GrDirectContext> fContext;
155     SkString fFullName;
156     int fKeyData32Count;
157     using INHERITED = Benchmark;
158 };
159 
160 DEF_BENCH( return new GrResourceCacheBenchAdd(1); )
161 #ifdef SK_RELEASE
162 // Only on release because on debug the SkTDynamicHash validation is too slow.
163 DEF_BENCH( return new GrResourceCacheBenchAdd(2); )
164 DEF_BENCH( return new GrResourceCacheBenchAdd(3); )
165 DEF_BENCH( return new GrResourceCacheBenchAdd(4); )
166 DEF_BENCH( return new GrResourceCacheBenchAdd(5); )
167 DEF_BENCH( return new GrResourceCacheBenchAdd(10); )
168 DEF_BENCH( return new GrResourceCacheBenchAdd(25); )
169 DEF_BENCH( return new GrResourceCacheBenchAdd(54); )
170 DEF_BENCH( return new GrResourceCacheBenchAdd(55); )
171 DEF_BENCH( return new GrResourceCacheBenchAdd(56); )
172 #endif
173 
174 DEF_BENCH( return new GrResourceCacheBenchFind(1); )
175 #ifdef SK_RELEASE
176 DEF_BENCH( return new GrResourceCacheBenchFind(2); )
177 DEF_BENCH( return new GrResourceCacheBenchFind(3); )
178 DEF_BENCH( return new GrResourceCacheBenchFind(4); )
179 DEF_BENCH( return new GrResourceCacheBenchFind(5); )
180 DEF_BENCH( return new GrResourceCacheBenchFind(10); )
181 DEF_BENCH( return new GrResourceCacheBenchFind(25); )
182 DEF_BENCH( return new GrResourceCacheBenchFind(54); )
183 DEF_BENCH( return new GrResourceCacheBenchFind(55); )
184 DEF_BENCH( return new GrResourceCacheBenchFind(56); )
185 #endif
186