| /* | |
| * Copyright 2024 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "include/gpu/graphite/PrecompileContext.h" | |
| #include "include/core/SkTypes.h" | |
| #include "src/gpu/GpuTypesPriv.h" | |
| #include "src/gpu/graphite/GlobalCache.h" | |
| #include "src/gpu/graphite/ResourceProvider.h" | |
| #include "src/gpu/graphite/SerializationUtils.h" | |
| #include "src/gpu/graphite/SharedContext.h" | |
| #if defined(SK_ENABLE_PRECOMPILE) | |
| #include "include/private/SkLog.h" | |
| #include "src/gpu/graphite/ContextUtils.h" | |
| #include "src/gpu/graphite/GraphicsPipelineDesc.h" | |
| #include "src/gpu/graphite/GraphicsPipelineHandle.h" | |
| #include "src/gpu/graphite/PipelineCreationTask.h" | |
| #include "src/gpu/graphite/PipelineManager.h" | |
| #include "src/gpu/graphite/RenderPassDesc.h" | |
| #include "src/gpu/graphite/RendererProvider.h" | |
| #include "src/gpu/graphite/RuntimeEffectDictionary.h" | |
| #endif | |
| #include <cstddef> | |
| namespace skgpu::graphite { | |
| #define ASSERT_SINGLE_OWNER SKGPU_ASSERT_SINGLE_OWNER(&fSingleOwner) | |
| PrecompileContext::~PrecompileContext() { | |
| ASSERT_SINGLE_OWNER | |
| } | |
| PrecompileContext::PrecompileContext(sk_sp<SharedContext> sharedContext) | |
| : fSharedContext(sharedContext) { | |
| } | |
| void PrecompileContext::purgePipelinesNotUsedInMs(std::chrono::milliseconds msNotUsed) { | |
| ASSERT_SINGLE_OWNER | |
| auto purgeTime = skgpu::StdSteadyClock::now() - msNotUsed; | |
| fSharedContext->globalCache()->purgePipelinesNotUsedSince(purgeTime); | |
| } | |
| void PrecompileContext::reportPipelineStats(StatOptions option) { | |
| ASSERT_SINGLE_OWNER | |
| if (option == StatOptions::kPrecompile) { | |
| fSharedContext->globalCache()->reportPrecompileStats(); | |
| } else { | |
| fSharedContext->globalCache()->reportCacheStats(); | |
| } | |
| } | |
| bool PrecompileContext::precompile(sk_sp<SkData> serializedPipelineKey) { | |
| #if defined(SK_ENABLE_PRECOMPILE) | |
| sk_sp<RuntimeEffectDictionary> rtEffectDict = sk_make_sp<RuntimeEffectDictionary>(); | |
| const Caps* caps = fSharedContext->caps(); | |
| PipelineManager* pipelineManager = fSharedContext->pipelineManager(); | |
| GraphicsPipelineDesc pipelineDesc; | |
| RenderPassDesc renderPassDesc; | |
| if (!DataToPipelineDesc(caps, | |
| fSharedContext->shaderCodeDictionary(), | |
| serializedPipelineKey.get(), | |
| &pipelineDesc, | |
| &renderPassDesc)) { | |
| return false; | |
| } | |
| GraphicsPipelineHandle handle = pipelineManager->createHandle( | |
| fSharedContext.get(), | |
| rtEffectDict, | |
| pipelineDesc, | |
| renderPassDesc, | |
| PipelineCreationFlags::kForPrecompilation); | |
| return true; | |
| #else | |
| return false; | |
| #endif | |
| } | |
| std::string PrecompileContext::getPipelineLabel(sk_sp<SkData> serializedPipelineKey, | |
| uint32_t* uniqueHash) { | |
| if (uniqueHash) { *uniqueHash = 0; } | |
| #if defined(SK_ENABLE_PRECOMPILE) | |
| GraphicsPipelineDesc pipelineDesc; | |
| RenderPassDesc renderPassDesc; | |
| // Deep in deserialize_graphics_pipeline_desc, this will have unpacked the PaintParamsKey | |
| // and then registered it with the ShaderCodeDictionary to get this session's | |
| // UniquePaintParamsID for it. | |
| if (!DataToPipelineDesc(fSharedContext->caps(), | |
| fSharedContext->shaderCodeDictionary(), | |
| serializedPipelineKey.get(), | |
| &pipelineDesc, | |
| &renderPassDesc)) { | |
| return ""; | |
| } | |
| const RendererProvider* rendererProvider = fSharedContext->rendererProvider(); | |
| const RenderStep* renderStep = rendererProvider->lookup(pipelineDesc.renderStepID()); | |
| if (!renderStep) { | |
| return ""; | |
| } | |
| if (uniqueHash) { | |
| const Caps* caps = fSharedContext->caps(); | |
| // This will make use of the UniquePaintParamsID registered in DataToPipelineDesc. | |
| UniqueKey pipelineKey = caps->makeGraphicsPipelineKey(pipelineDesc, renderPassDesc); | |
| *uniqueHash = pipelineKey.hash(); | |
| } | |
| return GetPipelineLabel(fSharedContext->caps(), | |
| fSharedContext->shaderCodeDictionary(), | |
| renderPassDesc, | |
| renderStep, | |
| pipelineDesc.paintParamsID()); | |
| #else | |
| return ""; | |
| #endif | |
| } | |
| PrecompileContext::ExternalFormatResult PrecompileContext::containsExternalFormat( | |
| sk_sp<SkData> serializedPipelineKey) const { | |
| #if defined(SK_ENABLE_PRECOMPILE) | |
| bool containsExtFormat = false; | |
| if (!DataContainsExternalFormat(fSharedContext->caps(), fSharedContext->shaderCodeDictionary(), | |
| serializedPipelineKey.get(), &containsExtFormat)) { | |
| return ExternalFormatResult::kInvalid; | |
| } | |
| return containsExtFormat ? ExternalFormatResult::kHasExternalFormat | |
| : ExternalFormatResult::kNoExternalFormat; | |
| #else | |
| return ExternalFormatResult::kInvalid; | |
| #endif | |
| } | |
| } // namespace skgpu::graphite |