| // Copyright 2025 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "gpu/command_buffer/service/gpu_persistent_cache.h" |
| |
| #include <string_view> |
| |
| #include "base/containers/span.h" |
| #include "base/dcheck_is_on.h" |
| #include "base/logging.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "base/synchronization/lock_subtle.h" |
| #include "base/timer/elapsed_timer.h" |
| #include "base/trace_event/trace_event.h" |
| #include "components/persistent_cache/entry.h" |
| #include "components/persistent_cache/persistent_cache.h" |
| |
| namespace gpu { |
| |
| // We have to enable lock tracking to allow PersistentCache to be used on |
| // multiple threads/different sequences. |
| #if DCHECK_IS_ON() |
| #define SCOPED_LOCK(lock) \ |
| base::AutoLock auto_lock(lock, base::subtle::LockTracking::kEnabled) |
| #else |
| #define SCOPED_LOCK(lock) base::AutoLock auto_lock(lock) |
| #endif // DCHECK_IS_ON() |
| |
| GpuPersistentCache::GpuPersistentCache(std::string_view cache_prefix) |
| : cache_prefix_(cache_prefix) {} |
| |
| GpuPersistentCache::~GpuPersistentCache() { |
| SCOPED_LOCK(lock_); |
| persistent_cache_.reset(); |
| } |
| |
| void GpuPersistentCache::InitializeCache( |
| persistent_cache::BackendParams backend_params) { |
| SCOPED_LOCK(lock_); |
| persistent_cache_ = |
| persistent_cache::PersistentCache::Open(std::move(backend_params)); |
| } |
| |
| size_t GpuPersistentCache::LoadData(const void* key, |
| size_t key_size, |
| void* value, |
| size_t value_size) { |
| SCOPED_LOCK(lock_); |
| TRACE_EVENT1("gpu", "GpuPersistentCache::LoadData", "persistent_cache_", |
| !!persistent_cache_); |
| base::UmaHistogramBoolean(GetHistogramName("Load.CacheAvailable"), |
| !!persistent_cache_); |
| if (!persistent_cache_) { |
| return 0; |
| } |
| |
| base::ElapsedTimer timer; |
| std::string_view key_str(static_cast<const char*>(key), key_size); |
| std::unique_ptr<persistent_cache::Entry> entry = |
| persistent_cache_->Find(key_str); |
| |
| if (!entry) { |
| return 0; |
| } |
| |
| size_t bytes_copied = 0; |
| if (value_size > 0) { |
| bytes_copied = entry->CopyContentTo( |
| UNSAFE_TODO(base::span(static_cast<uint8_t*>(value), value_size))); |
| } |
| |
| base::UmaHistogramCustomMicrosecondsTimes( |
| GetHistogramName("Load"), timer.Elapsed(), base::Microseconds(1), |
| base::Seconds(30), 100); |
| |
| if (bytes_copied > 0) { |
| return bytes_copied; |
| } |
| |
| return entry->GetContentSize(); |
| } |
| |
| void GpuPersistentCache::StoreData(const void* key, |
| size_t key_size, |
| const void* value, |
| size_t value_size) { |
| SCOPED_LOCK(lock_); |
| TRACE_EVENT1("gpu", "GpuPersistentCache::StoreData", "persistent_cache_", |
| !!persistent_cache_); |
| base::UmaHistogramBoolean(GetHistogramName("Store.CacheAvailable"), |
| !!persistent_cache_); |
| if (!persistent_cache_) { |
| return; |
| } |
| |
| std::string_view key_str(static_cast<const char*>(key), key_size); |
| persistent_cache_->Insert( |
| key_str, |
| UNSAFE_TODO(base::span(static_cast<const uint8_t*>(value), value_size))); |
| } |
| |
| std::string GpuPersistentCache::GetHistogramName( |
| std::string_view metric) const { |
| return "GPU.PersistentCache." + cache_prefix_ + "." + std::string(metric); |
| } |
| |
| } // namespace gpu |