// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_ #define CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_ #include <map> #include <queue> #include <string> #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" #include "content/common/content_export.h" #include "net/disk_cache/disk_cache.h" namespace content { class ShaderDiskCacheEntry; class ShaderDiskReadHelper; class ShaderClearHelper; // ShaderDiskCache is the interface to the on disk cache for // GL shaders. // // While this class is both RefCounted and SupportsWeakPtr // when using this class you should work with the RefCounting. // The WeakPtr is needed interally. class CONTENT_EXPORT ShaderDiskCache : public base::RefCounted<ShaderDiskCache>, public base::SupportsWeakPtr<ShaderDiskCache> { public: void Init(); void set_host_id(int host_id) { host_id_ = host_id; } // Store the |shader| into the cache under |key|. void Cache(const std::string& key, const std::string& shader); // Clear a range of entries. This supports unbounded deletes in either // direction by using null Time values for either |begin_time| or |end_time|. // The return value is a net error code. If this method returns // ERR_IO_PENDING, the |completion_callback| will be invoked when the // operation completes. int Clear( const base::Time begin_time, const base::Time end_time, const net::CompletionCallback& completion_callback); // Sets a callback for when the cache is available. If the cache is // already available the callback will not be called and net::OK is returned. // If the callback is set net::ERR_IO_PENDING is returned and the callback // will be executed when the cache is available. int SetAvailableCallback(const net::CompletionCallback& callback); // Returns the number of elements currently in the cache. int32 Size(); // Set a callback notification for when all current entries have been // written to the cache. // The return value is a net error code. If this method returns // ERR_IO_PENDING, the |callback| will be invoked when all entries have // been written to the cache. int SetCacheCompleteCallback(const net::CompletionCallback& callback); private: friend class base::RefCounted<ShaderDiskCache>; friend class ShaderDiskCacheEntry; friend class ShaderDiskReadHelper; friend class ShaderCacheFactory; explicit ShaderDiskCache(const base::FilePath& cache_path); ~ShaderDiskCache(); void CacheCreatedCallback(int rv); disk_cache::Backend* backend() { return backend_.get(); } void EntryComplete(void* entry); void ReadComplete(); bool cache_available_; int host_id_; base::FilePath cache_path_; bool is_initialized_; net::CompletionCallback available_callback_; net::CompletionCallback cache_complete_callback_; scoped_ptr<disk_cache::Backend> backend_; scoped_refptr<ShaderDiskReadHelper> helper_; std::map<void*, scoped_refptr<ShaderDiskCacheEntry> > entry_map_; DISALLOW_COPY_AND_ASSIGN(ShaderDiskCache); }; // ShaderCacheFactory maintains a cache of ShaderDiskCache objects // so we only create one per profile directory. class CONTENT_EXPORT ShaderCacheFactory { public: static ShaderCacheFactory* GetInstance(); // Clear the shader disk cache for the given |path|. This supports unbounded // deletes in either direction by using null Time values for either // |begin_time| or |end_time|. The |callback| will be executed when the // clear is complete. void ClearByPath(const base::FilePath& path, const base::Time& begin_time, const base::Time& end_time, const base::Closure& callback); // Retrieve the shader disk cache for the provided |client_id|. scoped_refptr<ShaderDiskCache> Get(int32 client_id); // Set the |path| to be used for the disk cache for |client_id|. void SetCacheInfo(int32 client_id, const base::FilePath& path); // Remove the path mapping for |client_id|. void RemoveCacheInfo(int32 client_id); // Set the provided |cache| into the cache map for the given |path|. void AddToCache(const base::FilePath& path, ShaderDiskCache* cache); // Remove the provided |path| from our cache map. void RemoveFromCache(const base::FilePath& path); private: friend struct DefaultSingletonTraits<ShaderCacheFactory>; friend class ShaderClearHelper; ShaderCacheFactory(); ~ShaderCacheFactory(); scoped_refptr<ShaderDiskCache> GetByPath(const base::FilePath& path); void CacheCleared(const base::FilePath& path); typedef std::map<base::FilePath, ShaderDiskCache*> ShaderCacheMap; ShaderCacheMap shader_cache_map_; typedef std::map<int32, base::FilePath> ClientIdToPathMap; ClientIdToPathMap client_id_to_path_map_; typedef std::queue<scoped_refptr<ShaderClearHelper> > ShaderClearQueue; typedef std::map<base::FilePath, ShaderClearQueue> ShaderClearMap; ShaderClearMap shader_clear_map_; DISALLOW_COPY_AND_ASSIGN(ShaderCacheFactory); }; } // namespace content #endif // CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_