1 /* 2 * Copyright 2019 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 PathInnerTriangulateOp_DEFINED 9 #define PathInnerTriangulateOp_DEFINED 10 11 #include "src/gpu/geometry/GrInnerFanTriangulator.h" 12 #include "src/gpu/ops/FillPathFlags.h" 13 #include "src/gpu/ops/GrDrawOp.h" 14 #include "src/gpu/tessellate/shaders/GrTessellationShader.h" 15 16 namespace skgpu { 17 18 class PathCurveTessellator; 19 20 }; 21 22 namespace skgpu::v1 { 23 24 // This op is a 3-pass twist on the standard Redbook "stencil then cover" algorithm: 25 // 26 // 1) Tessellate the path's outer curves into the stencil buffer. 27 // 2) Triangulate the path's inner fan and fill it with a stencil test against the curves. 28 // 3) Draw convex hulls around each curve that fill in remaining samples. 29 // 30 // In practice, a path's inner fan takes up a large majority of its pixels. So from a GPU load 31 // perspective, this op is effectively as fast as a single-pass algorithm. 32 class PathInnerTriangulateOp final : public GrDrawOp { 33 private: 34 DEFINE_OP_CLASS_ID 35 PathInnerTriangulateOp(const SkMatrix & viewMatrix,const SkPath & path,GrPaint && paint,GrAAType aaType,FillPathFlags pathFlags,const SkRect & drawBounds)36 PathInnerTriangulateOp(const SkMatrix& viewMatrix, 37 const SkPath& path, 38 GrPaint&& paint, 39 GrAAType aaType, 40 FillPathFlags pathFlags, 41 const SkRect& drawBounds) 42 : GrDrawOp(ClassID()) 43 , fPathFlags(pathFlags) 44 , fViewMatrix(viewMatrix) 45 , fPath(path) 46 , fAAType(aaType) 47 , fColor(paint.getColor4f()) 48 , fProcessors(std::move(paint)) { 49 SkASSERT(!fPath.isInverseFillType()); 50 this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo); 51 } 52 name()53 const char* name() const override { return "PathInnerTriangulateOp"; } 54 void visitProxies(const GrVisitProxyFunc&) const override; 55 FixedFunctionFlags fixedFunctionFlags() const override; 56 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override; 57 58 // These calls set up the stencil & fill programs we will use prior to preparing and executing. 59 void pushFanStencilProgram(const GrTessellationShader::ProgramArgs&, 60 const GrPipeline* pipelineForStencils, const GrUserStencilSettings*); 61 void pushFanFillProgram(const GrTessellationShader::ProgramArgs&, const GrUserStencilSettings*); 62 void prePreparePrograms(const GrTessellationShader::ProgramArgs&, GrAppliedClip&&); 63 64 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*, 65 const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override; 66 void onPrepare(GrOpFlushState*) override; 67 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; 68 69 const FillPathFlags fPathFlags; 70 const SkMatrix fViewMatrix; 71 const SkPath fPath; 72 const GrAAType fAAType; 73 SkPMColor4f fColor; 74 GrProcessorSet fProcessors; 75 76 // Triangulates the inner fan. 77 GrInnerFanTriangulator* fFanTriangulator = nullptr; 78 GrTriangulator::Poly* fFanPolys = nullptr; 79 GrInnerFanTriangulator::BreadcrumbTriangleList fFanBreadcrumbs; 80 81 // This pipeline is shared by all programs that do filling. 82 const GrPipeline* fPipelineForFills = nullptr; 83 84 // Tessellates the outer curves. 85 PathCurveTessellator* fTessellator = nullptr; 86 87 // Pass 1: Tessellate the outer curves into the stencil buffer. 88 const GrProgramInfo* fStencilCurvesProgram = nullptr; 89 90 // Pass 2: Fill the path's inner fan with a stencil test against the curves. (In extenuating 91 // circumstances this might require two separate draws.) 92 SkSTArray<2, const GrProgramInfo*> fFanPrograms; 93 94 // Pass 3: Draw convex hulls around each curve. 95 const GrProgramInfo* fCoverHullsProgram = nullptr; 96 97 // This buffer gets created by fFanTriangulator during onPrepare. 98 sk_sp<const GrBuffer> fFanBuffer; 99 int fBaseFanVertex = 0; 100 int fFanVertexCount = 0; 101 102 // Only used if sk_VertexID is not supported. 103 sk_sp<const GrGpuBuffer> fHullVertexBufferIfNoIDSupport; 104 105 friend class GrOp; // For ctor. 106 }; 107 108 } // namespace skgpu::v1 109 110 #endif // PathInnerTriangulateOp_DEFINED 111