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