blob: 2278fbc17809899504f6c4449e158471d5b18cf6 [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 Dalton0e543092020-11-03 14:09:16 -070012#include "src/gpu/GrSTArenaList.h"
Chris Dalton22241002021-02-04 09:47:40 -070013#include "src/gpu/ops/GrMeshDrawOp.h"
14#include "src/gpu/tessellate/GrPathShader.h"
Chris Dalton42582fc2021-02-18 11:29:49 -070015#include "src/gpu/tessellate/GrStrokeTessellateShader.h"
Chris Dalton0e543092020-11-03 14:09:16 -070016
Chris Dalton22241002021-02-04 09:47:40 -070017class GrRecordingContext;
18
19// Prepares GPU data for, and then draws a stroke's tessellated geometry.
20class GrStrokeTessellator {
21public:
Chris Dalton42582fc2021-02-18 11:29:49 -070022 using ShaderFlags = GrStrokeTessellateShader::ShaderFlags;
Chris Dalton22241002021-02-04 09:47:40 -070023
Chris Dalton42582fc2021-02-18 11:29:49 -070024 GrStrokeTessellator(ShaderFlags shaderFlags) : fShaderFlags(shaderFlags) {}
25
26 struct PathStroke {
27 PathStroke(const SkPath& path, const SkStrokeRec& stroke) : fPath(path), fStroke(stroke) {}
28 SkPath fPath;
29 SkStrokeRec fStroke;
30 };
31
32 // Called before draw(). Prepares GPU buffers containing the geometry to tessellate.
33 virtual void prepare(GrMeshDrawOp::Target*, const SkMatrix&, const GrSTArenaList<PathStroke>&,
34 int totalCombinedVerbCnt) = 0;
35
36 // Issues draw calls for the tessellated stroke. The caller is responsible for binding its
Chris Dalton22241002021-02-04 09:47:40 -070037 // desired pipeline ahead of time.
38 virtual void draw(GrOpFlushState*) const = 0;
39
40 virtual ~GrStrokeTessellator() {}
Chris Dalton0e543092020-11-03 14:09:16 -070041
Chris Dalton22241002021-02-04 09:47:40 -070042protected:
Chris Dalton42582fc2021-02-18 11:29:49 -070043 const ShaderFlags fShaderFlags;
44};
45
46// Renders strokes by linearizing them into sorted "parametric" and "radial" edges. See
47// GrStrokeTessellateShader.
48class GrStrokeTessellateOp : public GrDrawOp {
49public:
50 GrStrokeTessellateOp(GrAAType, const SkMatrix&, const SkPath&, const SkStrokeRec&, GrPaint&&);
51
52private:
53 using ShaderFlags = GrStrokeTessellateShader::ShaderFlags;
54 using PathStroke = GrStrokeTessellator::PathStroke;
Chris Dalton22241002021-02-04 09:47:40 -070055 DEFINE_OP_CLASS_ID
56
Chris Dalton42582fc2021-02-18 11:29:49 -070057 SkStrokeRec& headStroke() { return fPathStrokeList.head().fStroke; }
58
59 // Returns whether it is a good tradeoff to use the given dynamic state. Dynamic state improves
60 // batching, but if it isn't already enabled, it comes at the cost of having to write out more
61 // data with each patch or instance.
62 bool shouldUseDynamicState(ShaderFlags dynamicState) const {
63 // Use the dynamic state if either (1) the state is already enabled anyway, or (2) we don't
64 // have many verbs.
65 constexpr static int kMaxVerbsToEnableDynamicState = 50;
66 return (fShaderFlags & dynamicState) ||
67 (fTotalCombinedVerbCnt <= kMaxVerbsToEnableDynamicState);
68 }
69
Chris Dalton05007df2021-02-04 00:24:52 -070070 const char* name() const override { return "GrStrokeTessellateOp"; }
Chris Daltonb0643342020-12-15 01:04:12 -070071 void visitProxies(const VisitProxyFunc& fn) const override;
Chris Dalton0e543092020-11-03 14:09:16 -070072 FixedFunctionFlags fixedFunctionFlags() const override;
73 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
74 bool hasMixedSampledCoverage, GrClampType) override;
75 CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
76
Chris Dalton22241002021-02-04 09:47:40 -070077 // Creates the tessellator and the stencil/fill program(s) we will use with it.
78 void prePrepareTessellator(GrPathShader::ProgramArgs&&, GrAppliedClip&&);
Chris Dalton0e543092020-11-03 14:09:16 -070079
Chris Dalton22241002021-02-04 09:47:40 -070080 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
81 const GrXferProcessor::DstProxyView&, GrXferBarrierFlags,
82 GrLoadOp colorLoadOp) override;
Chris Dalton0e543092020-11-03 14:09:16 -070083
Chris Dalton22241002021-02-04 09:47:40 -070084 void onPrepare(GrOpFlushState*) override;
Chris Dalton0e543092020-11-03 14:09:16 -070085
Chris Dalton22241002021-02-04 09:47:40 -070086 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
Chris Dalton06b52ad2020-12-15 10:01:35 -070087
Chris Dalton0e543092020-11-03 14:09:16 -070088 const GrAAType fAAType;
89 const SkMatrix fViewMatrix;
Chris Dalton0e543092020-11-03 14:09:16 -070090 SkPMColor4f fColor;
Chris Dalton55abaf52020-12-08 10:25:13 -070091 bool fNeedsStencil = false;
Chris Dalton0e543092020-11-03 14:09:16 -070092 GrProcessorSet fProcessors;
93
Chris Dalton42582fc2021-02-18 11:29:49 -070094 ShaderFlags fShaderFlags = ShaderFlags::kNone;
95 GrSTArenaList<PathStroke> fPathStrokeList;
Chris Dalton7b807262020-12-10 10:22:50 -070096 int fTotalCombinedVerbCnt = 0;
Chris Dalton0e543092020-11-03 14:09:16 -070097
Chris Dalton22241002021-02-04 09:47:40 -070098 GrStrokeTessellator* fTessellator = nullptr;
99 const GrProgramInfo* fStencilProgram = nullptr; // Only used if the stroke has transparency.
Chris Dalton55abaf52020-12-08 10:25:13 -0700100 const GrProgramInfo* fFillProgram = nullptr;
Chris Dalton0e543092020-11-03 14:09:16 -0700101};
102
103#endif