1 /* 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 11 #include "include/core/SkData.h" 12 #include "include/gpu/GrContextOptions.h" 13 #include "include/private/SkChecksum.h" 14 15 #include <unordered_map> 16 17 namespace 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 */ 25 class MemoryCache : public GrContextOptions::PersistentCache { 26 public: 27 MemoryCache() = default; 28 MemoryCache(const MemoryCache&) = delete; 29 MemoryCache& operator=(const MemoryCache&) = delete; reset()30 void reset() { 31 this->resetCacheStats(); 32 fMap.clear(); 33 } 34 35 sk_sp<SkData> load(const SkData& key) override; 36 void store(const SkData& key, const SkData& data, const SkString& description) override; numCacheMisses()37 int numCacheMisses() const { return fCacheMissCnt; } numCacheStores()38 int numCacheStores() const { return fCacheStoreCnt; } resetCacheStats()39 void resetCacheStats() { 40 fCacheMissCnt = 0; 41 fCacheStoreCnt = 0; 42 } 43 44 void writeShadersToDisk(const char* path, GrBackendApi backend); 45 46 template <typename Fn> foreach(Fn && fn)47 void foreach(Fn&& fn) { 48 for (auto it = fMap.begin(); it != fMap.end(); ++it) { 49 fn(it->first.fKey, it->second.fData, it->second.fDescription, it->second.fHitCount); 50 } 51 } 52 53 private: 54 struct Key { 55 Key() = default; KeyKey56 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 66 struct Value { 67 Value() = default; ValueValue68 Value(const SkData& data, const SkString& description) 69 : fData(SkData::MakeWithCopy(data.data(), data.size())) 70 , fDescription(description) 71 , fHitCount(1) {} 72 Value(const Value& that) = default; 73 Value& operator=(const Value&) = default; 74 75 sk_sp<SkData> fData; 76 SkString fDescription; 77 int fHitCount; 78 }; 79 80 struct Hash { 81 using argument_type = Key; 82 using result_type = uint32_t; operatorHash83 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; 89 int fCacheStoreCnt = 0; 90 std::unordered_map<Key, Value, Hash> fMap; 91 }; 92 93 } // namespace sk_gpu_test 94 95 #endif 96