1 // Copyright (c) 2013 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_IPC_HOST_SHADER_DISK_CACHE_H_ 6 #define GPU_IPC_HOST_SHADER_DISK_CACHE_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <string> 12 #include <unordered_map> 13 14 #include "base/containers/queue.h" 15 #include "base/files/file_path.h" 16 #include "base/macros.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/threading/thread_checker.h" 19 #include "net/base/completion_once_callback.h" 20 #include "net/disk_cache/disk_cache.h" 21 22 namespace gpu { 23 24 class ShaderCacheFactory; 25 class ShaderDiskCacheEntry; 26 class ShaderDiskReadHelper; 27 class ShaderClearHelper; 28 29 // ShaderDiskCache is the interface to the on disk cache for 30 // GL shaders. 31 class ShaderDiskCache : public base::RefCounted<ShaderDiskCache> { 32 public: 33 using ShaderLoadedCallback = 34 base::RepeatingCallback<void(const std::string&, const std::string&)>; 35 set_shader_loaded_callback(const ShaderLoadedCallback & callback)36 void set_shader_loaded_callback(const ShaderLoadedCallback& callback) { 37 shader_loaded_callback_ = callback; 38 } 39 40 // Store the |shader| into the cache under |key|. 41 void Cache(const std::string& key, const std::string& shader); 42 43 // Clear a range of entries. This supports unbounded deletes in either 44 // direction by using null Time values for either |begin_time| or |end_time|. 45 // The return value is a net error code. If this method returns 46 // ERR_IO_PENDING, the |completion_callback| will be invoked when the 47 // operation completes. 48 int Clear(const base::Time begin_time, 49 const base::Time end_time, 50 net::CompletionOnceCallback completion_callback); 51 52 // Sets a callback for when the cache is available. If the cache is 53 // already available the callback will not be called and net::OK is returned. 54 // If the callback is set net::ERR_IO_PENDING is returned and the callback 55 // will be executed when the cache is available. 56 int SetAvailableCallback(net::CompletionOnceCallback callback); 57 58 // Returns the number of elements currently in the cache. 59 int32_t Size(); 60 61 // Set a callback notification for when all current entries have been 62 // written to the cache. 63 // The return value is a net error code. If this method returns 64 // ERR_IO_PENDING, the |callback| will be invoked when all entries have 65 // been written to the cache. 66 int SetCacheCompleteCallback(net::CompletionOnceCallback callback); 67 68 // Returns the size which should be used for the shader disk cache. 69 static size_t CacheSizeBytes(); 70 71 private: 72 friend class base::RefCounted<ShaderDiskCache>; 73 friend class ShaderDiskCacheEntry; 74 friend class ShaderDiskReadHelper; 75 friend class ShaderCacheFactory; 76 77 ShaderDiskCache(ShaderCacheFactory* factory, 78 const base::FilePath& cache_path); 79 ~ShaderDiskCache(); 80 81 void Init(); 82 void CacheCreatedCallback(int rv); 83 backend()84 disk_cache::Backend* backend() { return backend_.get(); } 85 86 void EntryComplete(ShaderDiskCacheEntry* entry); 87 void ReadComplete(); 88 89 ShaderCacheFactory* factory_; 90 bool cache_available_; 91 base::FilePath cache_path_; 92 bool is_initialized_; 93 net::CompletionOnceCallback available_callback_; 94 net::CompletionOnceCallback cache_complete_callback_; 95 ShaderLoadedCallback shader_loaded_callback_; 96 97 std::unique_ptr<disk_cache::Backend> backend_; 98 99 std::unique_ptr<ShaderDiskReadHelper> helper_; 100 std::unordered_map<ShaderDiskCacheEntry*, 101 std::unique_ptr<ShaderDiskCacheEntry>> 102 entries_; 103 104 DISALLOW_COPY_AND_ASSIGN(ShaderDiskCache); 105 }; 106 107 // ShaderCacheFactory maintains a cache of ShaderDiskCache objects 108 // so we only create one per profile directory. 109 class ShaderCacheFactory : public base::ThreadChecker { 110 public: 111 ShaderCacheFactory(); 112 ~ShaderCacheFactory(); 113 114 // Clear the shader disk cache for the given |path|. This supports unbounded 115 // deletes in either direction by using null Time values for either 116 // |begin_time| or |end_time|. The |callback| will be executed when the 117 // clear is complete. 118 void ClearByPath(const base::FilePath& path, 119 const base::Time& begin_time, 120 const base::Time& end_time, 121 base::OnceClosure callback); 122 123 // Same as ClearByPath, but looks up the cache by |client_id|. The |callback| 124 // will be executed when the clear is complete. 125 void ClearByClientId(int32_t client_id, 126 const base::Time& begin_time, 127 const base::Time& end_time, 128 base::OnceClosure callback); 129 130 // Retrieve the shader disk cache for the provided |client_id|. 131 scoped_refptr<ShaderDiskCache> Get(int32_t client_id); 132 133 // Set the |path| to be used for the disk cache for |client_id|. 134 void SetCacheInfo(int32_t client_id, const base::FilePath& path); 135 136 // Remove the path mapping for |client_id|. 137 void RemoveCacheInfo(int32_t client_id); 138 139 // Set the provided |cache| into the cache map for the given |path|. 140 void AddToCache(const base::FilePath& path, ShaderDiskCache* cache); 141 142 // Remove the provided |path| from our cache map. 143 void RemoveFromCache(const base::FilePath& path); 144 145 private: 146 friend class ShaderClearHelper; 147 148 scoped_refptr<ShaderDiskCache> GetByPath(const base::FilePath& path); 149 void CacheCleared(const base::FilePath& path); 150 151 using ShaderCacheMap = std::map<base::FilePath, ShaderDiskCache*>; 152 ShaderCacheMap shader_cache_map_; 153 154 using ClientIdToPathMap = std::map<int32_t, base::FilePath>; 155 ClientIdToPathMap client_id_to_path_map_; 156 157 using ShaderClearQueue = base::queue<std::unique_ptr<ShaderClearHelper>>; 158 using ShaderClearMap = std::map<base::FilePath, ShaderClearQueue>; 159 ShaderClearMap shader_clear_map_; 160 161 DISALLOW_COPY_AND_ASSIGN(ShaderCacheFactory); 162 }; 163 164 } // namespace gpu 165 166 #endif // GPU_IPC_HOST_SHADER_DISK_CACHE_H_ 167