blob: 734c152521021ed64be3d0c49ff46f6d62689b73 [file]
/*
* 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 "include/private/SkLog.h"
#include "src/core/SkTraceEvent.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/PipelineManager.h"
#include "src/gpu/graphite/RenderPassDesc.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/SharedContext.h"
#include "src/gpu/graphite/Texture.h" // IWYU pragma: keep
#include "src/gpu/graphite/TextureProxy.h"
using namespace skia_private;
namespace skgpu::graphite {
DrawPass::DrawPass(sk_sp<TextureProxy> target,
std::pair<LoadOp, StoreOp> ops,
std::array<float, 4> clearColor)
: fTarget(std::move(target))
, fBounds(SkIRect::MakeEmpty())
, fOps(ops)
, fClearColor(clearColor) {}
DrawPass::~DrawPass() = default;
bool DrawPass::prepareResources(ResourceProvider* resourceProvider,
sk_sp<const RuntimeEffectDictionary> runtimeDict,
const RenderPassDesc& renderPassDesc) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
SharedContext* sharedContext = resourceProvider->sharedContext();
PipelineManager* pipelineManager = sharedContext->pipelineManager();
fPipelineHandles.reserve(fPipelineDescs.size());
for (const GraphicsPipelineDesc& pipelineDesc : fPipelineDescs) {
fPipelineHandles.push_back(
pipelineManager->createHandle(sharedContext,
runtimeDict,
pipelineDesc,
renderPassDesc,
PipelineCreationFlags::kNone));
}
// 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();
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()) {
SKIA_LOG_W("Cannot sample from an uninstantiated TextureProxy, label %s",
fSampledTextures[i]->label());
return false;
}
}
return true;
}
bool DrawPass::addResourceRefs(ResourceProvider* resourceProvider,
CommandBuffer* commandBuffer) {
TRACE_EVENT1_ALWAYS("skia.shaders",
"GraphitePipelineUse",
"# pipelines",
fPipelineHandles.size());
SharedContext* sharedContext = resourceProvider->sharedContext();
PipelineManager* pipelineManager = sharedContext->pipelineManager();
SkASSERT(fPipelineHandles.size() == fPipelineDrawAreas.size());
for (int i = 0; i < fPipelineHandles.size(); ++i) {
sk_sp<GraphicsPipeline> pipeline = pipelineManager->resolveHandle(sharedContext,
fPipelineHandles[i]);
if (!pipeline) {
SKIA_LOG_W("Failed to create Pipeline for draw in RenderPass. Dropping draw!");
return false;
}
TRACE_EVENT_INSTANT1_ALWAYS(
"skia.shaders",
TRACE_STR_COPY(pipeline->getLabel()),
TRACE_EVENT_SCOPE_THREAD,
"area", sk_float_saturate2int(fPipelineDrawAreas[i]));
commandBuffer->trackResource(std::move(pipeline));
}
SkDEBUGCODE(fPipelinesHaveBeenResolved = true;)
for (int i = 0; i < fSampledTextures.size(); ++i) {
commandBuffer->trackResource(fSampledTextures[i]->refTexture());
}
return true;
}
} // namespace skgpu::graphite