/* * Copyright 2022 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/gpu/graphite/GlobalCache.h" #include "src/gpu/graphite/ComputePipeline.h" #include "src/gpu/graphite/ContextUtils.h" #include "src/gpu/graphite/GraphicsPipeline.h" #include "src/gpu/graphite/Resource.h" namespace skgpu::graphite { GlobalCache::GlobalCache() : fGraphicsPipelineCache(256) // TODO: find a good value for these limits , fComputePipelineCache(256) {} GlobalCache::~GlobalCache() { // These should have been cleared out earlier by deleteResources(). SkDEBUGCODE(SkAutoSpinlock lock{ fSpinLock }); SkASSERT(fGraphicsPipelineCache.count() == 0); SkASSERT(fComputePipelineCache.count() == 0); SkASSERT(fStaticResource.size() == 0); } void GlobalCache::deleteResources() { SkAutoSpinlock lock{ fSpinLock }; fGraphicsPipelineCache.reset(); fComputePipelineCache.reset(); fStaticResource.clear(); } sk_sp GlobalCache::findGraphicsPipeline(const UniqueKey& key) { SkAutoSpinlock lock{fSpinLock}; sk_sp* entry = fGraphicsPipelineCache.find(key); return entry ? *entry : nullptr; } sk_sp GlobalCache::addGraphicsPipeline(const UniqueKey& key, sk_sp pipeline) { SkAutoSpinlock lock{fSpinLock}; sk_sp* entry = fGraphicsPipelineCache.find(key); if (!entry) { // No equivalent pipeline was stored in the cache between a previous call to // findGraphicsPipeline() that returned null (triggering the pipeline creation) and this // later adding to the cache. entry = fGraphicsPipelineCache.insert(key, std::move(pipeline)); } // else there was a race creating the same pipeline and this thread lost, so return the winner return *entry; } #if defined(GRAPHITE_TEST_UTILS) int GlobalCache::numGraphicsPipelines() const { SkAutoSpinlock lock{fSpinLock}; return fGraphicsPipelineCache.count(); } void GlobalCache::resetGraphicsPipelines() { SkAutoSpinlock lock{fSpinLock}; fGraphicsPipelineCache.reset(); } void GlobalCache::forEachGraphicsPipeline( const std::function& fn) { SkAutoSpinlock lock{fSpinLock}; fGraphicsPipelineCache.foreach([&](const UniqueKey* k, const sk_sp* v) { fn(*k, v->get()); }); } #endif // defined(GRAPHITE_TEST_UTILS) sk_sp GlobalCache::findComputePipeline(const UniqueKey& key) { SkAutoSpinlock lock{fSpinLock}; sk_sp* entry = fComputePipelineCache.find(key); return entry ? *entry : nullptr; } sk_sp GlobalCache::addComputePipeline(const UniqueKey& key, sk_sp pipeline) { SkAutoSpinlock lock{fSpinLock}; sk_sp* entry = fComputePipelineCache.find(key); if (!entry) { entry = fComputePipelineCache.insert(key, std::move(pipeline)); } return *entry; } void GlobalCache::addStaticResource(sk_sp resource) { SkAutoSpinlock lock{fSpinLock}; fStaticResource.push_back(std::move(resource)); } } // namespace skgpu::graphite