/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef MemoryCache_DEFINED #define MemoryCache_DEFINED #include "include/core/SkData.h" #include "include/gpu/GrContextOptions.h" #include "include/private/SkChecksum.h" #include namespace sk_gpu_test { /** * This class can be used to maintain an in memory record of all programs cached by GrContext. * It can be shared by multiple GrContexts so long as those GrContexts are created with the same * options and will have the same GrCaps (e.g. same backend, same GL context creation parameters, * ...). */ class MemoryCache : public GrContextOptions::PersistentCache { public: MemoryCache() = default; MemoryCache(const MemoryCache&) = delete; MemoryCache& operator=(const MemoryCache&) = delete; void reset() { this->resetCacheStats(); fMap.clear(); } sk_sp load(const SkData& key) override; void store(const SkData& key, const SkData& data, const SkString& description) override; int numCacheMisses() const { return fCacheMissCnt; } int numCacheStores() const { return fCacheStoreCnt; } void resetCacheStats() { fCacheMissCnt = 0; fCacheStoreCnt = 0; } void writeShadersToDisk(const char* path, GrBackendApi backend); template void foreach(Fn&& fn) { for (auto it = fMap.begin(); it != fMap.end(); ++it) { fn(it->first.fKey, it->second.fData, it->second.fDescription, it->second.fHitCount); } } private: struct Key { Key() = default; Key(const SkData& key) : fKey(SkData::MakeWithCopy(key.data(), key.size())) {} Key(const Key& that) = default; Key& operator=(const Key&) = default; bool operator==(const Key& that) const { return that.fKey->size() == fKey->size() && !memcmp(fKey->data(), that.fKey->data(), that.fKey->size()); } sk_sp fKey; }; struct Value { Value() = default; Value(const SkData& data, const SkString& description) : fData(SkData::MakeWithCopy(data.data(), data.size())) , fDescription(description) , fHitCount(1) {} Value(const Value& that) = default; Value& operator=(const Value&) = default; sk_sp fData; SkString fDescription; int fHitCount; }; struct Hash { using argument_type = Key; using result_type = uint32_t; uint32_t operator()(const Key& key) const { return key.fKey ? SkOpts::hash_fn(key.fKey->data(), key.fKey->size(), 0) : 0; } }; int fCacheMissCnt = 0; int fCacheStoreCnt = 0; std::unordered_map fMap; }; } // namespace sk_gpu_test #endif