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

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