1 /* 2 * Copyright 2021 Google LLC. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef PathStencilCoverOp_DEFINED 9 #define PathStencilCoverOp_DEFINED 10 11 #include "src/gpu/ops/FillPathFlags.h" 12 #include "src/gpu/ops/GrDrawOp.h" 13 #include "src/gpu/tessellate/PathTessellator.h" 14 #include "src/gpu/tessellate/shaders/GrTessellationShader.h" 15 16 namespace skgpu::v1 { 17 18 // Draws paths using a standard Redbook "stencil then cover" method. Curves get linearized by either 19 // GPU tessellation shaders or indirect draws. This Op doesn't apply analytic AA, so it requires 20 // MSAA if AA is desired. 21 class PathStencilCoverOp final : public GrDrawOp { 22 private: 23 DEFINE_OP_CLASS_ID 24 25 using PathDrawList = PathTessellator::PathDrawList; 26 27 // If the path is inverse filled, drawBounds must be the entire backing store dimensions of the 28 // render target. PathStencilCoverOp(SkArenaAlloc * arena,const SkMatrix & viewMatrix,const SkPath & path,GrPaint && paint,GrAAType aaType,FillPathFlags pathFlags,const SkRect & drawBounds)29 PathStencilCoverOp(SkArenaAlloc* arena, 30 const SkMatrix& viewMatrix, 31 const SkPath& path, 32 GrPaint&& paint, 33 GrAAType aaType, 34 FillPathFlags pathFlags, 35 const SkRect& drawBounds) 36 : GrDrawOp(ClassID()) 37 , fPathDrawList(arena->make<PathDrawList>(viewMatrix, path, SK_PMColor4fTRANSPARENT)) 38 , fTotalCombinedPathVerbCnt(path.countVerbs()) 39 , fPathCount(1) 40 , fPathFlags(pathFlags) 41 , fAAType(aaType) 42 , fColor(paint.getColor4f()) 43 , fProcessors(std::move(paint)) { 44 this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo); 45 SkDEBUGCODE(fOriginalDrawBounds = drawBounds;) 46 } 47 48 // Constructs a PathStencilCoverOp from an existing draw list. 49 // FIXME: The only user of this method is the atlas. We should move the GrProgramInfos into 50 // PathTessellator so the atlas can use that directly instead of going through this class. PathStencilCoverOp(const PathDrawList * pathDrawList,int totalCombinedVerbCnt,int pathCount,GrPaint && paint,GrAAType aaType,FillPathFlags pathFlags,const SkRect & drawBounds)51 PathStencilCoverOp(const PathDrawList* pathDrawList, 52 int totalCombinedVerbCnt, 53 int pathCount, 54 GrPaint&& paint, 55 GrAAType aaType, 56 FillPathFlags pathFlags, 57 const SkRect& drawBounds) 58 : GrDrawOp(ClassID()) 59 , fPathDrawList(pathDrawList) 60 , fTotalCombinedPathVerbCnt(totalCombinedVerbCnt) 61 , fPathCount(pathCount) 62 , fPathFlags(pathFlags) 63 , fAAType(aaType) 64 , fColor(paint.getColor4f()) 65 , fProcessors(std::move(paint)) { 66 this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo); 67 SkDEBUGCODE(fOriginalDrawBounds = drawBounds;) 68 } 69 name()70 const char* name() const override { return "PathStencilCoverOp"; } 71 void visitProxies(const GrVisitProxyFunc&) const override; 72 FixedFunctionFlags fixedFunctionFlags() const override; 73 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override; 74 75 // All paths in fPathDrawList are required to have the same fill type. pathFillType()76 SkPathFillType pathFillType() const { 77 return fPathDrawList->fPath.getFillType(); 78 } 79 80 // Chooses the rendering method we will use and creates the corresponding tessellator and 81 // stencil/cover programs. 82 void prePreparePrograms(const GrTessellationShader::ProgramArgs&, GrAppliedClip&& clip); 83 84 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*, 85 const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override; 86 void onPrepare(GrOpFlushState*) override; 87 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; 88 89 const PathDrawList* fPathDrawList; 90 const int fTotalCombinedPathVerbCnt; 91 const int fPathCount; 92 const FillPathFlags fPathFlags; 93 const GrAAType fAAType; 94 SkPMColor4f fColor; 95 GrProcessorSet fProcessors; 96 SkDEBUGCODE(SkRect fOriginalDrawBounds;) 97 98 // Decided during prePreparePrograms. 99 PathTessellator* fTessellator = nullptr; 100 const GrProgramInfo* fStencilFanProgram = nullptr; 101 const GrProgramInfo* fStencilPathProgram = nullptr; 102 const GrProgramInfo* fCoverBBoxProgram = nullptr; 103 104 // Filled during onPrepare. 105 sk_sp<const GrBuffer> fFanBuffer; 106 int fFanBaseVertex = 0; 107 int fFanVertexCount = 0; 108 109 sk_sp<const GrBuffer> fBBoxBuffer; 110 int fBBoxBaseInstance = 0; 111 112 // Only used if sk_VertexID is not supported. 113 sk_sp<const GrGpuBuffer> fBBoxVertexBufferIfNoIDSupport; 114 115 friend class GrOp; // For ctor. 116 }; 117 118 } // namespace skgpu::v1 119 120 #endif // PathStencilCoverOp_DEFINED 121