| /* |
| * 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/ganesh/ops/PathTessellateOp.h" |
| |
| #include "src/gpu/ganesh/GrAppliedClip.h" |
| #include "src/gpu/ganesh/GrCaps.h" |
| #include "src/gpu/ganesh/GrOpFlushState.h" |
| #include "src/gpu/ganesh/GrRecordingContextPriv.h" |
| #include "src/gpu/ganesh/tessellate/GrPathTessellationShader.h" |
| |
| namespace skgpu::ganesh { |
| |
| void PathTessellateOp::visitProxies(const GrVisitProxyFunc& func) const { |
| if (fTessellationProgram) { |
| fTessellationProgram->pipeline().visitProxies(func); |
| } else { |
| fProcessors.visitProxies(func); |
| } |
| } |
| |
| GrProcessorSet::Analysis PathTessellateOp::finalize(const GrCaps& caps, |
| const GrAppliedClip* clip, |
| GrClampType clampType) { |
| auto analysis = fProcessors.finalize(this->headDraw().fColor, |
| GrProcessorAnalysisCoverage::kNone, |
| clip, |
| nullptr, |
| caps, |
| clampType, |
| &this->headDraw().fColor); |
| if (!analysis.usesLocalCoords()) { |
| // Since we don't need local coords, we can transform on CPU instead of in the shader. This |
| // gives us better batching potential. |
| this->headDraw().fPathMatrix = fShaderMatrix; |
| fShaderMatrix = SkMatrix::I(); |
| } |
| return analysis; |
| } |
| |
| GrDrawOp::CombineResult PathTessellateOp::onCombineIfPossible(GrOp* grOp, |
| SkArenaAlloc*, |
| const GrCaps&) { |
| auto* op = grOp->cast<PathTessellateOp>(); |
| bool canMerge = fAAType == op->fAAType && |
| fStencil == op->fStencil && |
| fProcessors == op->fProcessors && |
| fShaderMatrix == op->fShaderMatrix; |
| if (canMerge) { |
| fTotalCombinedPathVerbCnt += op->fTotalCombinedPathVerbCnt; |
| fPatchAttribs |= op->fPatchAttribs; |
| |
| if (!(fPatchAttribs & PatchAttribs::kColor) && |
| this->headDraw().fColor != op->headDraw().fColor) { |
| // Color is no longer uniform. Move it into patch attribs. |
| fPatchAttribs |= PatchAttribs::kColor; |
| } |
| |
| *fPathDrawTail = op->fPathDrawList; |
| fPathDrawTail = op->fPathDrawTail; |
| return CombineResult::kMerged; |
| } |
| |
| return CombineResult::kCannotCombine; |
| } |
| |
| void PathTessellateOp::prepareTessellator(const GrTessellationShader::ProgramArgs& args, |
| GrAppliedClip&& appliedClip) { |
| SkASSERT(!fTessellator); |
| SkASSERT(!fTessellationProgram); |
| auto* pipeline = GrTessellationShader::MakePipeline(args, fAAType, std::move(appliedClip), |
| std::move(fProcessors)); |
| fTessellator = PathWedgeTessellator::Make(args.fArena, |
| args.fCaps->shaderCaps()->fInfinitySupport, |
| fPatchAttribs); |
| auto* tessShader = GrPathTessellationShader::Make(*args.fCaps->shaderCaps(), |
| args.fArena, |
| fShaderMatrix, |
| this->headDraw().fColor, |
| fTessellator->patchAttribs()); |
| fTessellationProgram = GrTessellationShader::MakeProgram(args, tessShader, pipeline, fStencil); |
| } |
| |
| void PathTessellateOp::onPrePrepare(GrRecordingContext* context, |
| const GrSurfaceProxyView& writeView, GrAppliedClip* clip, |
| const GrDstProxyView& dstProxyView, |
| GrXferBarrierFlags renderPassXferBarriers, |
| GrLoadOp colorLoadOp) { |
| // DMSAA is not supported on DDL. |
| bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1; |
| this->prepareTessellator({context->priv().recordTimeAllocator(), writeView, usesMSAASurface, |
| &dstProxyView, renderPassXferBarriers, colorLoadOp, |
| context->priv().caps()}, |
| (clip) ? std::move(*clip) : GrAppliedClip::Disabled()); |
| SkASSERT(fTessellationProgram); |
| context->priv().recordProgramInfo(fTessellationProgram); |
| } |
| |
| void PathTessellateOp::onPrepare(GrOpFlushState* flushState) { |
| if (!fTessellator) { |
| this->prepareTessellator({flushState->allocator(), flushState->writeView(), |
| flushState->usesMSAASurface(), &flushState->dstProxyView(), |
| flushState->renderPassBarriers(), flushState->colorLoadOp(), |
| &flushState->caps()}, flushState->detachAppliedClip()); |
| SkASSERT(fTessellator); |
| } |
| fTessellator->prepare(flushState, |
| fShaderMatrix, |
| *fPathDrawList, |
| fTotalCombinedPathVerbCnt); |
| } |
| |
| void PathTessellateOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { |
| SkASSERT(fTessellator); |
| SkASSERT(fTessellationProgram); |
| flushState->bindPipelineAndScissorClip(*fTessellationProgram, this->bounds()); |
| flushState->bindTextures(fTessellationProgram->geomProc(), nullptr, |
| fTessellationProgram->pipeline()); |
| fTessellator->draw(flushState); |
| } |
| |
| } // namespace skgpu::ganesh |