blob: 4838c32ac364df19b2c7b6d3ebef2b5289d5c4ef [file] [log] [blame]
/*
* 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/SharedContext.h"
#if defined(SK_ENABLE_PRECOMPILE)
#include "src/gpu/graphite/ContextUtils.h"
#include "src/gpu/graphite/GraphicsPipelineDesc.h"
#include "src/gpu/graphite/GraphicsPipelineHandle.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/PipelineCreationTask.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/RendererProvider.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/precompile/SerializationUtils.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) {
// ResourceProviders are not thread-safe. Here we create a ResourceProvider
// specifically for the thread on which precompilation will occur.
static constexpr size_t kEmptyBudget = 0;
fResourceProvider =
fSharedContext->makeResourceProvider(&fSingleOwner, SK_InvalidGenID, kEmptyBudget);
}
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();
GraphicsPipelineDesc pipelineDesc;
RenderPassDesc renderPassDesc;
if (!DataToPipelineDesc(caps,
fSharedContext->shaderCodeDictionary(),
serializedPipelineKey.get(),
&pipelineDesc,
&renderPassDesc)) {
return false;
}
GraphicsPipelineHandle handle = fResourceProvider->createGraphicsPipelineHandle(
pipelineDesc,
renderPassDesc,
PipelineCreationFlags::kForPrecompilation);
fResourceProvider->startPipelineCreationTask(rtEffectDict, handle);
return true;
#else
return false;
#endif
}
std::string PrecompileContext::getPipelineLabel(sk_sp<SkData> serializedPipelineKey) {
#if defined(SK_ENABLE_PRECOMPILE)
GraphicsPipelineDesc pipelineDesc;
RenderPassDesc renderPassDesc;
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 "";
}
return GetPipelineLabel(fSharedContext->shaderCodeDictionary(),
renderPassDesc,
renderStep,
pipelineDesc.paintParamsID());
#else
return "";
#endif
}
} // namespace skgpu::graphite