Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: content/browser/gpu/shader_disk_cache.cc

Issue 2472473002: gpu shader cache: Clarify lifetime/ownership/threadiness of objects. (Closed)
Patch Set: . Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/gpu/shader_disk_cache.h" 5 #include "content/browser/gpu/shader_disk_cache.h"
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/memory/ptr_util.h"
8 #include "base/threading/thread_checker.h" 9 #include "base/threading/thread_checker.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "gpu/command_buffer/common/constants.h" 10 #include "gpu/command_buffer/common/constants.h"
11 #include "net/base/cache_type.h" 11 #include "net/base/cache_type.h"
12 #include "net/base/io_buffer.h" 12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
14 14
15 namespace content { 15 namespace content {
16 16
17 namespace { 17 namespace {
18 18
19 static const base::FilePath::CharType kGpuCachePath[] = 19 static const base::FilePath::CharType kGpuCachePath[] =
20 FILE_PATH_LITERAL("GPUCache"); 20 FILE_PATH_LITERAL("GPUCache");
21 21
22 void EntryCloser(disk_cache::Entry* entry) { 22 static ShaderCacheFactory* factory_instance = nullptr;
23 entry->Close();
24 }
25
26 void FreeDiskCacheIterator(
27 std::unique_ptr<disk_cache::Backend::Iterator> iterator) {}
28 23
29 } // namespace 24 } // namespace
30 25
31 // ShaderDiskCacheEntry handles the work of caching/updating the cached 26 // ShaderDiskCacheEntry handles the work of caching/updating the cached
32 // shaders. 27 // shaders.
33 class ShaderDiskCacheEntry 28 class ShaderDiskCacheEntry : public base::ThreadChecker {
34 : public base::ThreadChecker,
35 public base::RefCounted<ShaderDiskCacheEntry> {
36 public: 29 public:
37 ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache, 30 ShaderDiskCacheEntry(ShaderDiskCache* cache,
38 const std::string& key, 31 const std::string& key,
39 const std::string& shader); 32 const std::string& shader);
33 ~ShaderDiskCacheEntry();
34
40 void Cache(); 35 void Cache();
41 36
42 private: 37 private:
43 friend class base::RefCounted<ShaderDiskCacheEntry>;
44
45 enum OpType { 38 enum OpType {
46 TERMINATE,
47 OPEN_ENTRY, 39 OPEN_ENTRY,
48 WRITE_DATA, 40 WRITE_DATA,
49 CREATE_ENTRY, 41 CREATE_ENTRY,
50 }; 42 };
51 43
52 ~ShaderDiskCacheEntry();
53
54 void OnOpComplete(int rv); 44 void OnOpComplete(int rv);
55 45
56 int OpenCallback(int rv); 46 int OpenCallback(int rv);
57 int WriteCallback(int rv); 47 int WriteCallback(int rv);
58 int IOComplete(int rv); 48 int IOComplete(int rv);
59 49
60 base::WeakPtr<ShaderDiskCache> cache_; 50 ShaderDiskCache* cache_;
61 OpType op_type_; 51 OpType op_type_;
62 std::string key_; 52 std::string key_;
63 std::string shader_; 53 std::string shader_;
64 disk_cache::Entry* entry_; 54 disk_cache::Entry* entry_;
55 base::WeakPtrFactory<ShaderDiskCacheEntry> weak_ptr_factory_;
65 56
66 DISALLOW_COPY_AND_ASSIGN(ShaderDiskCacheEntry); 57 DISALLOW_COPY_AND_ASSIGN(ShaderDiskCacheEntry);
67 }; 58 };
68 59
69 // ShaderDiskReadHelper is used to load all of the cached shaders from the 60 // ShaderDiskReadHelper is used to load all of the cached shaders from the
70 // disk cache and send to the memory cache. 61 // disk cache and send to the memory cache.
71 class ShaderDiskReadHelper 62 class ShaderDiskReadHelper : public base::ThreadChecker {
72 : public base::ThreadChecker,
73 public base::RefCounted<ShaderDiskReadHelper> {
74 public: 63 public:
75 using ShaderLoadedCallback = ShaderDiskCache::ShaderLoadedCallback; 64 using ShaderLoadedCallback = ShaderDiskCache::ShaderLoadedCallback;
76 ShaderDiskReadHelper(base::WeakPtr<ShaderDiskCache> cache, 65 ShaderDiskReadHelper(ShaderDiskCache* cache,
77 const ShaderLoadedCallback& callback); 66 const ShaderLoadedCallback& callback);
67 ~ShaderDiskReadHelper();
68
78 void LoadCache(); 69 void LoadCache();
79 70
80 private: 71 private:
81 friend class base::RefCounted<ShaderDiskReadHelper>;
82
83 enum OpType { 72 enum OpType {
84 TERMINATE, 73 TERMINATE,
85 OPEN_NEXT, 74 OPEN_NEXT,
86 OPEN_NEXT_COMPLETE, 75 OPEN_NEXT_COMPLETE,
87 READ_COMPLETE, 76 READ_COMPLETE,
88 ITERATION_FINISHED 77 ITERATION_FINISHED
89 }; 78 };
90 79
91 80
92 ~ShaderDiskReadHelper();
93
94 void OnOpComplete(int rv); 81 void OnOpComplete(int rv);
95 82
96 int OpenNextEntry(); 83 int OpenNextEntry();
97 int OpenNextEntryComplete(int rv); 84 int OpenNextEntryComplete(int rv);
98 int ReadComplete(int rv); 85 int ReadComplete(int rv);
99 int IterationComplete(int rv); 86 int IterationComplete(int rv);
100 87
101 base::WeakPtr<ShaderDiskCache> cache_; 88 ShaderDiskCache* cache_;
102 ShaderLoadedCallback shader_loaded_callback_; 89 ShaderLoadedCallback shader_loaded_callback_;
103 OpType op_type_; 90 OpType op_type_;
104 std::unique_ptr<disk_cache::Backend::Iterator> iter_; 91 std::unique_ptr<disk_cache::Backend::Iterator> iter_;
105 scoped_refptr<net::IOBufferWithSize> buf_; 92 scoped_refptr<net::IOBufferWithSize> buf_;
106 disk_cache::Entry* entry_; 93 disk_cache::Entry* entry_;
94 base::WeakPtrFactory<ShaderDiskReadHelper> weak_ptr_factory_;
107 95
108 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper); 96 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper);
109 }; 97 };
110 98
111 class ShaderClearHelper 99 class ShaderClearHelper : public base::RefCounted<ShaderClearHelper>,
112 : public base::RefCounted<ShaderClearHelper>, 100 public base::SupportsWeakPtr<ShaderClearHelper>,
113 public base::SupportsWeakPtr<ShaderClearHelper> { 101 public base::ThreadChecker {
114 public: 102 public:
115 ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache, 103 ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
116 const base::FilePath& path, 104 const base::FilePath& path,
117 const base::Time& delete_begin, 105 const base::Time& delete_begin,
118 const base::Time& delete_end, 106 const base::Time& delete_end,
119 const base::Closure& callback); 107 const base::Closure& callback);
120 void Clear(); 108 void Clear();
121 109
122 private: 110 private:
123 friend class base::RefCounted<ShaderClearHelper>; 111 friend class base::RefCounted<ShaderClearHelper>;
(...skipping 11 matching lines...) Expand all
135 scoped_refptr<ShaderDiskCache> cache_; 123 scoped_refptr<ShaderDiskCache> cache_;
136 OpType op_type_; 124 OpType op_type_;
137 base::FilePath path_; 125 base::FilePath path_;
138 base::Time delete_begin_; 126 base::Time delete_begin_;
139 base::Time delete_end_; 127 base::Time delete_end_;
140 base::Closure callback_; 128 base::Closure callback_;
141 129
142 DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper); 130 DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper);
143 }; 131 };
144 132
145 ShaderDiskCacheEntry::ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache, 133 ////////////////////////////////////////////////////////////////////////////////
134 // ShaderDiskCacheEntry
135
136 ShaderDiskCacheEntry::ShaderDiskCacheEntry(ShaderDiskCache* cache,
146 const std::string& key, 137 const std::string& key,
147 const std::string& shader) 138 const std::string& shader)
148 : cache_(cache), 139 : cache_(cache),
149 op_type_(OPEN_ENTRY), 140 op_type_(OPEN_ENTRY),
150 key_(key), 141 key_(key),
151 shader_(shader), 142 shader_(shader),
152 entry_(NULL) { 143 entry_(nullptr),
153 } 144 weak_ptr_factory_(this) {}
154 145
155 ShaderDiskCacheEntry::~ShaderDiskCacheEntry() { 146 ShaderDiskCacheEntry::~ShaderDiskCacheEntry() {
147 DCHECK(CalledOnValidThread());
156 if (entry_) 148 if (entry_)
157 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 149 entry_->Close();
158 base::Bind(&EntryCloser, entry_));
159 } 150 }
160 151
161 void ShaderDiskCacheEntry::Cache() { 152 void ShaderDiskCacheEntry::Cache() {
162 DCHECK(CalledOnValidThread()); 153 DCHECK(CalledOnValidThread());
163 if (!cache_.get())
164 return;
165
166 int rv = cache_->backend()->OpenEntry( 154 int rv = cache_->backend()->OpenEntry(
167 key_, 155 key_, &entry_, base::Bind(&ShaderDiskCacheEntry::OnOpComplete,
168 &entry_, 156 weak_ptr_factory_.GetWeakPtr()));
169 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this));
170 if (rv != net::ERR_IO_PENDING) 157 if (rv != net::ERR_IO_PENDING)
171 OnOpComplete(rv); 158 OnOpComplete(rv);
172 } 159 }
173 160
174 void ShaderDiskCacheEntry::OnOpComplete(int rv) { 161 void ShaderDiskCacheEntry::OnOpComplete(int rv) {
175 DCHECK(CalledOnValidThread()); 162 DCHECK(CalledOnValidThread());
176 if (!cache_.get())
177 return;
178
179 do { 163 do {
180 switch (op_type_) { 164 switch (op_type_) {
181 case OPEN_ENTRY: 165 case OPEN_ENTRY:
182 rv = OpenCallback(rv); 166 rv = OpenCallback(rv);
183 break; 167 break;
184 case CREATE_ENTRY: 168 case CREATE_ENTRY:
185 rv = WriteCallback(rv); 169 rv = WriteCallback(rv);
186 break; 170 break;
187 case WRITE_DATA: 171 case WRITE_DATA:
188 rv = IOComplete(rv); 172 rv = IOComplete(rv);
189 break; 173 break;
190 case TERMINATE:
191 rv = net::ERR_IO_PENDING; // break the loop.
192 break;
193 default:
194 NOTREACHED(); // Invalid op_type_ provided.
195 break;
196 } 174 }
197 } while (rv != net::ERR_IO_PENDING); 175 } while (rv != net::ERR_IO_PENDING);
198 } 176 }
199 177
200 int ShaderDiskCacheEntry::OpenCallback(int rv) { 178 int ShaderDiskCacheEntry::OpenCallback(int rv) {
201 DCHECK(CalledOnValidThread()); 179 DCHECK(CalledOnValidThread());
202 // Called through OnOpComplete, so we know |cache_| is valid.
203 if (rv == net::OK) { 180 if (rv == net::OK) {
204 cache_->backend()->OnExternalCacheHit(key_); 181 cache_->backend()->OnExternalCacheHit(key_);
205 cache_->EntryComplete(this); 182 cache_->EntryComplete(this);
206 op_type_ = TERMINATE; 183 return net::ERR_IO_PENDING;
piman 2016/11/02 18:11:15 I'm not a huge fan of this transformation, because
sadrul 2016/11/02 19:24:53 I have reverted this part of the code. Instead of
207 return rv;
208 } 184 }
209 185
210 op_type_ = CREATE_ENTRY; 186 op_type_ = CREATE_ENTRY;
211 return cache_->backend()->CreateEntry( 187 return cache_->backend()->CreateEntry(
212 key_, 188 key_, &entry_, base::Bind(&ShaderDiskCacheEntry::OnOpComplete,
213 &entry_, 189 weak_ptr_factory_.GetWeakPtr()));
214 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this));
215 } 190 }
216 191
217 int ShaderDiskCacheEntry::WriteCallback(int rv) { 192 int ShaderDiskCacheEntry::WriteCallback(int rv) {
218 DCHECK(CalledOnValidThread()); 193 DCHECK(CalledOnValidThread());
219 // Called through OnOpComplete, so we know |cache_| is valid.
220 if (rv != net::OK) { 194 if (rv != net::OK) {
221 LOG(ERROR) << "Failed to create shader cache entry: " << rv; 195 LOG(ERROR) << "Failed to create shader cache entry: " << rv;
222 cache_->EntryComplete(this); 196 cache_->EntryComplete(this);
223 op_type_ = TERMINATE; 197 return net::ERR_IO_PENDING;
224 return rv;
225 } 198 }
226 199
227 op_type_ = WRITE_DATA; 200 op_type_ = WRITE_DATA;
228 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_); 201 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_);
229 return entry_->WriteData( 202 return entry_->WriteData(1, 0, io_buf.get(), shader_.length(),
230 1, 203 base::Bind(&ShaderDiskCacheEntry::OnOpComplete,
231 0, 204 weak_ptr_factory_.GetWeakPtr()),
232 io_buf.get(), 205 false);
233 shader_.length(),
234 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this),
235 false);
236 } 206 }
237 207
238 int ShaderDiskCacheEntry::IOComplete(int rv) { 208 int ShaderDiskCacheEntry::IOComplete(int rv) {
239 DCHECK(CalledOnValidThread()); 209 DCHECK(CalledOnValidThread());
240 // Called through OnOpComplete, so we know |cache_| is valid.
241 cache_->EntryComplete(this); 210 cache_->EntryComplete(this);
242 op_type_ = TERMINATE; 211 return net::ERR_IO_PENDING;
243 return rv;
244 } 212 }
245 213
246 ShaderDiskReadHelper::ShaderDiskReadHelper(base::WeakPtr<ShaderDiskCache> cache, 214 ////////////////////////////////////////////////////////////////////////////////
215 // ShaderDiskReadHelper
216
217 ShaderDiskReadHelper::ShaderDiskReadHelper(ShaderDiskCache* cache,
247 const ShaderLoadedCallback& callback) 218 const ShaderLoadedCallback& callback)
248 : cache_(cache), 219 : cache_(cache),
249 shader_loaded_callback_(callback), 220 shader_loaded_callback_(callback),
250 op_type_(OPEN_NEXT), 221 op_type_(OPEN_NEXT),
251 buf_(NULL), 222 buf_(NULL),
252 entry_(NULL) {} 223 entry_(NULL),
224 weak_ptr_factory_(this) {}
225
226 ShaderDiskReadHelper::~ShaderDiskReadHelper() {
227 DCHECK(CalledOnValidThread());
228 if (entry_)
229 entry_->Close();
230 iter_ = nullptr;
231 }
253 232
254 void ShaderDiskReadHelper::LoadCache() { 233 void ShaderDiskReadHelper::LoadCache() {
255 DCHECK(CalledOnValidThread()); 234 DCHECK(CalledOnValidThread());
256 if (!cache_.get())
257 return;
258 OnOpComplete(net::OK); 235 OnOpComplete(net::OK);
259 } 236 }
260 237
261 void ShaderDiskReadHelper::OnOpComplete(int rv) { 238 void ShaderDiskReadHelper::OnOpComplete(int rv) {
262 DCHECK(CalledOnValidThread()); 239 DCHECK(CalledOnValidThread());
263 if (!cache_.get())
264 return;
265
266 do { 240 do {
267 switch (op_type_) { 241 switch (op_type_) {
268 case OPEN_NEXT: 242 case OPEN_NEXT:
269 rv = OpenNextEntry(); 243 rv = OpenNextEntry();
270 break; 244 break;
271 case OPEN_NEXT_COMPLETE: 245 case OPEN_NEXT_COMPLETE:
272 rv = OpenNextEntryComplete(rv); 246 rv = OpenNextEntryComplete(rv);
273 break; 247 break;
274 case READ_COMPLETE: 248 case READ_COMPLETE:
275 rv = ReadComplete(rv); 249 rv = ReadComplete(rv);
276 break; 250 break;
277 case ITERATION_FINISHED: 251 case ITERATION_FINISHED:
278 rv = IterationComplete(rv); 252 rv = IterationComplete(rv);
279 break; 253 break;
280 case TERMINATE: 254 case TERMINATE:
281 cache_->ReadComplete(); 255 cache_->ReadComplete();
282 rv = net::ERR_IO_PENDING; // break the loop 256 rv = net::ERR_IO_PENDING; // break the loop
283 break; 257 break;
284 default: 258 default:
285 NOTREACHED(); // Invalid state for read helper 259 NOTREACHED(); // Invalid state for read helper
286 rv = net::ERR_FAILED; 260 rv = net::ERR_FAILED;
287 break; 261 break;
288 } 262 }
289 } while (rv != net::ERR_IO_PENDING); 263 } while (rv != net::ERR_IO_PENDING);
290 } 264 }
291 265
292 int ShaderDiskReadHelper::OpenNextEntry() { 266 int ShaderDiskReadHelper::OpenNextEntry() {
293 DCHECK(CalledOnValidThread()); 267 DCHECK(CalledOnValidThread());
294 // Called through OnOpComplete, so we know |cache_| is valid.
295 op_type_ = OPEN_NEXT_COMPLETE; 268 op_type_ = OPEN_NEXT_COMPLETE;
296 if (!iter_) 269 if (!iter_)
297 iter_ = cache_->backend()->CreateIterator(); 270 iter_ = cache_->backend()->CreateIterator();
298 return iter_->OpenNextEntry( 271 return iter_->OpenNextEntry(&entry_,
299 &entry_, base::Bind(&ShaderDiskReadHelper::OnOpComplete, this)); 272 base::Bind(&ShaderDiskReadHelper::OnOpComplete,
273 weak_ptr_factory_.GetWeakPtr()));
300 } 274 }
301 275
302 int ShaderDiskReadHelper::OpenNextEntryComplete(int rv) { 276 int ShaderDiskReadHelper::OpenNextEntryComplete(int rv) {
303 DCHECK(CalledOnValidThread()); 277 DCHECK(CalledOnValidThread());
304 // Called through OnOpComplete, so we know |cache_| is valid.
305 if (rv == net::ERR_FAILED) { 278 if (rv == net::ERR_FAILED) {
306 iter_.reset(); 279 iter_.reset();
307 op_type_ = ITERATION_FINISHED; 280 op_type_ = ITERATION_FINISHED;
308 return net::OK; 281 return net::OK;
309 } 282 }
310 283
311 if (rv < 0) 284 if (rv < 0)
312 return rv; 285 return rv;
313 286
314 op_type_ = READ_COMPLETE; 287 op_type_ = READ_COMPLETE;
315 buf_ = new net::IOBufferWithSize(entry_->GetDataSize(1)); 288 buf_ = new net::IOBufferWithSize(entry_->GetDataSize(1));
316 return entry_->ReadData( 289 return entry_->ReadData(1, 0, buf_.get(), buf_->size(),
317 1, 290 base::Bind(&ShaderDiskReadHelper::OnOpComplete,
318 0, 291 weak_ptr_factory_.GetWeakPtr()));
319 buf_.get(),
320 buf_->size(),
321 base::Bind(&ShaderDiskReadHelper::OnOpComplete, this));
322 } 292 }
323 293
324 int ShaderDiskReadHelper::ReadComplete(int rv) { 294 int ShaderDiskReadHelper::ReadComplete(int rv) {
325 DCHECK(CalledOnValidThread()); 295 DCHECK(CalledOnValidThread());
326 // Called through OnOpComplete, so we know |cache_| is valid.
327 if (rv && rv == buf_->size() && !shader_loaded_callback_.is_null()) { 296 if (rv && rv == buf_->size() && !shader_loaded_callback_.is_null()) {
328 shader_loaded_callback_.Run(entry_->GetKey(), 297 shader_loaded_callback_.Run(entry_->GetKey(),
329 std::string(buf_->data(), buf_->size())); 298 std::string(buf_->data(), buf_->size()));
330 } 299 }
331 300
332 buf_ = NULL; 301 buf_ = NULL;
333 entry_->Close(); 302 entry_->Close();
334 entry_ = NULL; 303 entry_ = NULL;
335 304
336 op_type_ = OPEN_NEXT; 305 op_type_ = OPEN_NEXT;
337 return net::OK; 306 return net::OK;
338 } 307 }
339 308
340 int ShaderDiskReadHelper::IterationComplete(int rv) { 309 int ShaderDiskReadHelper::IterationComplete(int rv) {
341 DCHECK(CalledOnValidThread()); 310 DCHECK(CalledOnValidThread());
342 // Called through OnOpComplete, so we know |cache_| is valid.
343 iter_.reset(); 311 iter_.reset();
344 op_type_ = TERMINATE; 312 op_type_ = TERMINATE;
345 return net::OK; 313 return net::OK;
346 } 314 }
347 315
348 ShaderDiskReadHelper::~ShaderDiskReadHelper() { 316 ////////////////////////////////////////////////////////////////////////////////
349 if (entry_) { 317 // ShaderClearHelper
350 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
351 base::Bind(&EntryCloser, entry_));
352 }
353 if (iter_) {
354 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
355 base::Bind(&FreeDiskCacheIterator,
356 base::Passed(&iter_)));
357 }
358 }
359 318
360 ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache, 319 ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
361 const base::FilePath& path, 320 const base::FilePath& path,
362 const base::Time& delete_begin, 321 const base::Time& delete_begin,
363 const base::Time& delete_end, 322 const base::Time& delete_end,
364 const base::Closure& callback) 323 const base::Closure& callback)
365 : cache_(cache), 324 : cache_(cache),
366 op_type_(VERIFY_CACHE_SETUP), 325 op_type_(VERIFY_CACHE_SETUP),
367 path_(path), 326 path_(path),
368 delete_begin_(delete_begin), 327 delete_begin_(delete_begin),
369 delete_end_(delete_end), 328 delete_end_(delete_end),
370 callback_(callback) { 329 callback_(callback) {
371 } 330 }
372 331
373 ShaderClearHelper::~ShaderClearHelper() { 332 ShaderClearHelper::~ShaderClearHelper() {
374 DCHECK_CURRENTLY_ON(BrowserThread::IO); 333 DCHECK(CalledOnValidThread());
375 } 334 }
376 335
377 void ShaderClearHelper::Clear() { 336 void ShaderClearHelper::Clear() {
378 DCHECK_CURRENTLY_ON(BrowserThread::IO); 337 DCHECK(CalledOnValidThread());
379 DoClearShaderCache(net::OK); 338 DoClearShaderCache(net::OK);
380 } 339 }
381 340
382 void ShaderClearHelper::DoClearShaderCache(int rv) { 341 void ShaderClearHelper::DoClearShaderCache(int rv) {
383 DCHECK_CURRENTLY_ON(BrowserThread::IO); 342 DCHECK(CalledOnValidThread());
384 343
385 // Hold a ref to ourselves so when we do the CacheCleared call we don't get 344 // Hold a ref to ourselves so when we do the CacheCleared call we don't get
386 // auto-deleted when our ref count drops to zero. 345 // auto-deleted when our ref count drops to zero.
387 scoped_refptr<ShaderClearHelper> helper = this; 346 scoped_refptr<ShaderClearHelper> helper = this;
388 347
389 while (rv != net::ERR_IO_PENDING) { 348 while (rv != net::ERR_IO_PENDING) {
390 switch (op_type_) { 349 switch (op_type_) {
391 case VERIFY_CACHE_SETUP: 350 case VERIFY_CACHE_SETUP:
392 rv = cache_->SetAvailableCallback( 351 rv = cache_->SetAvailableCallback(
393 base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr())); 352 base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr()));
(...skipping 11 matching lines...) Expand all
405 rv = net::ERR_IO_PENDING; // Break the loop. 364 rv = net::ERR_IO_PENDING; // Break the loop.
406 break; 365 break;
407 default: 366 default:
408 NOTREACHED(); // Invalid state provided. 367 NOTREACHED(); // Invalid state provided.
409 op_type_ = TERMINATE; 368 op_type_ = TERMINATE;
410 break; 369 break;
411 } 370 }
412 } 371 }
413 } 372 }
414 373
374 ////////////////////////////////////////////////////////////////////////////////
375 // ShaderCacheFactory
376
377 // static
378 void ShaderCacheFactory::InitInstance(
379 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
380 scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) {
381 if (task_runner->BelongsToCurrentThread()) {
382 CreateFactoryInstance(std::move(cache_task_runner));
383 } else {
384 task_runner->PostTask(FROM_HERE,
385 base::Bind(&ShaderCacheFactory::CreateFactoryInstance,
386 std::move(cache_task_runner)));
387 }
388 }
389
415 // static 390 // static
416 ShaderCacheFactory* ShaderCacheFactory::GetInstance() { 391 ShaderCacheFactory* ShaderCacheFactory::GetInstance() {
417 return base::Singleton<ShaderCacheFactory, 392 factory_instance =
418 base::LeakySingletonTraits<ShaderCacheFactory>>::get(); 393 base::Singleton<ShaderCacheFactory,
394 base::LeakySingletonTraits<ShaderCacheFactory>>::get();
piman 2016/11/02 18:11:15 Can we instantiate the singleton in CreateFactoryI
sadrul 2016/11/02 19:24:53 Done.
sadrul 2016/11/02 20:36:39 This change ended up catching a few places that ca
piman 2016/11/02 20:56:17 I'm ok with returning null from GetInstance() if i
sadrul 2016/11/03 03:57:51 Done.
395 DCHECK(factory_instance->CalledOnValidThread());
396 return factory_instance;
419 } 397 }
420 398
421 ShaderCacheFactory::ShaderCacheFactory() { 399 ShaderCacheFactory::ShaderCacheFactory() {
422 } 400 }
423 401
424 ShaderCacheFactory::~ShaderCacheFactory() { 402 ShaderCacheFactory::~ShaderCacheFactory() {
425 } 403 }
426 404
405 // static
406 void ShaderCacheFactory::CreateFactoryInstance(
407 scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) {
408 DCHECK(!factory_instance);
409 GetInstance()->cache_task_runner_ = std::move(cache_task_runner);
410 }
411
427 void ShaderCacheFactory::SetCacheInfo(int32_t client_id, 412 void ShaderCacheFactory::SetCacheInfo(int32_t client_id,
428 const base::FilePath& path) { 413 const base::FilePath& path) {
414 DCHECK(CalledOnValidThread());
429 client_id_to_path_map_[client_id] = path; 415 client_id_to_path_map_[client_id] = path;
430 } 416 }
431 417
432 void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) { 418 void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) {
419 DCHECK(CalledOnValidThread());
433 client_id_to_path_map_.erase(client_id); 420 client_id_to_path_map_.erase(client_id);
434 } 421 }
435 422
436 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) { 423 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) {
424 DCHECK(CalledOnValidThread());
437 ClientIdToPathMap::iterator iter = 425 ClientIdToPathMap::iterator iter =
438 client_id_to_path_map_.find(client_id); 426 client_id_to_path_map_.find(client_id);
439 if (iter == client_id_to_path_map_.end()) 427 if (iter == client_id_to_path_map_.end())
440 return NULL; 428 return NULL;
441 return ShaderCacheFactory::GetByPath(iter->second); 429 return ShaderCacheFactory::GetByPath(iter->second);
442 } 430 }
443 431
444 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath( 432 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath(
445 const base::FilePath& path) { 433 const base::FilePath& path) {
434 DCHECK(CalledOnValidThread());
446 ShaderCacheMap::iterator iter = shader_cache_map_.find(path); 435 ShaderCacheMap::iterator iter = shader_cache_map_.find(path);
447 if (iter != shader_cache_map_.end()) 436 if (iter != shader_cache_map_.end())
448 return iter->second; 437 return iter->second;
449 438
450 ShaderDiskCache* cache = new ShaderDiskCache(path); 439 ShaderDiskCache* cache = new ShaderDiskCache(path);
451 cache->Init(); 440 cache->Init(cache_task_runner_);
452 return cache; 441 return cache;
453 } 442 }
454 443
455 void ShaderCacheFactory::AddToCache(const base::FilePath& key, 444 void ShaderCacheFactory::AddToCache(const base::FilePath& key,
456 ShaderDiskCache* cache) { 445 ShaderDiskCache* cache) {
446 DCHECK(CalledOnValidThread());
457 shader_cache_map_[key] = cache; 447 shader_cache_map_[key] = cache;
458 } 448 }
459 449
460 void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) { 450 void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) {
451 DCHECK(CalledOnValidThread());
461 shader_cache_map_.erase(key); 452 shader_cache_map_.erase(key);
462 } 453 }
463 454
464 void ShaderCacheFactory::ClearByPath(const base::FilePath& path, 455 void ShaderCacheFactory::ClearByPath(const base::FilePath& path,
465 const base::Time& delete_begin, 456 const base::Time& delete_begin,
466 const base::Time& delete_end, 457 const base::Time& delete_end,
467 const base::Closure& callback) { 458 const base::Closure& callback) {
468 DCHECK_CURRENTLY_ON(BrowserThread::IO); 459 DCHECK(CalledOnValidThread());
469 DCHECK(!callback.is_null()); 460 DCHECK(!callback.is_null());
470 461
471 scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper( 462 scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper(
472 GetByPath(path), path, delete_begin, delete_end, callback); 463 GetByPath(path), path, delete_begin, delete_end, callback);
473 464
474 // We could receive requests to clear the same path with different 465 // We could receive requests to clear the same path with different
475 // begin/end times. So, we keep a list of requests. If we haven't seen this 466 // begin/end times. So, we keep a list of requests. If we haven't seen this
476 // path before we kick off the clear and add it to the list. If we have see it 467 // path before we kick off the clear and add it to the list. If we have see it
477 // already, then we already have a clear running. We add this clear to the 468 // already, then we already have a clear running. We add this clear to the
478 // list and wait for any previous clears to finish. 469 // list and wait for any previous clears to finish.
479 ShaderClearMap::iterator iter = shader_clear_map_.find(path); 470 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
480 if (iter != shader_clear_map_.end()) { 471 if (iter != shader_clear_map_.end()) {
481 iter->second.push(helper); 472 iter->second.push(helper);
482 return; 473 return;
483 } 474 }
484 475
485 shader_clear_map_.insert( 476 shader_clear_map_.insert(
486 std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue())); 477 std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue()));
487 shader_clear_map_[path].push(helper); 478 shader_clear_map_[path].push(helper);
488 helper->Clear(); 479 helper->Clear();
489 } 480 }
490 481
491 void ShaderCacheFactory::CacheCleared(const base::FilePath& path) { 482 void ShaderCacheFactory::CacheCleared(const base::FilePath& path) {
492 DCHECK_CURRENTLY_ON(BrowserThread::IO); 483 DCHECK(CalledOnValidThread());
493 484
494 ShaderClearMap::iterator iter = shader_clear_map_.find(path); 485 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
495 if (iter == shader_clear_map_.end()) { 486 if (iter == shader_clear_map_.end()) {
496 LOG(ERROR) << "Completed clear but missing clear helper."; 487 LOG(ERROR) << "Completed clear but missing clear helper.";
497 return; 488 return;
498 } 489 }
499 490
500 iter->second.pop(); 491 iter->second.pop();
501 492
502 // If there are remaining items in the list we trigger the Clear on the 493 // If there are remaining items in the list we trigger the Clear on the
503 // next one. 494 // next one.
504 if (!iter->second.empty()) { 495 if (!iter->second.empty()) {
505 iter->second.front()->Clear(); 496 iter->second.front()->Clear();
506 return; 497 return;
507 } 498 }
508 499
509 shader_clear_map_.erase(path); 500 shader_clear_map_.erase(path);
510 } 501 }
511 502
503 ////////////////////////////////////////////////////////////////////////////////
504 // ShaderDiskCache
505
512 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path) 506 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path)
513 : cache_available_(false), 507 : cache_available_(false),
514 cache_path_(cache_path), 508 cache_path_(cache_path),
515 is_initialized_(false) { 509 is_initialized_(false) {
516 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this); 510 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this);
517 } 511 }
518 512
519 ShaderDiskCache::~ShaderDiskCache() { 513 ShaderDiskCache::~ShaderDiskCache() {
520 ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_); 514 ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_);
521 } 515 }
522 516
523 void ShaderDiskCache::Init() { 517 void ShaderDiskCache::Init(
518 scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) {
524 if (is_initialized_) { 519 if (is_initialized_) {
525 NOTREACHED(); // can't initialize disk cache twice. 520 NOTREACHED(); // can't initialize disk cache twice.
526 return; 521 return;
527 } 522 }
528 is_initialized_ = true; 523 is_initialized_ = true;
529 524
530 int rv = disk_cache::CreateCacheBackend( 525 int rv = disk_cache::CreateCacheBackend(
531 net::SHADER_CACHE, net::CACHE_BACKEND_DEFAULT, 526 net::SHADER_CACHE, net::CACHE_BACKEND_DEFAULT,
532 cache_path_.Append(kGpuCachePath), 527 cache_path_.Append(kGpuCachePath),
533 gpu::kDefaultMaxProgramCacheMemoryBytes, true, 528 gpu::kDefaultMaxProgramCacheMemoryBytes, true, cache_task_runner, NULL,
534 BrowserThread::GetTaskRunnerForThread(BrowserThread::CACHE).get(), NULL,
535 &backend_, base::Bind(&ShaderDiskCache::CacheCreatedCallback, this)); 529 &backend_, base::Bind(&ShaderDiskCache::CacheCreatedCallback, this));
536 530
537 if (rv == net::OK) 531 if (rv == net::OK)
538 cache_available_ = true; 532 cache_available_ = true;
539 } 533 }
540 534
541 void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) { 535 void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) {
542 if (!cache_available_) 536 if (!cache_available_)
543 return; 537 return;
544 538
545 scoped_refptr<ShaderDiskCacheEntry> shim = 539 auto shim = base::MakeUnique<ShaderDiskCacheEntry>(this, key, shader);
546 new ShaderDiskCacheEntry(AsWeakPtr(), key, shader);
547 shim->Cache(); 540 shim->Cache();
548 541 entries_.push_back(std::move(shim));
549 entry_map_[shim.get()] = shim;
550 } 542 }
551 543
552 int ShaderDiskCache::Clear( 544 int ShaderDiskCache::Clear(
553 const base::Time begin_time, const base::Time end_time, 545 const base::Time begin_time, const base::Time end_time,
554 const net::CompletionCallback& completion_callback) { 546 const net::CompletionCallback& completion_callback) {
555 int rv; 547 int rv;
556 if (begin_time.is_null()) { 548 if (begin_time.is_null()) {
557 rv = backend_->DoomAllEntries(completion_callback); 549 rv = backend_->DoomAllEntries(completion_callback);
558 } else { 550 } else {
559 rv = backend_->DoomEntriesBetween(begin_time, end_time, 551 rv = backend_->DoomEntriesBetween(begin_time, end_time,
(...skipping 14 matching lines...) Expand all
574 return net::OK; 566 return net::OK;
575 available_callback_ = callback; 567 available_callback_ = callback;
576 return net::ERR_IO_PENDING; 568 return net::ERR_IO_PENDING;
577 } 569 }
578 570
579 void ShaderDiskCache::CacheCreatedCallback(int rv) { 571 void ShaderDiskCache::CacheCreatedCallback(int rv) {
580 if (rv != net::OK) { 572 if (rv != net::OK) {
581 LOG(ERROR) << "Shader Cache Creation failed: " << rv; 573 LOG(ERROR) << "Shader Cache Creation failed: " << rv;
582 return; 574 return;
583 } 575 }
584 helper_ = new ShaderDiskReadHelper(AsWeakPtr(), shader_loaded_callback_); 576 helper_ =
577 base::MakeUnique<ShaderDiskReadHelper>(this, shader_loaded_callback_);
585 helper_->LoadCache(); 578 helper_->LoadCache();
586 } 579 }
587 580
588 void ShaderDiskCache::EntryComplete(void* entry) { 581 void ShaderDiskCache::EntryComplete(ShaderDiskCacheEntry* entry) {
589 entry_map_.erase(entry); 582 entries_.erase(
583 std::remove_if(entries_.begin(), entries_.end(),
584 [entry](const std::unique_ptr<ShaderDiskCacheEntry>& e) {
585 return e.get() == entry;
586 }));
piman 2016/11/02 18:11:15 This changes from O(log n) to O(n) - is it really
sadrul 2016/11/02 19:24:53 I couldn't find a clean way of using std::[unorder
590 587
591 if (entry_map_.empty() && !cache_complete_callback_.is_null()) 588 if (entries_.empty() && !cache_complete_callback_.is_null())
592 cache_complete_callback_.Run(net::OK); 589 cache_complete_callback_.Run(net::OK);
593 } 590 }
594 591
595 void ShaderDiskCache::ReadComplete() { 592 void ShaderDiskCache::ReadComplete() {
596 helper_ = NULL; 593 helper_ = nullptr;
597 594
598 // The cache is considered available after we have finished reading any 595 // The cache is considered available after we have finished reading any
599 // of the old cache values off disk. This prevents a potential race where we 596 // of the old cache values off disk. This prevents a potential race where we
600 // are reading from disk and execute a cache clear at the same time. 597 // are reading from disk and execute a cache clear at the same time.
601 cache_available_ = true; 598 cache_available_ = true;
602 if (!available_callback_.is_null()) { 599 if (!available_callback_.is_null()) {
603 available_callback_.Run(net::OK); 600 available_callback_.Run(net::OK);
604 available_callback_.Reset(); 601 available_callback_.Reset();
605 } 602 }
606 } 603 }
607 604
608 int ShaderDiskCache::SetCacheCompleteCallback( 605 int ShaderDiskCache::SetCacheCompleteCallback(
609 const net::CompletionCallback& callback) { 606 const net::CompletionCallback& callback) {
610 if (entry_map_.empty()) { 607 if (entries_.empty()) {
611 return net::OK; 608 return net::OK;
612 } 609 }
613 cache_complete_callback_ = callback; 610 cache_complete_callback_ = callback;
614 return net::ERR_IO_PENDING; 611 return net::ERR_IO_PENDING;
615 } 612 }
616 613
617 } // namespace content 614 } // namespace content
618 615
OLDNEW
« no previous file with comments | « content/browser/gpu/shader_disk_cache.h ('k') | content/browser/gpu/shader_disk_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698