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