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