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 |