blob: 254cfb6c4da0400b124eeb9a7668e157e7495dcb [file] [log] [blame]
/*
* Copyright 2021 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/DrawPass.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/PaintParams.h"
#include "src/gpu/graphite/PaintParamsKey.h"
#include "src/gpu/graphite/PipelineCreationTask.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/Resource.h" // IWYU pragma: keep
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/ResourceTypes.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/Texture.h" // IWYU pragma: keep
#include "src/gpu/graphite/TextureProxy.h"
#if defined(SK_TRACE_GRAPHITE_PIPELINE_USE)
#include "src/gpu/graphite/RenderPassDesc.h"
#endif
using namespace skia_private;
namespace skgpu::graphite {
DrawPass::DrawPass(sk_sp<TextureProxy> target,
std::pair<LoadOp, StoreOp> ops,
std::array<float, 4> clearColor,
sk_sp<FloatStorageManager> floatStorageManager)
: fTarget(std::move(target))
, fBounds(SkIRect::MakeEmpty())
, fOps(ops)
, fClearColor(clearColor)
, fFloatStorageManager(floatStorageManager) {}
DrawPass::~DrawPass() = default;
bool DrawPass::prepareResources(ResourceProvider* resourceProvider,
sk_sp<const RuntimeEffectDictionary> runtimeDict,
const RenderPassDesc& renderPassDesc) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
fPipelineHandles.reserve(fPipelineDescs.size());
for (const GraphicsPipelineDesc& pipelineDesc : fPipelineDescs) {
fPipelineHandles.push_back(
resourceProvider->createGraphicsPipelineHandle(pipelineDesc,
renderPassDesc,
PipelineCreationFlags::kNone));
resourceProvider->startPipelineCreationTask(runtimeDict, fPipelineHandles.back());
}
// The DrawPass may be long lived on a Recording and we no longer need the GraphicPipelineDescs
// once we've created pipeline handles, so we drop the storage for them here.
fPipelineDescs.clear();
// TODO(robertphillips): move this resolvePipeline loop to addResourceRefs
fFullPipelines.reserve(fPipelineHandles.size());
for (const GraphicsPipelineHandle& handle : fPipelineHandles) {
sk_sp<GraphicsPipeline> pipeline = resourceProvider->resolveHandle(handle);
if (!pipeline) {
SKGPU_LOG_W("Failed to create GraphicsPipeline for draw in RenderPass. Dropping pass!");
return false;
}
fFullPipelines.push_back(std::move(pipeline));
}
fPipelineHandles.clear();
for (int i = 0; i < fSampledTextures.size(); ++i) {
// It should not have been possible to draw an Image that has an invalid texture info
SkASSERT(fSampledTextures[i]->textureInfo().isValid());
// Tasks should have been ordered to instantiate any scratch textures already, or any
// client-owned image will have been instantiated at creation. However, if a TextureProxy
// was cached for reuse across Recordings, it's possible that the initializing Recording
// failed, leaving the TextureProxy in a bad state (and currently with no way to reconstruct
// the tasks required to initialize it).
// TODO(b/409888039): Once TextureProxies track their dependendent tasks to include in all
// Recordings, this "should" be able to changed to asserts.
if (!fSampledTextures[i]->isInstantiated() && !fSampledTextures[i]->isLazy()) {
SKGPU_LOG_W("Cannot sample from an uninstantiated TextureProxy, label %s",
fSampledTextures[i]->label());
return false;
}
}
#if defined(SK_TRACE_GRAPHITE_PIPELINE_USE)
{
TRACE_EVENT0_ALWAYS("skia.shaders", "GraphitePipelineUse");
TRACE_EVENT0_ALWAYS("skia.shaders", TRACE_STR_COPY(renderPassDesc.toString().c_str()));
for (int i = 0 ; i < fFullPipelines.size(); ++i) {
TRACE_EVENT_INSTANT1_ALWAYS(
"skia.shaders",
TRACE_STR_COPY(fFullPipelines[i]->getPipelineInfo().fLabel.c_str()),
TRACE_EVENT_SCOPE_THREAD,
"area", sk_float_saturate2int(fPipelineDrawAreas[i]));
}
}
#endif
return true;
}
bool DrawPass::addResourceRefs(ResourceProvider* resourceProvider,
CommandBuffer* commandBuffer) {
for (int i = 0; i < fFullPipelines.size(); ++i) {
commandBuffer->trackResource(fFullPipelines[i]);
}
for (int i = 0; i < fSampledTextures.size(); ++i) {
commandBuffer->trackCommandBufferResource(fSampledTextures[i]->refTexture());
}
return true;
}
} // namespace skgpu::graphite