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

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

Issue 12500009: Add the ability to clear the shader disk cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months 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 | Annotate | Revision Log
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_impl.h"
6 6
7 #include "base/threading/thread_checker.h" 7 #include "base/threading/thread_checker.h"
8 #include "content/browser/gpu/gpu_process_host.h" 8 #include "content/browser/gpu/gpu_process_host.h"
9 #include "content/public/browser/browser_thread.h" 9 #include "content/public/browser/browser_thread.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
12 12
13 namespace content { 13 namespace content {
14 14
15 namespace { 15 namespace {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 base::WeakPtr<ShaderDiskCache> cache_; 94 base::WeakPtr<ShaderDiskCache> cache_;
95 OpType op_type_; 95 OpType op_type_;
96 void* iter_; 96 void* iter_;
97 scoped_refptr<net::IOBufferWithSize> buf_; 97 scoped_refptr<net::IOBufferWithSize> buf_;
98 int host_id_; 98 int host_id_;
99 disk_cache::Entry* entry_; 99 disk_cache::Entry* entry_;
100 100
101 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper); 101 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper);
102 }; 102 };
103 103
104 class ShaderClearHelper
105 : public base::ThreadChecker,
jonathan.backer 2013/03/21 21:06:36 nix: ThreadChecker is for CalledOnValidThread, whi
dsinclair 2013/03/22 18:08:23 Done.
106 public base::RefCounted<ShaderClearHelper> {
107 public:
108 ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
109 const base::FilePath& path,
110 const base::Time& delete_begin,
111 const base::Time& delete_end,
112 const base::Closure& callback);
113 void Clear();
114
115 private:
116 friend class base::RefCounted<ShaderClearHelper>;
117
118 enum OpType {
119 TERMINATE,
120 VERIFY_CACHE_SETUP,
121 DELETE_CACHE
122 };
123
124 ~ShaderClearHelper();
125
126 void DoClearShaderCache(int rv);
127
128 scoped_refptr<ShaderDiskCache> cache_;
129 OpType op_type_;
130 base::FilePath path_;
131 base::Time delete_begin_;
132 base::Time delete_end_;
133 base::Closure callback_;
134
135 DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper);
136 };
137
104 ShaderDiskCacheEntry::ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache, 138 ShaderDiskCacheEntry::ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache,
105 const std::string& key, 139 const std::string& key,
106 const std::string& shader) 140 const std::string& shader)
107 : cache_(cache), 141 : cache_(cache),
108 op_type_(OPEN_ENTRY), 142 op_type_(OPEN_ENTRY),
109 key_(key), 143 key_(key),
110 shader_(shader), 144 shader_(shader),
111 entry_(NULL) { 145 entry_(NULL) {
112 } 146 }
113 147
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 op_type_ = TERMINATE; 336 op_type_ = TERMINATE;
303 return net::OK; 337 return net::OK;
304 } 338 }
305 339
306 ShaderDiskReadHelper::~ShaderDiskReadHelper() { 340 ShaderDiskReadHelper::~ShaderDiskReadHelper() {
307 if (entry_) 341 if (entry_)
308 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 342 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
309 base::Bind(&EntryCloser, entry_)); 343 base::Bind(&EntryCloser, entry_));
310 } 344 }
311 345
312 ShaderCacheFactory* ShaderCacheFactory::GetInstance() { 346 ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
313 return Singleton<ShaderCacheFactory, 347 const base::FilePath& path,
314 LeakySingletonTraits<ShaderCacheFactory> >::get(); 348 const base::Time& delete_begin,
349 const base::Time& delete_end,
350 const base::Closure& callback)
351 : cache_(cache),
352 op_type_(VERIFY_CACHE_SETUP),
353 path_(path),
354 delete_begin_(delete_begin),
355 delete_end_(delete_end),
356 callback_(callback) {
315 } 357 }
316 358
317 ShaderCacheFactory::ShaderCacheFactory() { 359 ShaderClearHelper::~ShaderClearHelper() {
jonathan.backer 2013/03/21 21:06:36 Does it matter what thread the |cache| is deleted
dsinclair 2013/03/22 18:08:23 Done.
318 } 360 }
319 361
320 ShaderCacheFactory::~ShaderCacheFactory() { 362 void ShaderClearHelper::Clear() {
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
364 DoClearShaderCache(net::OK);
321 } 365 }
322 366
323 void ShaderCacheFactory::SetCacheInfo(int32 client_id, 367 void ShaderClearHelper::DoClearShaderCache(int rv) {
324 const base::FilePath& path) { 368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
325 client_id_to_path_map_[client_id] = path.Append(kGpuCachePath); 369
370 while (rv != net::ERR_IO_PENDING) {
371 switch (op_type_) {
372 case VERIFY_CACHE_SETUP:
373 rv = cache_->SetAvailableCallback(
374 base::Bind(&ShaderClearHelper::DoClearShaderCache, this));
375 op_type_ = DELETE_CACHE;
376 break;
377 case DELETE_CACHE:
378 rv = cache_->Clear(
379 delete_begin_, delete_end_,
380 base::Bind(&ShaderClearHelper::DoClearShaderCache, this));
381 op_type_ = TERMINATE;
382 break;
383 case TERMINATE:
384 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
385 base::Bind(&ShaderCacheFactoryImpl::CacheCleared,
386 base::Unretained(ShaderCacheFactoryImpl::GetInstance()),
387 path_));
jonathan.backer 2013/03/21 21:06:36 nit: Comment for the PostTask. This won't be clear
dsinclair 2013/03/22 18:08:23 Done.
388 callback_.Run();
389 rv = net::ERR_IO_PENDING; // Break the loop.
390 break;
391 default:
392 NOTREACHED(); // Invalid state provided.
393 op_type_ = TERMINATE;
394 break;
395 }
396 }
326 } 397 }
327 398
328 void ShaderCacheFactory::RemoveCacheInfo(int32 client_id) { 399 // static
400 ShaderCacheFactory* ShaderCacheFactory::GetInstance() {
401 return ShaderCacheFactoryImpl::GetInstance();
402 }
403
404 // static
405 ShaderCacheFactoryImpl* ShaderCacheFactoryImpl::GetInstance() {
406 return Singleton<ShaderCacheFactoryImpl,
407 LeakySingletonTraits<ShaderCacheFactoryImpl> >::get();
408 }
409
410 ShaderCacheFactoryImpl::ShaderCacheFactoryImpl() {
411 }
412
413 ShaderCacheFactoryImpl::~ShaderCacheFactoryImpl() {
414 }
415
416 void ShaderCacheFactoryImpl::SetCacheInfo(int32 client_id,
417 const base::FilePath& path) {
418 client_id_to_path_map_[client_id] = path;
419 }
420
421 void ShaderCacheFactoryImpl::RemoveCacheInfo(int32 client_id) {
329 client_id_to_path_map_.erase(client_id); 422 client_id_to_path_map_.erase(client_id);
330 } 423 }
331 424
332 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32 client_id) { 425 scoped_refptr<ShaderDiskCache> ShaderCacheFactoryImpl::Get(
333 ClientIdToPathMap::iterator client_iter = 426 int32 client_id) {
427 ClientIdToPathMap::iterator iter =
334 client_id_to_path_map_.find(client_id); 428 client_id_to_path_map_.find(client_id);
335 if (client_iter == client_id_to_path_map_.end()) 429 if (iter == client_id_to_path_map_.end())
336 return NULL; 430 return NULL;
431 return ShaderCacheFactoryImpl::GetByPath(iter->second);
432 }
337 433
338 ShaderCacheMap::iterator iter = shader_cache_map_.find(client_iter->second); 434 scoped_refptr<ShaderDiskCache> ShaderCacheFactoryImpl::GetByPath(
435 const base::FilePath& path) {
436 ShaderCacheMap::iterator iter = shader_cache_map_.find(path);
339 if (iter != shader_cache_map_.end()) 437 if (iter != shader_cache_map_.end())
340 return iter->second; 438 return iter->second;
341 439
342 ShaderDiskCache* cache = new ShaderDiskCache(client_iter->second); 440 ShaderDiskCache* cache = new ShaderDiskCache(path);
343 cache->Init(); 441 cache->Init();
344
345 return cache; 442 return cache;
346 } 443 }
347 444
348 void ShaderCacheFactory::AddToCache(const base::FilePath& key, 445 void ShaderCacheFactoryImpl::AddToCache(const base::FilePath& key,
349 ShaderDiskCache* cache) { 446 ShaderDiskCache* cache) {
350 shader_cache_map_[key] = cache; 447 shader_cache_map_[key] = cache;
351 } 448 }
352 449
353 void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) { 450 void ShaderCacheFactoryImpl::RemoveFromCache(const base::FilePath& key) {
354 shader_cache_map_.erase(key); 451 shader_cache_map_.erase(key);
355 } 452 }
356 453
454 void ShaderCacheFactoryImpl::ClearByPath(const base::FilePath& path,
455 const base::Time& delete_begin,
456 const base::Time& delete_end,
457 const base::Closure& callback) {
458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
459 DCHECK(!callback.is_null());
460
461 scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper(
462 GetByPath(path), path, delete_begin, delete_end, callback);
463
464 // We could receive requests to clear the same path with different
465 // begin/end times. So, we keep a list of requests. If we haven't seen this
466 // path before we kick off the clear and add it to the list. If we have see it
467 // already, then we already have a clear running. We add this clear to the
468 // list and wait for any previous clears to finish.
469 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
470 if (iter != shader_clear_map_.end()) {
471 iter->second.push(helper);
472 return;
473 }
474
475 shader_clear_map_.insert(
476 std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue()));
477 shader_clear_map_[path].push(helper);
478 helper->Clear();
479 }
480
481 void ShaderCacheFactoryImpl::CacheCleared(const base::FilePath& path) {
482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
483
484 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
485 if (iter == shader_clear_map_.end()) {
486 LOG(ERROR) << "Completed clear but missing clear helper.";
487 return;
488 }
489
490 iter->second.pop();
491
492 // If there are remaining items in the list we trigger the Clear on the
493 // next one.
494 if (!iter->second.empty()) {
495 iter->second.front()->Clear();
496 return;
497 }
498
499 shader_clear_map_.erase(path);
500 }
501
357 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path) 502 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path)
358 : cache_available_(false), 503 : cache_available_(false),
359 max_cache_size_(0), 504 max_cache_size_(0),
360 host_id_(0), 505 host_id_(0),
361 cache_path_(cache_path), 506 cache_path_(cache_path),
362 is_initialized_(false), 507 is_initialized_(false),
363 backend_(NULL) { 508 backend_(NULL) {
364 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this); 509 ShaderCacheFactoryImpl::GetInstance()->AddToCache(cache_path_, this);
365 } 510 }
366 511
367 ShaderDiskCache::~ShaderDiskCache() { 512 ShaderDiskCache::~ShaderDiskCache() {
368 ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_); 513 ShaderCacheFactoryImpl::GetInstance()->RemoveFromCache(cache_path_);
369 } 514 }
370 515
371 void ShaderDiskCache::Init() { 516 void ShaderDiskCache::Init() {
372 if (is_initialized_) { 517 if (is_initialized_) {
373 NOTREACHED(); // can't initialize disk cache twice. 518 NOTREACHED(); // can't initialize disk cache twice.
374 return; 519 return;
375 } 520 }
376 is_initialized_ = true; 521 is_initialized_ = true;
377 522
378 int rv = disk_cache::CreateCacheBackend( 523 int rv = disk_cache::CreateCacheBackend(
379 net::SHADER_CACHE, 524 net::SHADER_CACHE,
380 cache_path_, 525 cache_path_.Append(kGpuCachePath),
381 max_cache_size_, 526 max_cache_size_,
382 true, 527 true,
383 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE), 528 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE),
384 NULL, 529 NULL,
385 &backend_, 530 &backend_,
386 base::Bind(&ShaderDiskCache::CacheCreatedCallback, this)); 531 base::Bind(&ShaderDiskCache::CacheCreatedCallback, this));
387 532
388 if (rv == net::OK) 533 if (rv == net::OK)
389 cache_available_ = true; 534 cache_available_ = true;
390 } 535 }
391 536
392 void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) { 537 void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) {
393 if (!cache_available_) 538 if (!cache_available_)
394 return; 539 return;
395 540
396 ShaderDiskCacheEntry* shim = 541 ShaderDiskCacheEntry* shim =
397 new ShaderDiskCacheEntry(AsWeakPtr(), key, shader); 542 new ShaderDiskCacheEntry(AsWeakPtr(), key, shader);
398 shim->Cache(); 543 shim->Cache();
399 544
400 entry_map_[shim] = shim; 545 entry_map_[shim] = shim;
401 } 546 }
402 547
548 int ShaderDiskCache::Clear(
549 const base::Time begin_time, const base::Time end_time,
550 const net::CompletionCallback& completion_callback) {
551 int rv;
552 if (begin_time.is_null()) {
553 rv = backend_->DoomAllEntries(completion_callback);
554 } else {
555 rv = backend_->DoomEntriesBetween(begin_time, end_time,
556 completion_callback);
557 }
558 return rv;
559 }
560
561 int ShaderDiskCache::SetAvailableCallback(
562 const net::CompletionCallback& callback) {
563 if (cache_available_)
564 return net::OK;
565 available_callback_ = callback;
566 return net::ERR_IO_PENDING;
567 }
568
403 void ShaderDiskCache::CacheCreatedCallback(int rv) { 569 void ShaderDiskCache::CacheCreatedCallback(int rv) {
404 if (rv != net::OK) { 570 if (rv != net::OK) {
405 LOG(ERROR) << "Shader Cache Creation failed: " << rv; 571 LOG(ERROR) << "Shader Cache Creation failed: " << rv;
406 return; 572 return;
407 } 573 }
408
409 cache_available_ = true; 574 cache_available_ = true;
410 575
411 helper_ = new ShaderDiskReadHelper(AsWeakPtr(), host_id_); 576 helper_ = new ShaderDiskReadHelper(AsWeakPtr(), host_id_);
412 helper_->LoadCache(); 577 helper_->LoadCache();
578
579 if (!available_callback_.is_null()) {
580 available_callback_.Run(net::OK);
581 available_callback_.Reset();
582 }
413 } 583 }
414 584
415 void ShaderDiskCache::EntryComplete(void* entry) { 585 void ShaderDiskCache::EntryComplete(void* entry) {
416 entry_map_.erase(entry); 586 entry_map_.erase(entry);
417 } 587 }
418 588
419 void ShaderDiskCache::ReadComplete() { 589 void ShaderDiskCache::ReadComplete() {
420 helper_ = NULL; 590 helper_ = NULL;
421 } 591 }
422 592
423 } // namespace content 593 } // namespace content
424 594
OLDNEW
« no previous file with comments | « content/browser/gpu/shader_disk_cache_impl.h ('k') | content/browser/renderer_host/render_process_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698