blob: cf7d284e540d73bab327bc22926033d159d3b436 [file] [log] [blame]
Brian Salomon00a5eb82018-07-11 15:32:05 -04001/*
2 * Copyright 2018 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#ifndef MemoryCache_DEFINED
9#define MemoryCache_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkData.h"
12#include "include/gpu/GrContextOptions.h"
13#include "include/private/SkChecksum.h"
Brian Salomon00a5eb82018-07-11 15:32:05 -040014
Hal Canary8a001442018-09-19 11:31:27 -040015#include <unordered_map>
16
Brian Salomon00a5eb82018-07-11 15:32:05 -040017namespace sk_gpu_test {
18
19/**
20 * This class can be used to maintain an in memory record of all programs cached by GrContext.
21 * It can be shared by multiple GrContexts so long as those GrContexts are created with the same
22 * options and will have the same GrCaps (e.g. same backend, same GL context creation parameters,
23 * ...).
24 */
25class MemoryCache : public GrContextOptions::PersistentCache {
26public:
27 MemoryCache() = default;
28 MemoryCache(const MemoryCache&) = delete;
29 MemoryCache& operator=(const MemoryCache&) = delete;
Brian Osman0b8bb882019-04-12 11:47:19 -040030 void reset() {
Brian Osman43f443f2020-06-05 11:11:36 -040031 this->resetCacheStats();
Brian Osman0b8bb882019-04-12 11:47:19 -040032 fMap.clear();
33 }
Brian Salomon00a5eb82018-07-11 15:32:05 -040034
35 sk_sp<SkData> load(const SkData& key) override;
Brian Osmanf0de96f2021-02-26 13:54:11 -050036 void store(const SkData& key, const SkData& data, const SkString& description) override;
Brian Salomon00a5eb82018-07-11 15:32:05 -040037 int numCacheMisses() const { return fCacheMissCnt; }
Brian Osman43f443f2020-06-05 11:11:36 -040038 int numCacheStores() const { return fCacheStoreCnt; }
39 void resetCacheStats() {
40 fCacheMissCnt = 0;
41 fCacheStoreCnt = 0;
42 }
Brian Salomon00a5eb82018-07-11 15:32:05 -040043
Brian Osman5aa11fb2019-04-08 16:40:36 -040044 void writeShadersToDisk(const char* path, GrBackendApi backend);
45
Brian Osman0b8bb882019-04-12 11:47:19 -040046 template <typename Fn>
47 void foreach(Fn&& fn) {
48 for (auto it = fMap.begin(); it != fMap.end(); ++it) {
Brian Osmanf0de96f2021-02-26 13:54:11 -050049 fn(it->first.fKey, it->second.fData, it->second.fDescription, it->second.fHitCount);
Brian Osman0b8bb882019-04-12 11:47:19 -040050 }
51 }
52
Brian Salomon00a5eb82018-07-11 15:32:05 -040053private:
54 struct Key {
55 Key() = default;
56 Key(const SkData& key) : fKey(SkData::MakeWithCopy(key.data(), key.size())) {}
57 Key(const Key& that) = default;
58 Key& operator=(const Key&) = default;
59 bool operator==(const Key& that) const {
60 return that.fKey->size() == fKey->size() &&
61 !memcmp(fKey->data(), that.fKey->data(), that.fKey->size());
62 }
63 sk_sp<const SkData> fKey;
64 };
65
Brian Osman5aa11fb2019-04-08 16:40:36 -040066 struct Value {
67 Value() = default;
Brian Osmanf0de96f2021-02-26 13:54:11 -050068 Value(const SkData& data, const SkString& description)
Brian Osman5aa11fb2019-04-08 16:40:36 -040069 : fData(SkData::MakeWithCopy(data.data(), data.size()))
Brian Osmanf0de96f2021-02-26 13:54:11 -050070 , fDescription(description)
Brian Osman5aa11fb2019-04-08 16:40:36 -040071 , fHitCount(1) {}
72 Value(const Value& that) = default;
73 Value& operator=(const Value&) = default;
74
75 sk_sp<SkData> fData;
Brian Osmanf0de96f2021-02-26 13:54:11 -050076 SkString fDescription;
77 int fHitCount;
Brian Osman5aa11fb2019-04-08 16:40:36 -040078 };
79
Brian Salomon00a5eb82018-07-11 15:32:05 -040080 struct Hash {
81 using argument_type = Key;
82 using result_type = uint32_t;
83 uint32_t operator()(const Key& key) const {
84 return key.fKey ? SkOpts::hash_fn(key.fKey->data(), key.fKey->size(), 0) : 0;
85 }
86 };
87
88 int fCacheMissCnt = 0;
Brian Osman43f443f2020-06-05 11:11:36 -040089 int fCacheStoreCnt = 0;
Brian Osman5aa11fb2019-04-08 16:40:36 -040090 std::unordered_map<Key, Value, Hash> fMap;
Brian Salomon00a5eb82018-07-11 15:32:05 -040091};
92
93} // namespace sk_gpu_test
94
95#endif