xref: /aosp_15_r20/external/skia/src/gpu/ganesh/ops/StrokeTessellateOp.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 Google LLC.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef StrokeTessellateOp_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define StrokeTessellateOp_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStrokeRec.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMacros.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessorSet.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrDrawOp.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrOp.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/tessellate/GrTessellationShader.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/tessellate/StrokeTessellator.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/tessellate/Tessellation.h"
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker class GrAppliedClip;
26*c8dee2aaSAndroid Build Coastguard Worker class GrDstProxyView;
27*c8dee2aaSAndroid Build Coastguard Worker class GrOpFlushState;
28*c8dee2aaSAndroid Build Coastguard Worker class GrPaint;
29*c8dee2aaSAndroid Build Coastguard Worker class GrProgramInfo;
30*c8dee2aaSAndroid Build Coastguard Worker class GrRecordingContext;
31*c8dee2aaSAndroid Build Coastguard Worker class GrStrokeTessellationShader;
32*c8dee2aaSAndroid Build Coastguard Worker class GrSurfaceProxyView;
33*c8dee2aaSAndroid Build Coastguard Worker class SkArenaAlloc;
34*c8dee2aaSAndroid Build Coastguard Worker class SkPath;
35*c8dee2aaSAndroid Build Coastguard Worker enum class GrXferBarrierFlags;
36*c8dee2aaSAndroid Build Coastguard Worker struct SkRect;
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::ganesh {
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker // Renders strokes by linearizing them into sorted "parametric" and "radial" edges. See
41*c8dee2aaSAndroid Build Coastguard Worker // GrStrokeTessellationShader.
42*c8dee2aaSAndroid Build Coastguard Worker class StrokeTessellateOp final : public GrDrawOp {
43*c8dee2aaSAndroid Build Coastguard Worker public:
44*c8dee2aaSAndroid Build Coastguard Worker     StrokeTessellateOp(GrAAType, const SkMatrix&, const SkPath&, const SkStrokeRec&, GrPaint&&);
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker private:
47*c8dee2aaSAndroid Build Coastguard Worker     using PatchAttribs = StrokeTessellator::PatchAttribs;
48*c8dee2aaSAndroid Build Coastguard Worker     using PathStrokeList = StrokeTessellator::PathStrokeList;
49*c8dee2aaSAndroid Build Coastguard Worker 
50*c8dee2aaSAndroid Build Coastguard Worker     DEFINE_OP_CLASS_ID
51*c8dee2aaSAndroid Build Coastguard Worker 
headStroke()52*c8dee2aaSAndroid Build Coastguard Worker     SkStrokeRec& headStroke() { return fPathStrokeList.fStroke; }
headColor()53*c8dee2aaSAndroid Build Coastguard Worker     SkPMColor4f& headColor() { return fPathStrokeList.fColor; }
54*c8dee2aaSAndroid Build Coastguard Worker 
55*c8dee2aaSAndroid Build Coastguard Worker     // Returns whether it is a good tradeoff to use the dynamic states flagged in the given
56*c8dee2aaSAndroid Build Coastguard Worker     // bitfield. Dynamic states improve batching, but if they aren't already enabled, they come at
57*c8dee2aaSAndroid Build Coastguard Worker     // the cost of having to write out more data with each patch or instance.
shouldUseDynamicStates(PatchAttribs neededDynamicStates)58*c8dee2aaSAndroid Build Coastguard Worker     bool shouldUseDynamicStates(PatchAttribs neededDynamicStates) const {
59*c8dee2aaSAndroid Build Coastguard Worker         // Use the dynamic states if either (1) they are all already enabled anyway, or (2) we don't
60*c8dee2aaSAndroid Build Coastguard Worker         // have many verbs.
61*c8dee2aaSAndroid Build Coastguard Worker         constexpr static int kMaxVerbsToEnableDynamicState = 50;
62*c8dee2aaSAndroid Build Coastguard Worker         bool anyStateDisabled = (bool)(~fPatchAttribs & neededDynamicStates);
63*c8dee2aaSAndroid Build Coastguard Worker         bool allStatesEnabled = !anyStateDisabled;
64*c8dee2aaSAndroid Build Coastguard Worker         return allStatesEnabled || (fTotalCombinedVerbCnt <= kMaxVerbsToEnableDynamicState);
65*c8dee2aaSAndroid Build Coastguard Worker     }
66*c8dee2aaSAndroid Build Coastguard Worker 
name()67*c8dee2aaSAndroid Build Coastguard Worker     const char* name() const override { return "StrokeTessellateOp"; }
68*c8dee2aaSAndroid Build Coastguard Worker     void visitProxies(const GrVisitProxyFunc&) const override;
usesMSAA()69*c8dee2aaSAndroid Build Coastguard Worker     bool usesMSAA() const override { return fAAType == GrAAType::kMSAA; }
70*c8dee2aaSAndroid Build Coastguard Worker     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
usesStencil()71*c8dee2aaSAndroid Build Coastguard Worker     bool usesStencil() const override {
72*c8dee2aaSAndroid Build Coastguard Worker         // This must be called after finalize(). fNeedsStencil can change in finalize().
73*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fProcessors.isFinalized());
74*c8dee2aaSAndroid Build Coastguard Worker         return fNeedsStencil;
75*c8dee2aaSAndroid Build Coastguard Worker     }
76*c8dee2aaSAndroid Build Coastguard Worker     CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker     // Creates the tessellator and the stencil/fill program(s) we will use with it.
79*c8dee2aaSAndroid Build Coastguard Worker     void prePrepareTessellator(GrTessellationShader::ProgramArgs&&, GrAppliedClip&&);
80*c8dee2aaSAndroid Build Coastguard Worker 
81*c8dee2aaSAndroid Build Coastguard Worker     void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
82*c8dee2aaSAndroid Build Coastguard Worker                       const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     void onPrepare(GrOpFlushState*) override;
85*c8dee2aaSAndroid Build Coastguard Worker 
86*c8dee2aaSAndroid Build Coastguard Worker     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker     const GrAAType fAAType;
89*c8dee2aaSAndroid Build Coastguard Worker     const SkMatrix fViewMatrix;
90*c8dee2aaSAndroid Build Coastguard Worker     PatchAttribs fPatchAttribs = PatchAttribs::kNone;
91*c8dee2aaSAndroid Build Coastguard Worker     PathStrokeList fPathStrokeList;
92*c8dee2aaSAndroid Build Coastguard Worker     PathStrokeList** fPathStrokeTail = &fPathStrokeList.fNext;
93*c8dee2aaSAndroid Build Coastguard Worker     int fTotalCombinedVerbCnt = 0;
94*c8dee2aaSAndroid Build Coastguard Worker     GrProcessorSet fProcessors;
95*c8dee2aaSAndroid Build Coastguard Worker     bool fNeedsStencil;
96*c8dee2aaSAndroid Build Coastguard Worker 
97*c8dee2aaSAndroid Build Coastguard Worker     StrokeTessellator* fTessellator = nullptr;
98*c8dee2aaSAndroid Build Coastguard Worker     GrStrokeTessellationShader* fTessellationShader;
99*c8dee2aaSAndroid Build Coastguard Worker     const GrProgramInfo* fStencilProgram = nullptr;  // Only used if the stroke has transparency.
100*c8dee2aaSAndroid Build Coastguard Worker     const GrProgramInfo* fFillProgram = nullptr;
101*c8dee2aaSAndroid Build Coastguard Worker };
102*c8dee2aaSAndroid Build Coastguard Worker 
103*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skgpu::ganesh
104*c8dee2aaSAndroid Build Coastguard Worker 
105*c8dee2aaSAndroid Build Coastguard Worker #endif // StrokeTessellateOp_DEFINED
106