2 * Copyright 2021 Google LLC.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "src/gpu/ganesh/ops/PathTessellateOp.h"
10 #include "src/gpu/ganesh/GrAppliedClip.h"
11 #include "src/gpu/ganesh/GrOpFlushState.h"
12 #include "src/gpu/ganesh/tessellate/GrPathTessellationShader.h"
15 void PathTessellateOp::visitProxies(const GrVisitProxyFunc& func) const {
16 if (fTessellationProgram) {
17 fTessellationProgram->pipeline().visitProxies(func);
19 fProcessors.visitProxies(func);
23 GrProcessorSet::Analysis PathTessellateOp::finalize(const GrCaps& caps,
24 const GrAppliedClip* clip,
25 GrClampType clampType) {
26 auto analysis = fProcessors.finalize(this->headDraw().fColor,
27 GrProcessorAnalysisCoverage::kNone,
32 &this->headDraw().fColor);
33 if (!analysis.usesLocalCoords()) {
34 // Since we don't need local coords, we can transform on CPU instead of in the shader. This
35 // gives us better batching potential.
36 this->headDraw().fPathMatrix = fShaderMatrix;
37 fShaderMatrix = SkMatrix::I();
42 GrDrawOp::CombineResult PathTessellateOp::onCombineIfPossible(GrOp* grOp,
45 auto* op = grOp->cast<PathTessellateOp>();
46 bool canMerge = fAAType == op->fAAType &&
47 fStencil == op->fStencil &&
48 fProcessors == op->fProcessors &&
49 fShaderMatrix == op->fShaderMatrix;
51 fTotalCombinedPathVerbCnt += op->fTotalCombinedPathVerbCnt;
52 fPatchAttribs |= op->fPatchAttribs;
54 if (!(fPatchAttribs & PatchAttribs::kColor) &&
55 this->headDraw().fColor != op->headDraw().fColor) {
56 // Color is no longer uniform. Move it into patch attribs.
57 fPatchAttribs |= PatchAttribs::kColor;
60 *fPathDrawTail = op->fPathDrawList;
61 fPathDrawTail = op->fPathDrawTail;
62 return CombineResult::kMerged;
65 return CombineResult::kCannotCombine;
68 void PathTessellateOp::prepareTessellator(const GrTessellationShader::ProgramArgs& args,
69 GrAppliedClip&& appliedClip) {
70 SkASSERT(!fTessellator);
71 SkASSERT(!fTessellationProgram);
72 auto* pipeline = GrTessellationShader::MakePipeline(args, fAAType, std::move(appliedClip),
73 std::move(fProcessors));
74 fTessellator = PathWedgeTessellator::Make(args.fArena,
75 args.fCaps->shaderCaps()->infinitySupport(),
77 auto* tessShader = GrPathTessellationShader::Make(*args.fCaps->shaderCaps(),
80 this->headDraw().fColor,
81 fTessellator->patchAttribs());
82 fTessellationProgram = GrTessellationShader::MakeProgram(args, tessShader, pipeline, fStencil);
85 void PathTessellateOp::onPrePrepare(GrRecordingContext* context,
86 const GrSurfaceProxyView& writeView, GrAppliedClip* clip,
87 const GrDstProxyView& dstProxyView,
88 GrXferBarrierFlags renderPassXferBarriers,
89 GrLoadOp colorLoadOp) {
90 // DMSAA is not supported on DDL.
91 bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
92 this->prepareTessellator({context->priv().recordTimeAllocator(), writeView, usesMSAASurface,
93 &dstProxyView, renderPassXferBarriers, colorLoadOp,
94 context->priv().caps()},
95 (clip) ? std::move(*clip) : GrAppliedClip::Disabled());
96 SkASSERT(fTessellationProgram);
97 context->priv().recordProgramInfo(fTessellationProgram);
100 void PathTessellateOp::onPrepare(GrOpFlushState* flushState) {
102 this->prepareTessellator({flushState->allocator(), flushState->writeView(),
103 flushState->usesMSAASurface(), &flushState->dstProxyView(),
104 flushState->renderPassBarriers(), flushState->colorLoadOp(),
105 &flushState->caps()}, flushState->detachAppliedClip());
106 SkASSERT(fTessellator);
108 fTessellator->prepare(flushState,
111 fTotalCombinedPathVerbCnt);
114 void PathTessellateOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
115 SkASSERT(fTessellator);
116 SkASSERT(fTessellationProgram);
117 flushState->bindPipelineAndScissorClip(*fTessellationProgram, this->bounds());
118 flushState->bindTextures(fTessellationProgram->geomProc(), nullptr,
119 fTessellationProgram->pipeline());
120 fTessellator->draw(flushState);
123 } // namespace skgpu::v1