12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <queue>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/singleton.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/content_export.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/disk_cache/disk_cache.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShaderDiskCacheEntry;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShaderDiskReadHelper;
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ShaderClearHelper;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShaderDiskCache is the interface to the on disk cache for
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// GL shaders.
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// While this class is both RefCounted and SupportsWeakPtr
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// when using this class you should work with the RefCounting.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The WeakPtr is needed interally.
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class CONTENT_EXPORT ShaderDiskCache
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public base::RefCounted<ShaderDiskCache>,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public base::SupportsWeakPtr<ShaderDiskCache> {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Init();
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_host_id(int host_id) { host_id_ = host_id; }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Store the |shader| into the cache under |key|.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Cache(const std::string& key, const std::string& shader);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clear a range of entries. This supports unbounded deletes in either
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // direction by using null Time values for either |begin_time| or |end_time|.
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The return value is a net error code. If this method returns
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // ERR_IO_PENDING, the |completion_callback| will be invoked when the
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // operation completes.
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int Clear(
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::Time begin_time,
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::Time end_time,
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::CompletionCallback& completion_callback);
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sets a callback for when the cache is available. If the cache is
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // already available the callback will not be called and net::OK is returned.
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If the callback is set net::ERR_IO_PENDING is returned and the callback
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // will be executed when the cache is available.
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int SetAvailableCallback(const net::CompletionCallback& callback);
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns the number of elements currently in the cache.
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32 Size();
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set a callback notification for when all current entries have been
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // written to the cache.
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The return value is a net error code. If this method returns
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // ERR_IO_PENDING, the |callback| will be invoked when all entries have
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // been written to the cache.
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int SetCacheCompleteCallback(const net::CompletionCallback& callback);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class base::RefCounted<ShaderDiskCache>;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class ShaderDiskCacheEntry;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class ShaderDiskReadHelper;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class ShaderCacheFactory;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit ShaderDiskCache(const base::FilePath& cache_path);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~ShaderDiskCache();
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CacheCreatedCallback(int rv);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  disk_cache::Backend* backend() { return backend_.get(); }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void EntryComplete(void* entry);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ReadComplete();
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool cache_available_;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int host_id_;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath cache_path_;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_initialized_;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::CompletionCallback available_callback_;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::CompletionCallback cache_complete_callback_;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<disk_cache::Backend> backend_;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<ShaderDiskReadHelper> helper_;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<void*, scoped_refptr<ShaderDiskCacheEntry> > entry_map_;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ShaderDiskCache);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShaderCacheFactory maintains a cache of ShaderDiskCache objects
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// so we only create one per profile directory.
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class CONTENT_EXPORT ShaderCacheFactory {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static ShaderCacheFactory* GetInstance();
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clear the shader disk cache for the given |path|. This supports unbounded
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // deletes in either direction by using null Time values for either
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |begin_time| or |end_time|. The |callback| will be executed when the
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // clear is complete.
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ClearByPath(const base::FilePath& path,
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   const base::Time& begin_time,
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   const base::Time& end_time,
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   const base::Closure& callback);
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Retrieve the shader disk cache for the provided |client_id|.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<ShaderDiskCache> Get(int32 client_id);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set the |path| to be used for the disk cache for |client_id|.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetCacheInfo(int32 client_id, const base::FilePath& path);
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Remove the path mapping for |client_id|.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RemoveCacheInfo(int32 client_id);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set the provided |cache| into the cache map for the given |path|.
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddToCache(const base::FilePath& path, ShaderDiskCache* cache);
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Remove the provided |path| from our cache map.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RemoveFromCache(const base::FilePath& path);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend struct DefaultSingletonTraits<ShaderCacheFactory>;
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class ShaderClearHelper;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShaderCacheFactory();
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~ShaderCacheFactory();
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<ShaderDiskCache> GetByPath(const base::FilePath& path);
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CacheCleared(const base::FilePath& path);
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<base::FilePath, ShaderDiskCache*> ShaderCacheMap;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShaderCacheMap shader_cache_map_;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<int32, base::FilePath> ClientIdToPathMap;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClientIdToPathMap client_id_to_path_map_;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef std::queue<scoped_refptr<ShaderClearHelper> > ShaderClearQueue;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef std::map<base::FilePath, ShaderClearQueue> ShaderClearMap;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShaderClearMap shader_clear_map_;
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ShaderCacheFactory);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
155