blob: bb2724f00540be88a726cad890e04494368ff216 [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"
13#include "src/gpu/tessellate/GrPathShader.h"
Chris Dalton9b5b7db72021-03-30 10:59:34 -060014#include "src/gpu/tessellate/GrStrokeTessellator.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
19// GrStrokeTessellateShader.
20class GrStrokeTessellateOp : public GrDrawOp {
21public:
22 GrStrokeTessellateOp(GrAAType, const SkMatrix&, const SkPath&, const SkStrokeRec&, GrPaint&&);
23
24private:
25 using ShaderFlags = GrStrokeTessellateShader::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 Dalton82094cd2021-02-19 01:11:27 -070031 GrStrokeTessellateOp* nextInChain() const {
32 return static_cast<GrStrokeTessellateOp*>(this->GrDrawOp::nextInChain());
33 }
Chris Dalton42582fc2021-02-18 11:29:49 -070034
Chris Dalton1017a352021-02-18 15:22:54 -070035 // Returns whether it is a good tradeoff to use the dynamic states flagged in the given
36 // bitfield. Dynamic states improve batching, but if they aren't already enabled, they come at
37 // the cost of having to write out more data with each patch or instance.
38 bool shouldUseDynamicStates(ShaderFlags neededDynamicStates) const {
39 // 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 -070040 // have many verbs.
41 constexpr static int kMaxVerbsToEnableDynamicState = 50;
Chris Dalton1017a352021-02-18 15:22:54 -070042 bool anyStateDisabled = (bool)(~fShaderFlags & neededDynamicStates);
43 bool allStatesEnabled = !anyStateDisabled;
44 return allStatesEnabled || (fTotalCombinedVerbCnt <= kMaxVerbsToEnableDynamicState);
45 }
46
47 bool canUseHardwareTessellation(const GrCaps& caps) {
48 SkASSERT(!fStencilProgram && !fFillProgram); // Ensure we haven't std::moved fProcessors.
49 // Our back door for HW tessellation shaders isn't currently capable of passing varyings to
50 // the fragment shader, so if the processors have varyings we need to use indirect draws.
51 return caps.shaderCaps()->tessellationSupport() && !fProcessors.usesVaryingCoords();
Chris Dalton42582fc2021-02-18 11:29:49 -070052 }
53
Chris Dalton05007df2021-02-04 00:24:52 -070054 const char* name() const override { return "GrStrokeTessellateOp"; }
Chris Daltonb0643342020-12-15 01:04:12 -070055 void visitProxies(const VisitProxyFunc& fn) const override;
Chris Dalton0e543092020-11-03 14:09:16 -070056 FixedFunctionFlags fixedFunctionFlags() const override;
Chris Dalton57ab06c2021-04-22 12:57:28 -060057 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Chris Dalton0e543092020-11-03 14:09:16 -070058 CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
59
Chris Dalton22241002021-02-04 09:47:40 -070060 // Creates the tessellator and the stencil/fill program(s) we will use with it.
61 void prePrepareTessellator(GrPathShader::ProgramArgs&&, GrAppliedClip&&);
Chris Dalton0e543092020-11-03 14:09:16 -070062
Chris Dalton22241002021-02-04 09:47:40 -070063 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
64 const GrXferProcessor::DstProxyView&, GrXferBarrierFlags,
65 GrLoadOp colorLoadOp) override;
Chris Dalton0e543092020-11-03 14:09:16 -070066
Chris Dalton22241002021-02-04 09:47:40 -070067 void onPrepare(GrOpFlushState*) override;
Chris Dalton0e543092020-11-03 14:09:16 -070068
Chris Dalton22241002021-02-04 09:47:40 -070069 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
Chris Dalton06b52ad2020-12-15 10:01:35 -070070
Chris Dalton0e543092020-11-03 14:09:16 -070071 const GrAAType fAAType;
72 const SkMatrix fViewMatrix;
Chris Dalton42582fc2021-02-18 11:29:49 -070073 ShaderFlags fShaderFlags = ShaderFlags::kNone;
Chris Daltoned826862021-02-22 12:01:12 -070074 PathStrokeList fPathStrokeList;
75 PathStrokeList** fPathStrokeTail = &fPathStrokeList.fNext;
Chris Dalton7b807262020-12-10 10:22:50 -070076 int fTotalCombinedVerbCnt = 0;
Chris Dalton1017a352021-02-18 15:22:54 -070077 GrProcessorSet fProcessors;
78 bool fNeedsStencil = false;
Chris Dalton0e543092020-11-03 14:09:16 -070079
Chris Dalton22241002021-02-04 09:47:40 -070080 GrStrokeTessellator* fTessellator = nullptr;
81 const GrProgramInfo* fStencilProgram = nullptr; // Only used if the stroke has transparency.
Chris Dalton55abaf52020-12-08 10:25:13 -070082 const GrProgramInfo* fFillProgram = nullptr;
Chris Dalton0e543092020-11-03 14:09:16 -070083};
84
85#endif