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