1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_GR_SHADER_CACHE_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_GR_SHADER_CACHE_H_
7 
8 #include "base/containers/flat_set.h"
9 #include "base/containers/mru_cache.h"
10 #include "base/hash/hash.h"
11 #include "base/memory/memory_pressure_listener.h"
12 #include "base/trace_event/memory_dump_provider.h"
13 #include "gpu/gpu_gles2_export.h"
14 #include "third_party/skia/include/gpu/GrContextOptions.h"
15 
16 namespace gpu {
17 namespace raster {
18 
19 class GPU_GLES2_EXPORT GrShaderCache
20     : public GrContextOptions::PersistentCache,
21       public base::trace_event::MemoryDumpProvider {
22  public:
23   class GPU_GLES2_EXPORT Client {
24    public:
~Client()25     virtual ~Client() {}
26 
27     virtual void StoreShader(const std::string& key,
28                              const std::string& shader) = 0;
29   };
30 
31   class GPU_GLES2_EXPORT ScopedCacheUse {
32    public:
33     ScopedCacheUse(GrShaderCache* cache, int32_t client_id);
34     ~ScopedCacheUse();
35 
36    private:
37     GrShaderCache* cache_;
38   };
39 
40   GrShaderCache(size_t max_cache_size_bytes, Client* client);
41   ~GrShaderCache() override;
42 
43   // GrContextOptions::PersistentCache implementation.
44   sk_sp<SkData> load(const SkData& key) override;
45   void store(const SkData& key, const SkData& data) override;
46 
47   void PopulateCache(const std::string& key, const std::string& data);
48   void CacheClientIdOnDisk(int32_t client_id);
49   void PurgeMemory(
50       base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
51 
52   // base::trace_event::MemoryDumpProvider implementation.
53   bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
54                     base::trace_event::ProcessMemoryDump* pmd) override;
55 
num_cache_entries()56   size_t num_cache_entries() const { return store_.size(); }
curr_size_bytes_for_testing()57   size_t curr_size_bytes_for_testing() const { return curr_size_bytes_; }
58 
59  private:
60   static constexpr int32_t kInvalidClientId = 0;
61 
62   struct CacheKey {
63     explicit CacheKey(sk_sp<SkData> data);
64     CacheKey(CacheKey&& other);
65     CacheKey(const CacheKey& other);
66     CacheKey& operator=(const CacheKey& other);
67     CacheKey& operator=(CacheKey&& other);
68     ~CacheKey();
69 
70     bool operator==(const CacheKey& other) const;
71 
72     sk_sp<SkData> data;
73     size_t hash;
74   };
75 
76   struct CacheData {
77    public:
78     explicit CacheData(sk_sp<SkData> data);
79     CacheData(CacheData&& other);
80     CacheData& operator=(CacheData&& other);
81     ~CacheData();
82 
83     bool operator==(const CacheData& other) const;
84 
85     sk_sp<SkData> data;
86     bool pending_disk_write = true;
87   };
88 
89   struct CacheKeyHash {
operatorCacheKeyHash90     size_t operator()(const CacheKey& key) const { return key.hash; }
91   };
92 
93   using Store = base::HashingMRUCache<CacheKey, CacheData, CacheKeyHash>;
94 
95   void EnforceLimits(size_t size_needed);
96 
97   Store::iterator AddToCache(CacheKey key, CacheData data);
98   template <typename Iterator>
99   void EraseFromCache(Iterator it);
100 
101   void WriteToDisk(const CacheKey& key, CacheData* data);
102 
103   size_t cache_size_limit_;
104   size_t curr_size_bytes_ = 0u;
105   Store store_;
106 
107   Client* const client_;
108   base::flat_set<int32_t> client_ids_to_cache_on_disk_;
109 
110   int32_t current_client_id_ = kInvalidClientId;
111 
112   DISALLOW_COPY_AND_ASSIGN(GrShaderCache);
113 };
114 
115 }  // namespace raster
116 }  // namespace gpu
117 
118 #endif  // GPU_COMMAND_BUFFER_SERVICE_GR_SHADER_CACHE_H_
119