1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef MemoryCache_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define MemoryCache_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextOptions.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkChecksum.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include <unordered_map> 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker namespace sk_gpu_test { 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker /** 20*c8dee2aaSAndroid Build Coastguard Worker * This class can be used to maintain an in memory record of all programs cached by GrContext. 21*c8dee2aaSAndroid Build Coastguard Worker * It can be shared by multiple GrContexts so long as those GrContexts are created with the same 22*c8dee2aaSAndroid Build Coastguard Worker * options and will have the same GrCaps (e.g. same backend, same GL context creation parameters, 23*c8dee2aaSAndroid Build Coastguard Worker * ...). 24*c8dee2aaSAndroid Build Coastguard Worker */ 25*c8dee2aaSAndroid Build Coastguard Worker class MemoryCache : public GrContextOptions::PersistentCache { 26*c8dee2aaSAndroid Build Coastguard Worker public: 27*c8dee2aaSAndroid Build Coastguard Worker MemoryCache() = default; 28*c8dee2aaSAndroid Build Coastguard Worker MemoryCache(const MemoryCache&) = delete; 29*c8dee2aaSAndroid Build Coastguard Worker MemoryCache& operator=(const MemoryCache&) = delete; reset()30*c8dee2aaSAndroid Build Coastguard Worker void reset() { 31*c8dee2aaSAndroid Build Coastguard Worker this->resetCacheStats(); 32*c8dee2aaSAndroid Build Coastguard Worker fMap.clear(); 33*c8dee2aaSAndroid Build Coastguard Worker } 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> load(const SkData& key) override; 36*c8dee2aaSAndroid Build Coastguard Worker void store(const SkData& key, const SkData& data, const SkString& description) override; numCacheMisses()37*c8dee2aaSAndroid Build Coastguard Worker int numCacheMisses() const { return fCacheMissCnt; } numCacheStores()38*c8dee2aaSAndroid Build Coastguard Worker int numCacheStores() const { return fCacheStoreCnt; } resetCacheStats()39*c8dee2aaSAndroid Build Coastguard Worker void resetCacheStats() { 40*c8dee2aaSAndroid Build Coastguard Worker fCacheMissCnt = 0; 41*c8dee2aaSAndroid Build Coastguard Worker fCacheStoreCnt = 0; 42*c8dee2aaSAndroid Build Coastguard Worker } 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker void writeShadersToDisk(const char* path, GrBackendApi backend); 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker template <typename Fn> foreach(Fn && fn)47*c8dee2aaSAndroid Build Coastguard Worker void foreach(Fn&& fn) { 48*c8dee2aaSAndroid Build Coastguard Worker for (auto it = fMap.begin(); it != fMap.end(); ++it) { 49*c8dee2aaSAndroid Build Coastguard Worker fn(it->first.fKey, it->second.fData, it->second.fDescription, it->second.fHitCount); 50*c8dee2aaSAndroid Build Coastguard Worker } 51*c8dee2aaSAndroid Build Coastguard Worker } 52*c8dee2aaSAndroid Build Coastguard Worker 53*c8dee2aaSAndroid Build Coastguard Worker private: 54*c8dee2aaSAndroid Build Coastguard Worker struct Key { 55*c8dee2aaSAndroid Build Coastguard Worker Key() = default; KeyKey56*c8dee2aaSAndroid Build Coastguard Worker Key(const SkData& key) : fKey(SkData::MakeWithCopy(key.data(), key.size())) {} 57*c8dee2aaSAndroid Build Coastguard Worker Key(const Key& that) = default; 58*c8dee2aaSAndroid Build Coastguard Worker Key& operator=(const Key&) = default; 59*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const Key& that) const { 60*c8dee2aaSAndroid Build Coastguard Worker return that.fKey->size() == fKey->size() && 61*c8dee2aaSAndroid Build Coastguard Worker !memcmp(fKey->data(), that.fKey->data(), that.fKey->size()); 62*c8dee2aaSAndroid Build Coastguard Worker } 63*c8dee2aaSAndroid Build Coastguard Worker sk_sp<const SkData> fKey; 64*c8dee2aaSAndroid Build Coastguard Worker }; 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker struct Value { 67*c8dee2aaSAndroid Build Coastguard Worker Value() = default; ValueValue68*c8dee2aaSAndroid Build Coastguard Worker Value(const SkData& data, const SkString& description) 69*c8dee2aaSAndroid Build Coastguard Worker : fData(SkData::MakeWithCopy(data.data(), data.size())) 70*c8dee2aaSAndroid Build Coastguard Worker , fDescription(description) 71*c8dee2aaSAndroid Build Coastguard Worker , fHitCount(1) {} 72*c8dee2aaSAndroid Build Coastguard Worker Value(const Value& that) = default; 73*c8dee2aaSAndroid Build Coastguard Worker Value& operator=(const Value&) = default; 74*c8dee2aaSAndroid Build Coastguard Worker 75*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> fData; 76*c8dee2aaSAndroid Build Coastguard Worker SkString fDescription; 77*c8dee2aaSAndroid Build Coastguard Worker int fHitCount; 78*c8dee2aaSAndroid Build Coastguard Worker }; 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker struct Hash { 81*c8dee2aaSAndroid Build Coastguard Worker using argument_type = Key; 82*c8dee2aaSAndroid Build Coastguard Worker using result_type = uint32_t; operatorHash83*c8dee2aaSAndroid Build Coastguard Worker uint32_t operator()(const Key& key) const { 84*c8dee2aaSAndroid Build Coastguard Worker return key.fKey ? SkChecksum::Hash32(key.fKey->data(), key.fKey->size()) : 0; 85*c8dee2aaSAndroid Build Coastguard Worker } 86*c8dee2aaSAndroid Build Coastguard Worker }; 87*c8dee2aaSAndroid Build Coastguard Worker 88*c8dee2aaSAndroid Build Coastguard Worker int fCacheMissCnt = 0; 89*c8dee2aaSAndroid Build Coastguard Worker int fCacheStoreCnt = 0; 90*c8dee2aaSAndroid Build Coastguard Worker std::unordered_map<Key, Value, Hash> fMap; 91*c8dee2aaSAndroid Build Coastguard Worker }; 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker } // namespace sk_gpu_test 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker #endif 96