• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 GrStrokeTessellateOp_DEFINED
9 #define GrStrokeTessellateOp_DEFINED
10 
11 #include "include/core/SkStrokeRec.h"
12 #include "src/gpu/ops/GrMeshDrawOp.h"
13 #include "src/gpu/tessellate/GrPathShader.h"
14 #include "src/gpu/tessellate/GrStrokeTessellator.h"
15 
16 class GrRecordingContext;
17 
18 // Renders strokes by linearizing them into sorted "parametric" and "radial" edges. See
19 // GrStrokeTessellateShader.
20 class GrStrokeTessellateOp : public GrDrawOp {
21 public:
22     GrStrokeTessellateOp(GrAAType, const SkMatrix&, const SkPath&, const SkStrokeRec&, GrPaint&&);
23 
24 private:
25     using ShaderFlags = GrStrokeTessellateShader::ShaderFlags;
26     using PathStrokeList = GrStrokeTessellator::PathStrokeList;
27     DEFINE_OP_CLASS_ID
28 
headStroke()29     SkStrokeRec& headStroke() { return fPathStrokeList.fStroke; }
headColor()30     SkPMColor4f& headColor() { return fPathStrokeList.fColor; }
31 
32     // Returns whether it is a good tradeoff to use the dynamic states flagged in the given
33     // bitfield. Dynamic states improve batching, but if they aren't already enabled, they come at
34     // the cost of having to write out more data with each patch or instance.
shouldUseDynamicStates(ShaderFlags neededDynamicStates)35     bool shouldUseDynamicStates(ShaderFlags neededDynamicStates) const {
36         // Use the dynamic states if either (1) they are all already enabled anyway, or (2) we don't
37         // have many verbs.
38         constexpr static int kMaxVerbsToEnableDynamicState = 50;
39         bool anyStateDisabled = (bool)(~fShaderFlags & neededDynamicStates);
40         bool allStatesEnabled = !anyStateDisabled;
41         return allStatesEnabled || (fTotalCombinedVerbCnt <= kMaxVerbsToEnableDynamicState);
42     }
43 
44     bool canUseHardwareTessellation(int numVerbs, const GrCaps& caps);
45 
name()46     const char* name() const override { return "GrStrokeTessellateOp"; }
47     void visitProxies(const VisitProxyFunc& fn) const override;
48     FixedFunctionFlags fixedFunctionFlags() const override;
49     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
50     CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
51 
52     // Creates the tessellator and the stencil/fill program(s) we will use with it.
53     void prePrepareTessellator(GrPathShader::ProgramArgs&&, GrAppliedClip&&);
54 
55     void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
56                       const GrXferProcessor::DstProxyView&, GrXferBarrierFlags,
57                       GrLoadOp colorLoadOp) override;
58 
59     void onPrepare(GrOpFlushState*) override;
60 
61     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
62 
63     const GrAAType fAAType;
64     const SkMatrix fViewMatrix;
65     ShaderFlags fShaderFlags = ShaderFlags::kNone;
66     PathStrokeList fPathStrokeList;
67     PathStrokeList** fPathStrokeTail = &fPathStrokeList.fNext;
68     int fTotalCombinedVerbCnt = 0;
69     GrProcessorSet fProcessors;
70     bool fNeedsStencil = false;
71 
72     GrStrokeTessellator* fTessellator = nullptr;
73     const GrProgramInfo* fStencilProgram = nullptr;  // Only used if the stroke has transparency.
74     const GrProgramInfo* fFillProgram = nullptr;
75 };
76 
77 #endif
78