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