blob: 6a4529834077733653ed096151bc7fd1f8e864cd [file] [log] [blame]
Chris Dalton70a0d2c2021-01-26 12:01:21 -07001/*
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
Robert Phillips62bd6332021-08-26 09:56:55 -04008#ifndef PathStencilCoverOp_DEFINED
9#define PathStencilCoverOp_DEFINED
Chris Dalton70a0d2c2021-01-26 12:01:21 -070010
11#include "src/gpu/ops/GrDrawOp.h"
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060012#include "src/gpu/tessellate/GrPathTessellator.h"
Robert Phillips832f3fb2021-08-18 13:05:15 -040013#include "src/gpu/tessellate/GrTessTypes.h"
Chris Dalton3b412782021-06-01 13:40:03 -060014#include "src/gpu/tessellate/shaders/GrTessellationShader.h"
Chris Dalton70a0d2c2021-01-26 12:01:21 -070015
Robert Phillips62bd6332021-08-26 09:56:55 -040016namespace skgpu::v1 {
17
Chris Dalton031d76b2021-06-08 16:32:00 -060018// Draws paths using a standard Redbook "stencil then cover" method. Curves get linearized by either
Chris Dalton57ab06c2021-04-22 12:57:28 -060019// GPU tessellation shaders or indirect draws. This Op doesn't apply analytic AA, so it requires
20// MSAA if AA is desired.
Robert Phillips62bd6332021-08-26 09:56:55 -040021class PathStencilCoverOp final : public GrDrawOp {
Chris Dalton70a0d2c2021-01-26 12:01:21 -070022private:
23 DEFINE_OP_CLASS_ID
24
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060025 using PathDrawList = GrPathTessellator::PathDrawList;
26
Chris Daltonbaae2dd2021-06-25 14:52:49 -060027 // If the path is inverse filled, drawBounds must be the entire backing store dimensions of the
28 // render target.
Robert Phillips62bd6332021-08-26 09:56:55 -040029 PathStencilCoverOp(SkArenaAlloc* arena,
30 const SkMatrix& viewMatrix,
31 const SkPath& path,
32 GrPaint&& paint,
33 GrAAType aaType,
34 GrTessellationPathFlags pathFlags,
35 const SkRect& drawBounds)
Chris Dalton70a0d2c2021-01-26 12:01:21 -070036 : GrDrawOp(ClassID())
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060037 , fPathDrawList(arena->make<PathDrawList>(viewMatrix, path))
38 , fTotalCombinedPathVerbCnt(path.countVerbs())
39 , fPathCount(1)
Chris Dalton917f9192021-06-08 14:32:37 -060040 , fPathFlags(pathFlags)
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060041 , 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
Robert Phillips62bd6332021-08-26 09:56:55 -040048 // Constructs a PathStencilCoverOp from an existing draw list.
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060049 // FIXME: The only user of this method is the atlas. We should move the GrProgramInfos into
50 // GrPathTessellator so the atlas can use that directly instead of going through this class.
Robert Phillips62bd6332021-08-26 09:56:55 -040051 PathStencilCoverOp(const PathDrawList* pathDrawList,
52 int totalCombinedVerbCnt,
53 int pathCount,
54 GrPaint&& paint,
55 GrAAType aaType,
56 GrTessellationPathFlags pathFlags,
57 const SkRect& drawBounds)
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060058 : GrDrawOp(ClassID())
59 , fPathDrawList(pathDrawList)
60 , fTotalCombinedPathVerbCnt(totalCombinedVerbCnt)
61 , fPathCount(pathCount)
62 , fPathFlags(pathFlags)
Chris Dalton70a0d2c2021-01-26 12:01:21 -070063 , fAAType(aaType)
64 , fColor(paint.getColor4f())
65 , fProcessors(std::move(paint)) {
Chris Daltonbaae2dd2021-06-25 14:52:49 -060066 this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo);
67 SkDEBUGCODE(fOriginalDrawBounds = drawBounds;)
Chris Dalton70a0d2c2021-01-26 12:01:21 -070068 }
69
Robert Phillips62bd6332021-08-26 09:56:55 -040070 const char* name() const override { return "PathStencilCoverOp"; }
Robert Phillips294723d2021-06-17 09:23:58 -040071 void visitProxies(const GrVisitProxyFunc&) const override;
Chris Dalton70a0d2c2021-01-26 12:01:21 -070072 FixedFunctionFlags fixedFunctionFlags() const override;
Chris Dalton57ab06c2021-04-22 12:57:28 -060073 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Chris Dalton70a0d2c2021-01-26 12:01:21 -070074
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060075 // All paths in fPathDrawList are required to have the same fill type.
76 SkPathFillType pathFillType() const {
77 return fPathDrawList->fPath.getFillType();
78 }
79
Chris Dalton70a0d2c2021-01-26 12:01:21 -070080 // Chooses the rendering method we will use and creates the corresponding tessellator and
Chris Dalton031d76b2021-06-08 16:32:00 -060081 // stencil/cover programs.
Chris Dalton2f733ec2021-06-01 12:11:57 -060082 void prePreparePrograms(const GrTessellationShader::ProgramArgs&, GrAppliedClip&& clip);
Chris Dalton70a0d2c2021-01-26 12:01:21 -070083
84 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
John Stiles52cb1d02021-06-02 11:58:05 -040085 const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
Chris Dalton70a0d2c2021-01-26 12:01:21 -070086 void onPrepare(GrOpFlushState*) override;
87 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
88
Chris Dalton8a1bbaa2021-07-28 14:43:07 -060089 const PathDrawList* fPathDrawList;
90 const int fTotalCombinedPathVerbCnt;
91 const int fPathCount;
Robert Phillips832f3fb2021-08-18 13:05:15 -040092 const GrTessellationPathFlags fPathFlags;
Chris Dalton70a0d2c2021-01-26 12:01:21 -070093 const GrAAType fAAType;
94 SkPMColor4f fColor;
95 GrProcessorSet fProcessors;
Chris Daltonbaae2dd2021-06-25 14:52:49 -060096 SkDEBUGCODE(SkRect fOriginalDrawBounds;)
Chris Dalton70a0d2c2021-01-26 12:01:21 -070097
98 // Decided during prePreparePrograms.
99 GrPathTessellator* fTessellator = nullptr;
100 const GrProgramInfo* fStencilFanProgram = nullptr;
101 const GrProgramInfo* fStencilPathProgram = nullptr;
Chris Dalton031d76b2021-06-08 16:32:00 -0600102 const GrProgramInfo* fCoverBBoxProgram = nullptr;
Chris Dalton70a0d2c2021-01-26 12:01:21 -0700103
104 // Filled during onPrepare.
105 sk_sp<const GrBuffer> fFanBuffer;
106 int fFanBaseVertex = 0;
107 int fFanVertexCount = 0;
108
Chris Daltonc91dd692021-05-24 15:04:47 -0600109 sk_sp<const GrBuffer> fBBoxBuffer;
110 int fBBoxBaseInstance = 0;
111
Chris Daltona05ccc32021-06-29 19:42:13 -0600112 // Only used if sk_VertexID is not supported.
113 sk_sp<const GrGpuBuffer> fBBoxVertexBufferIfNoIDSupport;
114
Chris Dalton70a0d2c2021-01-26 12:01:21 -0700115 friend class GrOp; // For ctor.
116};
117
Robert Phillips62bd6332021-08-26 09:56:55 -0400118} // namespace skgpu::v1
119
120#endif // PathStencilCoverOp_DEFINED