Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 ShaderDiskCacheEntry::ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache, | 104 ShaderDiskCacheEntry::ShaderDiskCacheEntry( |
| 105 const std::string& key, | 105 base::WeakPtr<ShaderDiskCache> cache, |
| 106 const std::string& shader) | 106 const std::string& key, |
| 107 const std::string& shader) | |
|
jonathan.backer
2013/03/20 18:39:05
Why reformat?
dsinclair
2013/03/21 17:46:59
Done. For a change which has since been reverted.
| |
| 107 : cache_(cache), | 108 : cache_(cache), |
| 108 op_type_(OPEN_ENTRY), | 109 op_type_(OPEN_ENTRY), |
| 109 key_(key), | 110 key_(key), |
| 110 shader_(shader), | 111 shader_(shader), |
| 111 entry_(NULL) { | 112 entry_(NULL) { |
| 112 } | 113 } |
| 113 | 114 |
| 114 ShaderDiskCacheEntry::~ShaderDiskCacheEntry() { | 115 ShaderDiskCacheEntry::~ShaderDiskCacheEntry() { |
| 115 if (entry_) | 116 if (entry_) |
| 116 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 117 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 return cache_->backend()->CreateEntry( | 171 return cache_->backend()->CreateEntry( |
| 171 key_, | 172 key_, |
| 172 &entry_, | 173 &entry_, |
| 173 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this)); | 174 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this)); |
| 174 } | 175 } |
| 175 | 176 |
| 176 int ShaderDiskCacheEntry::WriteCallback(int rv) { | 177 int ShaderDiskCacheEntry::WriteCallback(int rv) { |
| 177 DCHECK(CalledOnValidThread()); | 178 DCHECK(CalledOnValidThread()); |
| 178 // Called through OnOpComplete, so we know |cache_| is valid. | 179 // Called through OnOpComplete, so we know |cache_| is valid. |
| 179 if (rv != net::OK) { | 180 if (rv != net::OK) { |
| 180 LOG(ERROR) << "Failed to create shader cache entry: " << rv; | |
|
jonathan.backer
2013/03/20 18:39:05
Still an error, no?
dsinclair
2013/03/21 17:46:59
Done.
| |
| 181 cache_->EntryComplete(this); | 181 cache_->EntryComplete(this); |
| 182 op_type_ = TERMINATE; | 182 op_type_ = TERMINATE; |
| 183 return rv; | 183 return rv; |
| 184 } | 184 } |
| 185 | 185 |
| 186 op_type_ = WRITE_DATA; | 186 op_type_ = WRITE_DATA; |
| 187 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_); | 187 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_); |
| 188 return entry_->WriteData(1, 0, io_buf, shader_.length(), | 188 return entry_->WriteData(1, 0, io_buf, shader_.length(), |
| 189 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, | 189 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, |
| 190 this), | 190 this), |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 op_type_ = TERMINATE; | 302 op_type_ = TERMINATE; |
| 303 return net::OK; | 303 return net::OK; |
| 304 } | 304 } |
| 305 | 305 |
| 306 ShaderDiskReadHelper::~ShaderDiskReadHelper() { | 306 ShaderDiskReadHelper::~ShaderDiskReadHelper() { |
| 307 if (entry_) | 307 if (entry_) |
| 308 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 308 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 309 base::Bind(&EntryCloser, entry_)); | 309 base::Bind(&EntryCloser, entry_)); |
| 310 } | 310 } |
| 311 | 311 |
| 312 ShaderCacheFactory* ShaderCacheFactory::GetInstance() { | 312 // static |
| 313 return Singleton<ShaderCacheFactory, | 313 ShaderCacheFactoryImpl* ShaderCacheFactoryImpl::GetInstance() { |
| 314 LeakySingletonTraits<ShaderCacheFactory> >::get(); | 314 return Singleton<ShaderCacheFactoryImpl, |
| 315 LeakySingletonTraits<ShaderCacheFactoryImpl> >::get(); | |
| 315 } | 316 } |
| 316 | 317 |
| 317 ShaderCacheFactory::ShaderCacheFactory() { | 318 ShaderCacheFactoryImpl::ShaderCacheFactoryImpl() |
| 319 : op_type_(CREATE_CACHE) { | |
|
jonathan.backer
2013/03/20 18:39:05
Why CREATE_CACHE? There hasn't been a clear reques
dsinclair
2013/03/21 17:46:59
Good point. Made it TERMINATE so nothing will happ
| |
| 318 } | 320 } |
| 319 | 321 |
| 320 ShaderCacheFactory::~ShaderCacheFactory() { | 322 ShaderCacheFactoryImpl::~ShaderCacheFactoryImpl() { |
| 321 } | 323 } |
| 322 | 324 |
| 323 void ShaderCacheFactory::SetCacheInfo(int32 client_id, | 325 void ShaderCacheFactoryImpl::SetCacheInfo(int32 client_id, |
| 324 const base::FilePath& path) { | 326 const base::FilePath& path) { |
| 325 client_id_to_path_map_[client_id] = path.Append(kGpuCachePath); | 327 client_id_to_path_map_[client_id] = path; |
| 326 } | 328 } |
| 327 | 329 |
| 328 void ShaderCacheFactory::RemoveCacheInfo(int32 client_id) { | 330 void ShaderCacheFactoryImpl::RemoveCacheInfo(int32 client_id) { |
| 329 client_id_to_path_map_.erase(client_id); | 331 client_id_to_path_map_.erase(client_id); |
| 330 } | 332 } |
| 331 | 333 |
| 332 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32 client_id) { | 334 scoped_refptr<ShaderDiskCache> ShaderCacheFactoryImpl::Get( |
| 333 ClientIdToPathMap::iterator client_iter = | 335 int32 client_id) { |
| 336 ClientIdToPathMap::iterator iter = | |
| 334 client_id_to_path_map_.find(client_id); | 337 client_id_to_path_map_.find(client_id); |
| 335 if (client_iter == client_id_to_path_map_.end()) | 338 if (iter == client_id_to_path_map_.end()) |
| 336 return NULL; | 339 return NULL; |
| 340 return ShaderCacheFactoryImpl::GetByPath(iter->second); | |
| 341 } | |
| 337 | 342 |
| 338 ShaderCacheMap::iterator iter = shader_cache_map_.find(client_iter->second); | 343 scoped_refptr<ShaderDiskCache> ShaderCacheFactoryImpl::GetByPath( |
| 344 const base::FilePath& path) { | |
| 345 ShaderCacheMap::iterator iter = shader_cache_map_.find(path); | |
| 339 if (iter != shader_cache_map_.end()) | 346 if (iter != shader_cache_map_.end()) |
| 340 return iter->second; | 347 return iter->second; |
| 341 | 348 |
| 342 ShaderDiskCache* cache = new ShaderDiskCache(client_iter->second); | 349 ShaderDiskCache* cache = new ShaderDiskCache(path); |
| 343 cache->Init(); | 350 cache->Init(); |
| 344 | |
| 345 return cache; | 351 return cache; |
| 346 } | 352 } |
| 347 | 353 |
| 348 void ShaderCacheFactory::AddToCache(const base::FilePath& key, | 354 void ShaderCacheFactoryImpl::AddToCache(const base::FilePath& key, |
| 349 ShaderDiskCache* cache) { | 355 ShaderDiskCache* cache) { |
| 350 shader_cache_map_[key] = cache; | 356 shader_cache_map_[key] = cache; |
| 351 } | 357 } |
| 352 | 358 |
| 353 void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) { | 359 void ShaderCacheFactoryImpl::RemoveFromCache(const base::FilePath& key) { |
| 354 shader_cache_map_.erase(key); | 360 shader_cache_map_.erase(key); |
| 355 } | 361 } |
| 356 | 362 |
| 363 void ShaderCacheFactoryImpl::ClearByPath(const base::FilePath& path, | |
| 364 const base::Time& delete_begin, | |
| 365 const base::Time& delete_end, | |
| 366 const base::Closure& callback) { | |
| 367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 368 DCHECK(!callback.is_null()); | |
| 369 | |
| 370 clear_path_ = path; | |
| 371 delete_begin_ = delete_begin; | |
| 372 delete_end_ = delete_end; | |
| 373 clear_callback_ = callback; | |
| 374 | |
| 375 op_type_ = CREATE_CACHE; | |
| 376 DoClearShaderCache(net::OK); | |
| 377 } | |
| 378 | |
| 379 void ShaderCacheFactoryImpl::DoClearShaderCache(int rv) { | |
| 380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 381 | |
| 382 while (rv != net::ERR_IO_PENDING) { | |
| 383 switch (op_type_) { | |
| 384 case CREATE_CACHE: | |
| 385 clear_shader_cache_ = GetByPath(clear_path_); | |
| 386 rv = clear_shader_cache_->SetAvailableCallback( | |
| 387 base::Bind(&ShaderCacheFactoryImpl::DoClearShaderCache, | |
| 388 base::Unretained(this))); // We're a singleton. | |
| 389 op_type_ = DELETE_CACHE; | |
| 390 break; | |
| 391 case DELETE_CACHE: | |
| 392 rv = clear_shader_cache_->Clear( | |
| 393 delete_begin_, delete_end_, | |
| 394 base::Bind(&ShaderCacheFactoryImpl::DoClearShaderCache, | |
| 395 base::Unretained(this))); // We're a singleton. | |
| 396 op_type_ = TERMINATE; | |
| 397 break; | |
| 398 case TERMINATE: | |
| 399 clear_shader_cache_ = NULL; | |
| 400 clear_callback_.Run(); | |
| 401 rv = net::ERR_IO_PENDING; // Break the loop. | |
| 402 break; | |
| 403 default: | |
| 404 NOTREACHED(); // Invalid state provided. | |
| 405 op_type_ = TERMINATE; | |
| 406 break; | |
| 407 } | |
| 408 } | |
| 409 } | |
| 410 | |
| 357 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path) | 411 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path) |
| 358 : cache_available_(false), | 412 : cache_available_(false), |
| 359 max_cache_size_(0), | 413 max_cache_size_(0), |
| 360 host_id_(0), | 414 host_id_(0), |
| 361 cache_path_(cache_path), | 415 cache_path_(cache_path), |
| 362 is_initialized_(false), | 416 is_initialized_(false), |
| 363 backend_(NULL) { | 417 backend_(NULL) { |
| 364 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this); | 418 static_cast<ShaderCacheFactoryImpl*>(ShaderCacheFactory::GetInstance())-> |
|
jonathan.backer
2013/03/20 18:39:05
Call the Impl getter and skip the cast?
dsinclair
2013/03/21 17:46:59
Done.
| |
| 419 AddToCache(cache_path_, this); | |
| 365 } | 420 } |
| 366 | 421 |
| 367 ShaderDiskCache::~ShaderDiskCache() { | 422 ShaderDiskCache::~ShaderDiskCache() { |
| 368 ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_); | 423 static_cast<ShaderCacheFactoryImpl*>(ShaderCacheFactory::GetInstance())-> |
|
jonathan.backer
2013/03/20 18:39:05
Ditto.
dsinclair
2013/03/21 17:46:59
Done.
| |
| 424 RemoveFromCache(cache_path_); | |
| 369 } | 425 } |
| 370 | 426 |
| 371 void ShaderDiskCache::Init() { | 427 void ShaderDiskCache::Init() { |
| 372 if (is_initialized_) { | 428 if (is_initialized_) { |
| 373 NOTREACHED(); // can't initialize disk cache twice. | 429 NOTREACHED(); // can't initialize disk cache twice. |
| 374 return; | 430 return; |
| 375 } | 431 } |
| 376 is_initialized_ = true; | 432 is_initialized_ = true; |
| 377 | 433 |
| 378 int rv = disk_cache::CreateCacheBackend( | 434 int rv = disk_cache::CreateCacheBackend( |
| 379 net::SHADER_CACHE, | 435 net::SHADER_CACHE, |
| 380 cache_path_, | 436 cache_path_.Append(kGpuCachePath), |
| 381 max_cache_size_, | 437 max_cache_size_, |
| 382 true, | 438 true, |
| 383 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE), | 439 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE), |
| 384 NULL, | 440 NULL, |
| 385 &backend_, | 441 &backend_, |
| 386 base::Bind(&ShaderDiskCache::CacheCreatedCallback, this)); | 442 base::Bind(&ShaderDiskCache::CacheCreatedCallback, this)); |
| 387 | 443 |
| 388 if (rv == net::OK) | 444 if (rv == net::OK) |
| 389 cache_available_ = true; | 445 cache_available_ = true; |
| 390 } | 446 } |
| 391 | 447 |
| 392 void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) { | 448 void ShaderDiskCache::set_host_id(int host_id) { |
| 449 host_id_ = host_id; | |
| 450 } | |
| 451 | |
| 452 void ShaderDiskCache::set_max_cache_size(size_t max_cache_size) { | |
| 453 max_cache_size_ = max_cache_size; | |
| 454 } | |
| 455 | |
| 456 void ShaderDiskCache::Cache(const std::string& key, | |
| 457 const std::string& shader) { | |
|
jonathan.backer
2013/03/20 18:39:05
Why reformat?
dsinclair
2013/03/21 17:46:59
Reverted change. Fixed.
| |
| 393 if (!cache_available_) | 458 if (!cache_available_) |
| 394 return; | 459 return; |
| 395 | 460 |
| 396 ShaderDiskCacheEntry* shim = | 461 ShaderDiskCacheEntry* shim = |
| 397 new ShaderDiskCacheEntry(AsWeakPtr(), key, shader); | 462 new ShaderDiskCacheEntry(AsWeakPtr(), key, shader); |
| 398 shim->Cache(); | 463 shim->Cache(); |
| 399 | 464 |
| 400 entry_map_[shim] = shim; | 465 entry_map_[shim] = shim; |
| 401 } | 466 } |
| 402 | 467 |
| 468 int ShaderDiskCache::Clear( | |
| 469 const base::Time begin_time, const base::Time end_time, | |
| 470 const net::CompletionCallback& completion_callback) { | |
| 471 int rv; | |
| 472 if (begin_time.is_null()) { | |
| 473 rv = backend_->DoomAllEntries(completion_callback); | |
| 474 } else { | |
| 475 rv = backend_->DoomEntriesBetween(begin_time, end_time, | |
| 476 completion_callback); | |
| 477 } | |
| 478 return rv; | |
| 479 } | |
| 480 | |
| 481 int ShaderDiskCache::SetAvailableCallback( | |
| 482 const net::CompletionCallback& callback) { | |
| 483 if (cache_available_) | |
| 484 return net::OK; | |
| 485 available_callback_ = callback; | |
| 486 return net::ERR_IO_PENDING; | |
| 487 } | |
| 488 | |
| 403 void ShaderDiskCache::CacheCreatedCallback(int rv) { | 489 void ShaderDiskCache::CacheCreatedCallback(int rv) { |
| 404 if (rv != net::OK) { | 490 if (rv != net::OK) { |
| 405 LOG(ERROR) << "Shader Cache Creation failed: " << rv; | 491 LOG(ERROR) << "Shader Cache Creation failed: " << rv; |
| 406 return; | 492 return; |
| 407 } | 493 } |
| 408 | |
| 409 cache_available_ = true; | 494 cache_available_ = true; |
| 410 | 495 |
| 411 helper_ = new ShaderDiskReadHelper(AsWeakPtr(), host_id_); | 496 helper_ = new ShaderDiskReadHelper(AsWeakPtr(), host_id_); |
| 412 helper_->LoadCache(); | 497 helper_->LoadCache(); |
| 498 | |
| 499 if (!available_callback_.is_null()) { | |
| 500 available_callback_.Run(net::OK); | |
| 501 available_callback_.Reset(); | |
| 502 } | |
| 413 } | 503 } |
| 414 | 504 |
| 415 void ShaderDiskCache::EntryComplete(void* entry) { | 505 void ShaderDiskCache::EntryComplete(void* entry) { |
| 416 entry_map_.erase(entry); | 506 entry_map_.erase(entry); |
| 417 } | 507 } |
| 418 | 508 |
| 419 void ShaderDiskCache::ReadComplete() { | 509 void ShaderDiskCache::ReadComplete() { |
| 420 helper_ = NULL; | 510 helper_ = NULL; |
| 421 } | 511 } |
| 422 | 512 |
| 423 } // namespace content | 513 } // namespace content |
| 424 | 514 |
| OLD | NEW |