1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2013 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "bench/Benchmark.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h"
11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResource.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResourcePriv.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrResourceCache.h"
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_cienum {
19cb93a386Sopenharmony_ci    CACHE_SIZE_COUNT = 4096,
20cb93a386Sopenharmony_ci};
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_ciclass BenchResource : public GrGpuResource {
23cb93a386Sopenharmony_cipublic:
24cb93a386Sopenharmony_ci    BenchResource (GrGpu* gpu)
25cb93a386Sopenharmony_ci        : INHERITED(gpu) {
26cb93a386Sopenharmony_ci        this->registerWithCache(SkBudgeted::kYes);
27cb93a386Sopenharmony_ci    }
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci    static void ComputeKey(int i, int keyData32Count, GrUniqueKey* key) {
30cb93a386Sopenharmony_ci        static GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
31cb93a386Sopenharmony_ci        GrUniqueKey::Builder builder(key, kDomain, keyData32Count);
32cb93a386Sopenharmony_ci        for (int j = 0; j < keyData32Count; ++j) {
33cb93a386Sopenharmony_ci            builder[j] = i + j;
34cb93a386Sopenharmony_ci        }
35cb93a386Sopenharmony_ci    }
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ciprivate:
38cb93a386Sopenharmony_ci    size_t onGpuMemorySize() const override { return 100; }
39cb93a386Sopenharmony_ci    const char* getResourceType() const override { return "bench"; }
40cb93a386Sopenharmony_ci    using INHERITED = GrGpuResource;
41cb93a386Sopenharmony_ci};
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_cistatic void populate_cache(GrGpu* gpu, int resourceCount, int keyData32Count) {
44cb93a386Sopenharmony_ci    for (int i = 0; i < resourceCount; ++i) {
45cb93a386Sopenharmony_ci        GrUniqueKey key;
46cb93a386Sopenharmony_ci        BenchResource::ComputeKey(i, keyData32Count, &key);
47cb93a386Sopenharmony_ci        GrGpuResource* resource = new BenchResource(gpu);
48cb93a386Sopenharmony_ci        resource->resourcePriv().setUniqueKey(key);
49cb93a386Sopenharmony_ci        resource->unref();
50cb93a386Sopenharmony_ci    }
51cb93a386Sopenharmony_ci}
52cb93a386Sopenharmony_ci
53cb93a386Sopenharmony_ciclass GrResourceCacheBenchAdd : public Benchmark {
54cb93a386Sopenharmony_cipublic:
55cb93a386Sopenharmony_ci    GrResourceCacheBenchAdd(int keyData32Count)
56cb93a386Sopenharmony_ci        : fFullName("grresourcecache_add")
57cb93a386Sopenharmony_ci        , fKeyData32Count(keyData32Count) {
58cb93a386Sopenharmony_ci        if (keyData32Count > 1) {
59cb93a386Sopenharmony_ci            fFullName.appendf("_%d", fKeyData32Count);
60cb93a386Sopenharmony_ci        }
61cb93a386Sopenharmony_ci    }
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_ci    bool isSuitableFor(Backend backend) override {
64cb93a386Sopenharmony_ci        return backend == kNonRendering_Backend;
65cb93a386Sopenharmony_ci    }
66cb93a386Sopenharmony_ciprotected:
67cb93a386Sopenharmony_ci    const char* onGetName() override {
68cb93a386Sopenharmony_ci        return fFullName.c_str();
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci
71cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
72cb93a386Sopenharmony_ci        sk_sp<GrDirectContext> context(GrDirectContext::MakeMock(nullptr));
73cb93a386Sopenharmony_ci        if (nullptr == context) {
74cb93a386Sopenharmony_ci            return;
75cb93a386Sopenharmony_ci        }
76cb93a386Sopenharmony_ci        // Set the cache budget to be very large so no purging occurs.
77cb93a386Sopenharmony_ci        context->setResourceCacheLimits(CACHE_SIZE_COUNT, 1 << 30);
78cb93a386Sopenharmony_ci
79cb93a386Sopenharmony_ci        GrResourceCache* cache = context->priv().getResourceCache();
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ci        // Make sure the cache is empty.
82cb93a386Sopenharmony_ci        cache->purgeUnlockedResources();
83cb93a386Sopenharmony_ci        SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci        GrGpu* gpu = context->priv().getGpu();
86cb93a386Sopenharmony_ci
87cb93a386Sopenharmony_ci        for (int i = 0; i < loops; ++i) {
88cb93a386Sopenharmony_ci            populate_cache(gpu, CACHE_SIZE_COUNT, fKeyData32Count);
89cb93a386Sopenharmony_ci            SkASSERT(CACHE_SIZE_COUNT == cache->getResourceCount());
90cb93a386Sopenharmony_ci        }
91cb93a386Sopenharmony_ci    }
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ciprivate:
94cb93a386Sopenharmony_ci    SkString fFullName;
95cb93a386Sopenharmony_ci    int fKeyData32Count;
96cb93a386Sopenharmony_ci    using INHERITED = Benchmark;
97cb93a386Sopenharmony_ci};
98cb93a386Sopenharmony_ci
99cb93a386Sopenharmony_ciclass GrResourceCacheBenchFind : public Benchmark {
100cb93a386Sopenharmony_cipublic:
101cb93a386Sopenharmony_ci    GrResourceCacheBenchFind(int keyData32Count)
102cb93a386Sopenharmony_ci        : fFullName("grresourcecache_find")
103cb93a386Sopenharmony_ci        , fKeyData32Count(keyData32Count) {
104cb93a386Sopenharmony_ci        if (keyData32Count > 1) {
105cb93a386Sopenharmony_ci            fFullName.appendf("_%d", fKeyData32Count);
106cb93a386Sopenharmony_ci        }
107cb93a386Sopenharmony_ci    }
108cb93a386Sopenharmony_ci
109cb93a386Sopenharmony_ci    bool isSuitableFor(Backend backend) override {
110cb93a386Sopenharmony_ci        return backend == kNonRendering_Backend;
111cb93a386Sopenharmony_ci    }
112cb93a386Sopenharmony_ciprotected:
113cb93a386Sopenharmony_ci    const char* onGetName() override {
114cb93a386Sopenharmony_ci        return fFullName.c_str();
115cb93a386Sopenharmony_ci    }
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci    void onDelayedSetup() override {
118cb93a386Sopenharmony_ci        fContext = GrDirectContext::MakeMock(nullptr);
119cb93a386Sopenharmony_ci        if (!fContext) {
120cb93a386Sopenharmony_ci            return;
121cb93a386Sopenharmony_ci        }
122cb93a386Sopenharmony_ci        // Set the cache budget to be very large so no purging occurs.
123cb93a386Sopenharmony_ci        fContext->setResourceCacheLimits(CACHE_SIZE_COUNT, 1 << 30);
124cb93a386Sopenharmony_ci
125cb93a386Sopenharmony_ci        GrResourceCache* cache = fContext->priv().getResourceCache();
126cb93a386Sopenharmony_ci
127cb93a386Sopenharmony_ci        // Make sure the cache is empty.
128cb93a386Sopenharmony_ci        cache->purgeUnlockedResources();
129cb93a386Sopenharmony_ci        SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci        GrGpu* gpu = fContext->priv().getGpu();
132cb93a386Sopenharmony_ci
133cb93a386Sopenharmony_ci        populate_cache(gpu, CACHE_SIZE_COUNT, fKeyData32Count);
134cb93a386Sopenharmony_ci    }
135cb93a386Sopenharmony_ci
136cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
137cb93a386Sopenharmony_ci        if (!fContext) {
138cb93a386Sopenharmony_ci            return;
139cb93a386Sopenharmony_ci        }
140cb93a386Sopenharmony_ci        GrResourceCache* cache = fContext->priv().getResourceCache();
141cb93a386Sopenharmony_ci        SkASSERT(CACHE_SIZE_COUNT == cache->getResourceCount());
142cb93a386Sopenharmony_ci        for (int i = 0; i < loops; ++i) {
143cb93a386Sopenharmony_ci            for (int k = 0; k < CACHE_SIZE_COUNT; ++k) {
144cb93a386Sopenharmony_ci                GrUniqueKey key;
145cb93a386Sopenharmony_ci                BenchResource::ComputeKey(k, fKeyData32Count, &key);
146cb93a386Sopenharmony_ci                sk_sp<GrGpuResource> resource(cache->findAndRefUniqueResource(key));
147cb93a386Sopenharmony_ci                SkASSERT(resource);
148cb93a386Sopenharmony_ci            }
149cb93a386Sopenharmony_ci        }
150cb93a386Sopenharmony_ci    }
151cb93a386Sopenharmony_ci
152cb93a386Sopenharmony_ciprivate:
153cb93a386Sopenharmony_ci    sk_sp<GrDirectContext> fContext;
154cb93a386Sopenharmony_ci    SkString fFullName;
155cb93a386Sopenharmony_ci    int fKeyData32Count;
156cb93a386Sopenharmony_ci    using INHERITED = Benchmark;
157cb93a386Sopenharmony_ci};
158cb93a386Sopenharmony_ci
159cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(1); )
160cb93a386Sopenharmony_ci#ifdef SK_RELEASE
161cb93a386Sopenharmony_ci// Only on release because on debug the SkTDynamicHash validation is too slow.
162cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(2); )
163cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(3); )
164cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(4); )
165cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(5); )
166cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(10); )
167cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(25); )
168cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(54); )
169cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(55); )
170cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchAdd(56); )
171cb93a386Sopenharmony_ci#endif
172cb93a386Sopenharmony_ci
173cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(1); )
174cb93a386Sopenharmony_ci#ifdef SK_RELEASE
175cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(2); )
176cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(3); )
177cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(4); )
178cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(5); )
179cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(10); )
180cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(25); )
181cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(54); )
182cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(55); )
183cb93a386Sopenharmony_ciDEF_BENCH( return new GrResourceCacheBenchFind(56); )
184cb93a386Sopenharmony_ci#endif
185