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

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

Issue 2469413002: gpu shader cache: Make ShaderClearHelper non-refcounted. (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
« no previous file with comments | « content/browser/gpu/shader_disk_cache.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/memory/ptr_util.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/threading/thread_checker.h" 10 #include "base/threading/thread_checker.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 ShaderLoadedCallback shader_loaded_callback_; 91 ShaderLoadedCallback shader_loaded_callback_;
92 OpType op_type_; 92 OpType op_type_;
93 std::unique_ptr<disk_cache::Backend::Iterator> iter_; 93 std::unique_ptr<disk_cache::Backend::Iterator> iter_;
94 scoped_refptr<net::IOBufferWithSize> buf_; 94 scoped_refptr<net::IOBufferWithSize> buf_;
95 disk_cache::Entry* entry_; 95 disk_cache::Entry* entry_;
96 base::WeakPtrFactory<ShaderDiskReadHelper> weak_ptr_factory_; 96 base::WeakPtrFactory<ShaderDiskReadHelper> weak_ptr_factory_;
97 97
98 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper); 98 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper);
99 }; 99 };
100 100
101 class ShaderClearHelper : public base::RefCounted<ShaderClearHelper>, 101 class ShaderClearHelper : public base::ThreadChecker {
102 public base::SupportsWeakPtr<ShaderClearHelper>,
103 public base::ThreadChecker {
104 public: 102 public:
105 ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache, 103 ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
106 const base::FilePath& path, 104 const base::FilePath& path,
107 const base::Time& delete_begin, 105 const base::Time& delete_begin,
108 const base::Time& delete_end, 106 const base::Time& delete_end,
109 const base::Closure& callback); 107 const base::Closure& callback);
108 ~ShaderClearHelper();
109
110 void Clear(); 110 void Clear();
111 111
112 private: 112 private:
113 friend class base::RefCounted<ShaderClearHelper>;
114
115 enum OpType { 113 enum OpType {
116 TERMINATE, 114 TERMINATE,
117 VERIFY_CACHE_SETUP, 115 VERIFY_CACHE_SETUP,
118 DELETE_CACHE 116 DELETE_CACHE
119 }; 117 };
120 118
121 ~ShaderClearHelper();
122
123 void DoClearShaderCache(int rv); 119 void DoClearShaderCache(int rv);
124 120
125 scoped_refptr<ShaderDiskCache> cache_; 121 scoped_refptr<ShaderDiskCache> cache_;
126 OpType op_type_; 122 OpType op_type_;
127 base::FilePath path_; 123 base::FilePath path_;
128 base::Time delete_begin_; 124 base::Time delete_begin_;
129 base::Time delete_end_; 125 base::Time delete_end_;
130 base::Closure callback_; 126 base::Closure callback_;
127 base::WeakPtrFactory<ShaderClearHelper> weak_ptr_factory_;
131 128
132 DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper); 129 DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper);
133 }; 130 };
134 131
135 //////////////////////////////////////////////////////////////////////////////// 132 ////////////////////////////////////////////////////////////////////////////////
136 // ShaderDiskCacheEntry 133 // ShaderDiskCacheEntry
137 134
138 ShaderDiskCacheEntry::ShaderDiskCacheEntry(ShaderDiskCache* cache, 135 ShaderDiskCacheEntry::ShaderDiskCacheEntry(ShaderDiskCache* cache,
139 const std::string& key, 136 const std::string& key,
140 const std::string& shader) 137 const std::string& shader)
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 case READ_COMPLETE: 255 case READ_COMPLETE:
259 rv = ReadComplete(rv); 256 rv = ReadComplete(rv);
260 break; 257 break;
261 case ITERATION_FINISHED: 258 case ITERATION_FINISHED:
262 rv = IterationComplete(rv); 259 rv = IterationComplete(rv);
263 break; 260 break;
264 case TERMINATE: 261 case TERMINATE:
265 cache_->ReadComplete(); 262 cache_->ReadComplete();
266 rv = net::ERR_IO_PENDING; // break the loop 263 rv = net::ERR_IO_PENDING; // break the loop
267 break; 264 break;
268 default:
269 NOTREACHED(); // Invalid state for read helper
270 rv = net::ERR_FAILED;
271 break;
272 } 265 }
273 } while (rv != net::ERR_IO_PENDING); 266 } while (rv != net::ERR_IO_PENDING);
274 } 267 }
275 268
276 int ShaderDiskReadHelper::OpenNextEntry() { 269 int ShaderDiskReadHelper::OpenNextEntry() {
277 DCHECK(CalledOnValidThread()); 270 DCHECK(CalledOnValidThread());
278 op_type_ = OPEN_NEXT_COMPLETE; 271 op_type_ = OPEN_NEXT_COMPLETE;
279 if (!iter_) 272 if (!iter_)
280 iter_ = cache_->backend()->CreateIterator(); 273 iter_ = cache_->backend()->CreateIterator();
281 return iter_->OpenNextEntry(&entry_, 274 return iter_->OpenNextEntry(&entry_,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 317 }
325 318
326 //////////////////////////////////////////////////////////////////////////////// 319 ////////////////////////////////////////////////////////////////////////////////
327 // ShaderClearHelper 320 // ShaderClearHelper
328 321
329 ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache, 322 ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
330 const base::FilePath& path, 323 const base::FilePath& path,
331 const base::Time& delete_begin, 324 const base::Time& delete_begin,
332 const base::Time& delete_end, 325 const base::Time& delete_end,
333 const base::Closure& callback) 326 const base::Closure& callback)
334 : cache_(cache), 327 : cache_(std::move(cache)),
335 op_type_(VERIFY_CACHE_SETUP), 328 op_type_(VERIFY_CACHE_SETUP),
336 path_(path), 329 path_(path),
337 delete_begin_(delete_begin), 330 delete_begin_(delete_begin),
338 delete_end_(delete_end), 331 delete_end_(delete_end),
339 callback_(callback) { 332 callback_(callback),
333 weak_ptr_factory_(this) {
340 } 334 }
341 335
342 ShaderClearHelper::~ShaderClearHelper() { 336 ShaderClearHelper::~ShaderClearHelper() {
343 DCHECK(CalledOnValidThread()); 337 DCHECK(CalledOnValidThread());
344 } 338 }
345 339
346 void ShaderClearHelper::Clear() { 340 void ShaderClearHelper::Clear() {
347 DCHECK(CalledOnValidThread()); 341 DCHECK(CalledOnValidThread());
348 DoClearShaderCache(net::OK); 342 DoClearShaderCache(net::OK);
349 } 343 }
350 344
351 void ShaderClearHelper::DoClearShaderCache(int rv) { 345 void ShaderClearHelper::DoClearShaderCache(int rv) {
352 DCHECK(CalledOnValidThread()); 346 DCHECK(CalledOnValidThread());
353
354 // Hold a ref to ourselves so when we do the CacheCleared call we don't get
355 // auto-deleted when our ref count drops to zero.
356 scoped_refptr<ShaderClearHelper> helper = this;
357
358 while (rv != net::ERR_IO_PENDING) { 347 while (rv != net::ERR_IO_PENDING) {
359 switch (op_type_) { 348 switch (op_type_) {
360 case VERIFY_CACHE_SETUP: 349 case VERIFY_CACHE_SETUP:
361 rv = cache_->SetAvailableCallback( 350 rv = cache_->SetAvailableCallback(
362 base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr())); 351 base::Bind(&ShaderClearHelper::DoClearShaderCache,
352 weak_ptr_factory_.GetWeakPtr()));
363 op_type_ = DELETE_CACHE; 353 op_type_ = DELETE_CACHE;
364 break; 354 break;
365 case DELETE_CACHE: 355 case DELETE_CACHE:
366 rv = cache_->Clear( 356 rv = cache_->Clear(
367 delete_begin_, delete_end_, 357 delete_begin_, delete_end_,
368 base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr())); 358 base::Bind(&ShaderClearHelper::DoClearShaderCache,
359 weak_ptr_factory_.GetWeakPtr()));
369 op_type_ = TERMINATE; 360 op_type_ = TERMINATE;
370 break; 361 break;
371 case TERMINATE: 362 case TERMINATE:
363 callback_.Run();
364 // Calling CacheCleared() destroys |this|.
372 ShaderCacheFactory::GetInstance()->CacheCleared(path_); 365 ShaderCacheFactory::GetInstance()->CacheCleared(path_);
373 callback_.Run();
374 rv = net::ERR_IO_PENDING; // Break the loop. 366 rv = net::ERR_IO_PENDING; // Break the loop.
375 break; 367 break;
376 default:
377 NOTREACHED(); // Invalid state provided.
378 op_type_ = TERMINATE;
379 break;
380 } 368 }
381 } 369 }
382 } 370 }
383 371
384 //////////////////////////////////////////////////////////////////////////////// 372 ////////////////////////////////////////////////////////////////////////////////
385 // ShaderCacheFactory 373 // ShaderCacheFactory
386 374
387 // static 375 // static
388 void ShaderCacheFactory::InitInstance( 376 void ShaderCacheFactory::InitInstance(
389 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 377 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 client_id_to_path_map_[client_id] = path; 411 client_id_to_path_map_[client_id] = path;
424 } 412 }
425 413
426 void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) { 414 void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) {
427 DCHECK(CalledOnValidThread()); 415 DCHECK(CalledOnValidThread());
428 client_id_to_path_map_.erase(client_id); 416 client_id_to_path_map_.erase(client_id);
429 } 417 }
430 418
431 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) { 419 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) {
432 DCHECK(CalledOnValidThread()); 420 DCHECK(CalledOnValidThread());
433 ClientIdToPathMap::iterator iter = 421 ClientIdToPathMap::iterator iter = client_id_to_path_map_.find(client_id);
434 client_id_to_path_map_.find(client_id);
435 if (iter == client_id_to_path_map_.end()) 422 if (iter == client_id_to_path_map_.end())
436 return NULL; 423 return NULL;
437 return ShaderCacheFactory::GetByPath(iter->second); 424 return ShaderCacheFactory::GetByPath(iter->second);
438 } 425 }
439 426
440 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath( 427 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath(
441 const base::FilePath& path) { 428 const base::FilePath& path) {
442 DCHECK(CalledOnValidThread()); 429 DCHECK(CalledOnValidThread());
443 ShaderCacheMap::iterator iter = shader_cache_map_.find(path); 430 ShaderCacheMap::iterator iter = shader_cache_map_.find(path);
444 if (iter != shader_cache_map_.end()) 431 if (iter != shader_cache_map_.end())
(...skipping 15 matching lines...) Expand all
460 shader_cache_map_.erase(key); 447 shader_cache_map_.erase(key);
461 } 448 }
462 449
463 void ShaderCacheFactory::ClearByPath(const base::FilePath& path, 450 void ShaderCacheFactory::ClearByPath(const base::FilePath& path,
464 const base::Time& delete_begin, 451 const base::Time& delete_begin,
465 const base::Time& delete_end, 452 const base::Time& delete_end,
466 const base::Closure& callback) { 453 const base::Closure& callback) {
467 DCHECK(CalledOnValidThread()); 454 DCHECK(CalledOnValidThread());
468 DCHECK(!callback.is_null()); 455 DCHECK(!callback.is_null());
469 456
470 scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper( 457 auto helper = base::MakeUnique<ShaderClearHelper>(
471 GetByPath(path), path, delete_begin, delete_end, callback); 458 GetByPath(path), path, delete_begin, delete_end, callback);
472 459
473 // We could receive requests to clear the same path with different 460 // We could receive requests to clear the same path with different
474 // begin/end times. So, we keep a list of requests. If we haven't seen this 461 // begin/end times. So, we keep a list of requests. If we haven't seen this
475 // path before we kick off the clear and add it to the list. If we have see it 462 // path before we kick off the clear and add it to the list. If we have see it
476 // already, then we already have a clear running. We add this clear to the 463 // already, then we already have a clear running. We add this clear to the
477 // list and wait for any previous clears to finish. 464 // list and wait for any previous clears to finish.
478 ShaderClearMap::iterator iter = shader_clear_map_.find(path); 465 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
479 if (iter != shader_clear_map_.end()) { 466 if (iter != shader_clear_map_.end()) {
480 iter->second.push(helper); 467 iter->second.push(std::move(helper));
481 return; 468 return;
482 } 469 }
483 470
471 helper->Clear();
piman 2016/11/03 18:01:38 Is it possible that Clear() will reenter CacheClea
sadrul 2016/11/03 19:31:13 Oh nice! You are right. Done. Thanks!
484 shader_clear_map_.insert( 472 shader_clear_map_.insert(
485 std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue())); 473 std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue()));
486 shader_clear_map_[path].push(helper); 474 shader_clear_map_[path].push(std::move(helper));
487 helper->Clear();
488 } 475 }
489 476
490 void ShaderCacheFactory::CacheCleared(const base::FilePath& path) { 477 void ShaderCacheFactory::CacheCleared(const base::FilePath& path) {
491 DCHECK(CalledOnValidThread()); 478 DCHECK(CalledOnValidThread());
492 479
493 ShaderClearMap::iterator iter = shader_clear_map_.find(path); 480 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
494 if (iter == shader_clear_map_.end()) { 481 if (iter == shader_clear_map_.end()) {
495 LOG(ERROR) << "Completed clear but missing clear helper."; 482 LOG(ERROR) << "Completed clear but missing clear helper.";
496 return; 483 return;
497 } 484 }
498 485
499 iter->second.pop(); 486 iter->second.pop();
500 487
501 // If there are remaining items in the list we trigger the Clear on the 488 // If there are remaining items in the list we trigger the Clear on the
502 // next one. 489 // next one.
503 if (!iter->second.empty()) { 490 if (!iter->second.empty()) {
504 iter->second.front()->Clear(); 491 iter->second.front()->Clear();
505 return; 492 return;
506 } 493 }
507 494
508 shader_clear_map_.erase(path); 495 shader_clear_map_.erase(iter);
509 } 496 }
510 497
511 //////////////////////////////////////////////////////////////////////////////// 498 ////////////////////////////////////////////////////////////////////////////////
512 // ShaderDiskCache 499 // ShaderDiskCache
513 500
514 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path) 501 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path)
515 : cache_available_(false), 502 : cache_available_(false),
516 cache_path_(cache_path), 503 cache_path_(cache_path),
517 is_initialized_(false) { 504 is_initialized_(false) {
518 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this); 505 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 const net::CompletionCallback& callback) { 597 const net::CompletionCallback& callback) {
611 if (entries_.empty()) { 598 if (entries_.empty()) {
612 return net::OK; 599 return net::OK;
613 } 600 }
614 cache_complete_callback_ = callback; 601 cache_complete_callback_ = callback;
615 return net::ERR_IO_PENDING; 602 return net::ERR_IO_PENDING;
616 } 603 }
617 604
618 } // namespace content 605 } // namespace content
619 606
OLDNEW
« no previous file with comments | « content/browser/gpu/shader_disk_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698