Index: content/browser/gpu/shader_disk_cache.cc |
diff --git a/content/browser/gpu/shader_disk_cache.cc b/content/browser/gpu/shader_disk_cache.cc |
deleted file mode 100644 |
index 601edec0c1d04b428fd9a841a7b8a3ece0357c13..0000000000000000000000000000000000000000 |
--- a/content/browser/gpu/shader_disk_cache.cc |
+++ /dev/null |
@@ -1,584 +0,0 @@ |
-// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/browser/gpu/shader_disk_cache.h" |
- |
-#include "base/macros.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/single_thread_task_runner.h" |
-#include "base/threading/thread_checker.h" |
-#include "gpu/command_buffer/common/constants.h" |
-#include "net/base/cache_type.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/net_errors.h" |
- |
-namespace content { |
- |
-namespace { |
- |
-static const base::FilePath::CharType kGpuCachePath[] = |
- FILE_PATH_LITERAL("GPUCache"); |
- |
-} // namespace |
- |
-// ShaderDiskCacheEntry handles the work of caching/updating the cached |
-// shaders. |
-class ShaderDiskCacheEntry : public base::ThreadChecker { |
- public: |
- ShaderDiskCacheEntry(ShaderDiskCache* cache, |
- const std::string& key, |
- const std::string& shader); |
- ~ShaderDiskCacheEntry(); |
- |
- void Cache(); |
- |
- private: |
- enum OpType { |
- OPEN_ENTRY, |
- WRITE_DATA, |
- CREATE_ENTRY, |
- }; |
- |
- void OnOpComplete(int rv); |
- |
- int OpenCallback(int rv); |
- int WriteCallback(int rv); |
- int IOComplete(int rv); |
- |
- ShaderDiskCache* cache_; |
- OpType op_type_; |
- std::string key_; |
- std::string shader_; |
- disk_cache::Entry* entry_; |
- base::WeakPtr<ShaderDiskCacheEntry> weak_ptr_; |
- base::WeakPtrFactory<ShaderDiskCacheEntry> weak_ptr_factory_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ShaderDiskCacheEntry); |
-}; |
- |
-// ShaderDiskReadHelper is used to load all of the cached shaders from the |
-// disk cache and send to the memory cache. |
-class ShaderDiskReadHelper : public base::ThreadChecker { |
- public: |
- using ShaderLoadedCallback = ShaderDiskCache::ShaderLoadedCallback; |
- ShaderDiskReadHelper(ShaderDiskCache* cache, |
- const ShaderLoadedCallback& callback); |
- ~ShaderDiskReadHelper(); |
- |
- void LoadCache(); |
- |
- private: |
- enum OpType { |
- TERMINATE, |
- OPEN_NEXT, |
- OPEN_NEXT_COMPLETE, |
- READ_COMPLETE, |
- ITERATION_FINISHED |
- }; |
- |
- |
- void OnOpComplete(int rv); |
- |
- int OpenNextEntry(); |
- int OpenNextEntryComplete(int rv); |
- int ReadComplete(int rv); |
- int IterationComplete(int rv); |
- |
- ShaderDiskCache* cache_; |
- ShaderLoadedCallback shader_loaded_callback_; |
- OpType op_type_; |
- std::unique_ptr<disk_cache::Backend::Iterator> iter_; |
- scoped_refptr<net::IOBufferWithSize> buf_; |
- disk_cache::Entry* entry_; |
- base::WeakPtrFactory<ShaderDiskReadHelper> weak_ptr_factory_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper); |
-}; |
- |
-class ShaderClearHelper : public base::ThreadChecker { |
- public: |
- ShaderClearHelper(ShaderCacheFactory* factory, |
- scoped_refptr<ShaderDiskCache> cache, |
- const base::FilePath& path, |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- const base::Closure& callback); |
- ~ShaderClearHelper(); |
- |
- void Clear(); |
- |
- private: |
- enum OpType { |
- TERMINATE, |
- VERIFY_CACHE_SETUP, |
- DELETE_CACHE |
- }; |
- |
- void DoClearShaderCache(int rv); |
- |
- ShaderCacheFactory* factory_; |
- scoped_refptr<ShaderDiskCache> cache_; |
- OpType op_type_; |
- base::FilePath path_; |
- base::Time delete_begin_; |
- base::Time delete_end_; |
- base::Closure callback_; |
- base::WeakPtrFactory<ShaderClearHelper> weak_ptr_factory_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper); |
-}; |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ShaderDiskCacheEntry |
- |
-ShaderDiskCacheEntry::ShaderDiskCacheEntry(ShaderDiskCache* cache, |
- const std::string& key, |
- const std::string& shader) |
- : cache_(cache), |
- op_type_(OPEN_ENTRY), |
- key_(key), |
- shader_(shader), |
- entry_(nullptr), |
- weak_ptr_factory_(this) { |
- weak_ptr_ = weak_ptr_factory_.GetWeakPtr(); |
-} |
- |
-ShaderDiskCacheEntry::~ShaderDiskCacheEntry() { |
- DCHECK(CalledOnValidThread()); |
- if (entry_) |
- entry_->Close(); |
-} |
- |
-void ShaderDiskCacheEntry::Cache() { |
- DCHECK(CalledOnValidThread()); |
- int rv = cache_->backend()->OpenEntry( |
- key_, &entry_, base::Bind(&ShaderDiskCacheEntry::OnOpComplete, |
- weak_ptr_factory_.GetWeakPtr())); |
- if (rv != net::ERR_IO_PENDING) |
- OnOpComplete(rv); |
-} |
- |
-void ShaderDiskCacheEntry::OnOpComplete(int rv) { |
- DCHECK(CalledOnValidThread()); |
- // The function calls inside the switch block below can end up destroying |
- // |this|. So hold on to a WeakPtr<>, and terminate the while loop if |this| |
- // has been destroyed. |
- auto weak_ptr = std::move(weak_ptr_); |
- do { |
- switch (op_type_) { |
- case OPEN_ENTRY: |
- rv = OpenCallback(rv); |
- break; |
- case CREATE_ENTRY: |
- rv = WriteCallback(rv); |
- break; |
- case WRITE_DATA: |
- rv = IOComplete(rv); |
- break; |
- } |
- } while (rv != net::ERR_IO_PENDING && weak_ptr); |
- if (weak_ptr) |
- weak_ptr_ = std::move(weak_ptr); |
-} |
- |
-int ShaderDiskCacheEntry::OpenCallback(int rv) { |
- DCHECK(CalledOnValidThread()); |
- if (rv == net::OK) { |
- cache_->backend()->OnExternalCacheHit(key_); |
- cache_->EntryComplete(this); |
- return rv; |
- } |
- |
- op_type_ = CREATE_ENTRY; |
- return cache_->backend()->CreateEntry( |
- key_, &entry_, base::Bind(&ShaderDiskCacheEntry::OnOpComplete, |
- weak_ptr_factory_.GetWeakPtr())); |
-} |
- |
-int ShaderDiskCacheEntry::WriteCallback(int rv) { |
- DCHECK(CalledOnValidThread()); |
- if (rv != net::OK) { |
- LOG(ERROR) << "Failed to create shader cache entry: " << rv; |
- cache_->EntryComplete(this); |
- return rv; |
- } |
- |
- op_type_ = WRITE_DATA; |
- scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_); |
- return entry_->WriteData(1, 0, io_buf.get(), shader_.length(), |
- base::Bind(&ShaderDiskCacheEntry::OnOpComplete, |
- weak_ptr_factory_.GetWeakPtr()), |
- false); |
-} |
- |
-int ShaderDiskCacheEntry::IOComplete(int rv) { |
- DCHECK(CalledOnValidThread()); |
- cache_->EntryComplete(this); |
- return rv; |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ShaderDiskReadHelper |
- |
-ShaderDiskReadHelper::ShaderDiskReadHelper(ShaderDiskCache* cache, |
- const ShaderLoadedCallback& callback) |
- : cache_(cache), |
- shader_loaded_callback_(callback), |
- op_type_(OPEN_NEXT), |
- buf_(NULL), |
- entry_(NULL), |
- weak_ptr_factory_(this) {} |
- |
-ShaderDiskReadHelper::~ShaderDiskReadHelper() { |
- DCHECK(CalledOnValidThread()); |
- if (entry_) |
- entry_->Close(); |
- iter_ = nullptr; |
-} |
- |
-void ShaderDiskReadHelper::LoadCache() { |
- DCHECK(CalledOnValidThread()); |
- OnOpComplete(net::OK); |
-} |
- |
-void ShaderDiskReadHelper::OnOpComplete(int rv) { |
- DCHECK(CalledOnValidThread()); |
- do { |
- switch (op_type_) { |
- case OPEN_NEXT: |
- rv = OpenNextEntry(); |
- break; |
- case OPEN_NEXT_COMPLETE: |
- rv = OpenNextEntryComplete(rv); |
- break; |
- case READ_COMPLETE: |
- rv = ReadComplete(rv); |
- break; |
- case ITERATION_FINISHED: |
- rv = IterationComplete(rv); |
- break; |
- case TERMINATE: |
- cache_->ReadComplete(); |
- rv = net::ERR_IO_PENDING; // break the loop |
- break; |
- } |
- } while (rv != net::ERR_IO_PENDING); |
-} |
- |
-int ShaderDiskReadHelper::OpenNextEntry() { |
- DCHECK(CalledOnValidThread()); |
- op_type_ = OPEN_NEXT_COMPLETE; |
- if (!iter_) |
- iter_ = cache_->backend()->CreateIterator(); |
- return iter_->OpenNextEntry(&entry_, |
- base::Bind(&ShaderDiskReadHelper::OnOpComplete, |
- weak_ptr_factory_.GetWeakPtr())); |
-} |
- |
-int ShaderDiskReadHelper::OpenNextEntryComplete(int rv) { |
- DCHECK(CalledOnValidThread()); |
- if (rv == net::ERR_FAILED) { |
- iter_.reset(); |
- op_type_ = ITERATION_FINISHED; |
- return net::OK; |
- } |
- |
- if (rv < 0) |
- return rv; |
- |
- op_type_ = READ_COMPLETE; |
- buf_ = new net::IOBufferWithSize(entry_->GetDataSize(1)); |
- return entry_->ReadData(1, 0, buf_.get(), buf_->size(), |
- base::Bind(&ShaderDiskReadHelper::OnOpComplete, |
- weak_ptr_factory_.GetWeakPtr())); |
-} |
- |
-int ShaderDiskReadHelper::ReadComplete(int rv) { |
- DCHECK(CalledOnValidThread()); |
- if (rv && rv == buf_->size() && !shader_loaded_callback_.is_null()) { |
- shader_loaded_callback_.Run(entry_->GetKey(), |
- std::string(buf_->data(), buf_->size())); |
- } |
- |
- buf_ = NULL; |
- entry_->Close(); |
- entry_ = NULL; |
- |
- op_type_ = OPEN_NEXT; |
- return net::OK; |
-} |
- |
-int ShaderDiskReadHelper::IterationComplete(int rv) { |
- DCHECK(CalledOnValidThread()); |
- iter_.reset(); |
- op_type_ = TERMINATE; |
- return net::OK; |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ShaderClearHelper |
- |
-ShaderClearHelper::ShaderClearHelper(ShaderCacheFactory* factory, |
- scoped_refptr<ShaderDiskCache> cache, |
- const base::FilePath& path, |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- const base::Closure& callback) |
- : factory_(factory), |
- cache_(std::move(cache)), |
- op_type_(VERIFY_CACHE_SETUP), |
- path_(path), |
- delete_begin_(delete_begin), |
- delete_end_(delete_end), |
- callback_(callback), |
- weak_ptr_factory_(this) {} |
- |
-ShaderClearHelper::~ShaderClearHelper() { |
- DCHECK(CalledOnValidThread()); |
-} |
- |
-void ShaderClearHelper::Clear() { |
- DCHECK(CalledOnValidThread()); |
- DoClearShaderCache(net::OK); |
-} |
- |
-void ShaderClearHelper::DoClearShaderCache(int rv) { |
- DCHECK(CalledOnValidThread()); |
- while (rv != net::ERR_IO_PENDING) { |
- switch (op_type_) { |
- case VERIFY_CACHE_SETUP: |
- rv = cache_->SetAvailableCallback( |
- base::Bind(&ShaderClearHelper::DoClearShaderCache, |
- weak_ptr_factory_.GetWeakPtr())); |
- op_type_ = DELETE_CACHE; |
- break; |
- case DELETE_CACHE: |
- rv = cache_->Clear(delete_begin_, delete_end_, |
- base::Bind(&ShaderClearHelper::DoClearShaderCache, |
- weak_ptr_factory_.GetWeakPtr())); |
- op_type_ = TERMINATE; |
- break; |
- case TERMINATE: |
- callback_.Run(); |
- // Calling CacheCleared() destroys |this|. |
- factory_->CacheCleared(path_); |
- rv = net::ERR_IO_PENDING; // Break the loop. |
- break; |
- } |
- } |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ShaderCacheFactory |
- |
-ShaderCacheFactory::ShaderCacheFactory( |
- scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) |
- : cache_task_runner_(std::move(cache_task_runner)) {} |
- |
-ShaderCacheFactory::~ShaderCacheFactory() { |
-} |
- |
-void ShaderCacheFactory::SetCacheInfo(int32_t client_id, |
- const base::FilePath& path) { |
- DCHECK(CalledOnValidThread()); |
- client_id_to_path_map_[client_id] = path; |
-} |
- |
-void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) { |
- DCHECK(CalledOnValidThread()); |
- client_id_to_path_map_.erase(client_id); |
-} |
- |
-scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) { |
- DCHECK(CalledOnValidThread()); |
- ClientIdToPathMap::iterator iter = client_id_to_path_map_.find(client_id); |
- if (iter == client_id_to_path_map_.end()) |
- return NULL; |
- return ShaderCacheFactory::GetByPath(iter->second); |
-} |
- |
-scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath( |
- const base::FilePath& path) { |
- DCHECK(CalledOnValidThread()); |
- ShaderCacheMap::iterator iter = shader_cache_map_.find(path); |
- if (iter != shader_cache_map_.end()) |
- return iter->second; |
- |
- ShaderDiskCache* cache = new ShaderDiskCache(this, path); |
- cache->Init(cache_task_runner_); |
- return cache; |
-} |
- |
-void ShaderCacheFactory::AddToCache(const base::FilePath& key, |
- ShaderDiskCache* cache) { |
- DCHECK(CalledOnValidThread()); |
- shader_cache_map_[key] = cache; |
-} |
- |
-void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) { |
- DCHECK(CalledOnValidThread()); |
- shader_cache_map_.erase(key); |
-} |
- |
-void ShaderCacheFactory::ClearByPath(const base::FilePath& path, |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- const base::Closure& callback) { |
- DCHECK(CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- auto helper = base::MakeUnique<ShaderClearHelper>( |
- this, GetByPath(path), path, delete_begin, delete_end, callback); |
- |
- // We could receive requests to clear the same path with different |
- // begin/end times. So, we keep a list of requests. If we haven't seen this |
- // path before we kick off the clear and add it to the list. If we have see it |
- // already, then we already have a clear running. We add this clear to the |
- // list and wait for any previous clears to finish. |
- ShaderClearMap::iterator iter = shader_clear_map_.find(path); |
- if (iter != shader_clear_map_.end()) { |
- iter->second.push(std::move(helper)); |
- return; |
- } |
- |
- // Insert the helper in the map before calling Clear(), since it can lead to a |
- // call back into CacheCleared(). |
- ShaderClearHelper* helper_ptr = helper.get(); |
- shader_clear_map_.insert( |
- std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue())); |
- shader_clear_map_[path].push(std::move(helper)); |
- helper_ptr->Clear(); |
-} |
- |
-void ShaderCacheFactory::CacheCleared(const base::FilePath& path) { |
- DCHECK(CalledOnValidThread()); |
- |
- ShaderClearMap::iterator iter = shader_clear_map_.find(path); |
- if (iter == shader_clear_map_.end()) { |
- LOG(ERROR) << "Completed clear but missing clear helper."; |
- return; |
- } |
- |
- iter->second.pop(); |
- |
- // If there are remaining items in the list we trigger the Clear on the |
- // next one. |
- if (!iter->second.empty()) { |
- iter->second.front()->Clear(); |
- return; |
- } |
- |
- shader_clear_map_.erase(iter); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// ShaderDiskCache |
- |
-ShaderDiskCache::ShaderDiskCache(ShaderCacheFactory* factory, |
- const base::FilePath& cache_path) |
- : factory_(factory), |
- cache_available_(false), |
- cache_path_(cache_path), |
- is_initialized_(false) { |
- factory_->AddToCache(cache_path_, this); |
-} |
- |
-ShaderDiskCache::~ShaderDiskCache() { |
- factory_->RemoveFromCache(cache_path_); |
-} |
- |
-void ShaderDiskCache::Init( |
- scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) { |
- if (is_initialized_) { |
- NOTREACHED(); // can't initialize disk cache twice. |
- return; |
- } |
- is_initialized_ = true; |
- |
- int rv = disk_cache::CreateCacheBackend( |
- net::SHADER_CACHE, net::CACHE_BACKEND_DEFAULT, |
- cache_path_.Append(kGpuCachePath), |
- gpu::kDefaultMaxProgramCacheMemoryBytes, true, cache_task_runner, NULL, |
- &backend_, base::Bind(&ShaderDiskCache::CacheCreatedCallback, this)); |
- |
- if (rv == net::OK) |
- cache_available_ = true; |
-} |
- |
-void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) { |
- if (!cache_available_) |
- return; |
- |
- auto shim = base::MakeUnique<ShaderDiskCacheEntry>(this, key, shader); |
- shim->Cache(); |
- auto* raw_ptr = shim.get(); |
- entries_.insert(std::make_pair(raw_ptr, std::move(shim))); |
-} |
- |
-int ShaderDiskCache::Clear( |
- const base::Time begin_time, const base::Time end_time, |
- const net::CompletionCallback& completion_callback) { |
- int rv; |
- if (begin_time.is_null()) { |
- rv = backend_->DoomAllEntries(completion_callback); |
- } else { |
- rv = backend_->DoomEntriesBetween(begin_time, end_time, |
- completion_callback); |
- } |
- return rv; |
-} |
- |
-int32_t ShaderDiskCache::Size() { |
- if (!cache_available_) |
- return -1; |
- return backend_->GetEntryCount(); |
-} |
- |
-int ShaderDiskCache::SetAvailableCallback( |
- const net::CompletionCallback& callback) { |
- if (cache_available_) |
- return net::OK; |
- available_callback_ = callback; |
- return net::ERR_IO_PENDING; |
-} |
- |
-void ShaderDiskCache::CacheCreatedCallback(int rv) { |
- if (rv != net::OK) { |
- LOG(ERROR) << "Shader Cache Creation failed: " << rv; |
- return; |
- } |
- helper_ = |
- base::MakeUnique<ShaderDiskReadHelper>(this, shader_loaded_callback_); |
- helper_->LoadCache(); |
-} |
- |
-void ShaderDiskCache::EntryComplete(ShaderDiskCacheEntry* entry) { |
- entries_.erase(entry); |
- if (entries_.empty() && !cache_complete_callback_.is_null()) |
- cache_complete_callback_.Run(net::OK); |
-} |
- |
-void ShaderDiskCache::ReadComplete() { |
- helper_ = nullptr; |
- |
- // The cache is considered available after we have finished reading any |
- // of the old cache values off disk. This prevents a potential race where we |
- // are reading from disk and execute a cache clear at the same time. |
- cache_available_ = true; |
- if (!available_callback_.is_null()) { |
- available_callback_.Run(net::OK); |
- available_callback_.Reset(); |
- } |
-} |
- |
-int ShaderDiskCache::SetCacheCompleteCallback( |
- const net::CompletionCallback& callback) { |
- if (entries_.empty()) { |
- return net::OK; |
- } |
- cache_complete_callback_ = callback; |
- return net::ERR_IO_PENDING; |
-} |
- |
-} // namespace content |