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