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