blob: e3890cba1f8dfd9625bf8f7f1794128c344cf0c2 [file] [log] [blame]
Chris Dalton0e543092020-11-03 14:09:16 -07001/*
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
Chris Dalton05007df2021-02-04 00:24:52 -07008#ifndef GrStrokeTessellateOp_DEFINED
9#define GrStrokeTessellateOp_DEFINED
Chris Dalton0e543092020-11-03 14:09:16 -070010
11#include "include/core/SkStrokeRec.h"
Chris Dalton22241002021-02-04 09:47:40 -070012#include "src/gpu/ops/GrMeshDrawOp.h"
Chris Dalton9b5b7db72021-03-30 10:59:34 -060013#include "src/gpu/tessellate/GrStrokeTessellator.h"
Chris Dalton3b412782021-06-01 13:40:03 -060014#include "src/gpu/tessellate/shaders/GrTessellationShader.h"
Chris Dalton0e543092020-11-03 14:09:16 -070015
Chris Dalton22241002021-02-04 09:47:40 -070016class GrRecordingContext;
17
Chris Dalton42582fc2021-02-18 11:29:49 -070018// Renders strokes by linearizing them into sorted "parametric" and "radial" edges. See
Chris Dalton3b412782021-06-01 13:40:03 -060019// GrStrokeTessellationShader.
Chris Dalton42582fc2021-02-18 11:29:49 -070020class GrStrokeTessellateOp : public GrDrawOp {
21public:
22 GrStrokeTessellateOp(GrAAType, const SkMatrix&, const SkPath&, const SkStrokeRec&, GrPaint&&);
23
24private:
Chris Dalton3b412782021-06-01 13:40:03 -060025 using ShaderFlags = GrStrokeTessellationShader::ShaderFlags;
Chris Daltoned826862021-02-22 12:01:12 -070026 using PathStrokeList = GrStrokeTessellator::PathStrokeList;
Chris Dalton22241002021-02-04 09:47:40 -070027 DEFINE_OP_CLASS_ID
28
Chris Daltoned826862021-02-22 12:01:12 -070029 SkStrokeRec& headStroke() { return fPathStrokeList.fStroke; }
30 SkPMColor4f& headColor() { return fPathStrokeList.fColor; }
Chris Dalton42582fc2021-02-18 11:29:49 -070031
Chris Dalton1017a352021-02-18 15:22:54 -070032 // 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.
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
Chris Dalton42582fc2021-02-18 11:29:49 -070037 // have many verbs.
38 constexpr static int kMaxVerbsToEnableDynamicState = 50;
Chris Dalton1017a352021-02-18 15:22:54 -070039 bool anyStateDisabled = (bool)(~fShaderFlags & neededDynamicStates);
40 bool allStatesEnabled = !anyStateDisabled;
41 return allStatesEnabled || (fTotalCombinedVerbCnt <= kMaxVerbsToEnableDynamicState);
42 }
43
Chris Dalton7d979912021-05-11 12:36:51 -060044 bool canUseHardwareTessellation(int numVerbs, const GrCaps& caps);
Chris Dalton42582fc2021-02-18 11:29:49 -070045
Chris Dalton05007df2021-02-04 00:24:52 -070046 const char* name() const override { return "GrStrokeTessellateOp"; }
Chris Daltonb0643342020-12-15 01:04:12 -070047 void visitProxies(const VisitProxyFunc& fn) const override;
Chris Dalton2a63f822021-05-27 14:14:11 -060048 bool usesMSAA() const override { return fAAType == GrAAType::kMSAA; }
Chris Dalton57ab06c2021-04-22 12:57:28 -060049 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Chris Dalton2a63f822021-05-27 14:14:11 -060050 bool usesStencil() const override {
51 // This must be called after finalize(). fNeedsStencil can change in finalize().
52 SkASSERT(fProcessors.isFinalized());
53 return fNeedsStencil;
54 }
Chris Dalton0e543092020-11-03 14:09:16 -070055 CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
56
Chris Dalton22241002021-02-04 09:47:40 -070057 // Creates the tessellator and the stencil/fill program(s) we will use with it.
Chris Dalton2f733ec2021-06-01 12:11:57 -060058 void prePrepareTessellator(GrTessellationShader::ProgramArgs&&, GrAppliedClip&&);
Chris Dalton0e543092020-11-03 14:09:16 -070059
Chris Dalton22241002021-02-04 09:47:40 -070060 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
John Stiles52cb1d02021-06-02 11:58:05 -040061 const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
Chris Dalton0e543092020-11-03 14:09:16 -070062
Chris Dalton22241002021-02-04 09:47:40 -070063 void onPrepare(GrOpFlushState*) override;
Chris Dalton0e543092020-11-03 14:09:16 -070064
Chris Dalton22241002021-02-04 09:47:40 -070065 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
Chris Dalton06b52ad2020-12-15 10:01:35 -070066
Chris Dalton0e543092020-11-03 14:09:16 -070067 const GrAAType fAAType;
68 const SkMatrix fViewMatrix;
Chris Dalton42582fc2021-02-18 11:29:49 -070069 ShaderFlags fShaderFlags = ShaderFlags::kNone;
Chris Daltoned826862021-02-22 12:01:12 -070070 PathStrokeList fPathStrokeList;
71 PathStrokeList** fPathStrokeTail = &fPathStrokeList.fNext;
Chris Dalton0638df12021-05-14 15:57:39 -060072 float fInflationRadius = 0;
Chris Dalton7b807262020-12-10 10:22:50 -070073 int fTotalCombinedVerbCnt = 0;
Chris Dalton1017a352021-02-18 15:22:54 -070074 GrProcessorSet fProcessors;
Chris Dalton2a63f822021-05-27 14:14:11 -060075 bool fNeedsStencil;
Chris Dalton0e543092020-11-03 14:09:16 -070076
Chris Dalton22241002021-02-04 09:47:40 -070077 GrStrokeTessellator* fTessellator = nullptr;
78 const GrProgramInfo* fStencilProgram = nullptr; // Only used if the stroke has transparency.
Chris Dalton55abaf52020-12-08 10:25:13 -070079 const GrProgramInfo* fFillProgram = nullptr;
Chris Dalton0e543092020-11-03 14:09:16 -070080};
81
82#endif