1 /* 2 * Copyright 2017 Google Inc. 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 GrSimpleMeshDrawOpHelper_DEFINED 9 #define GrSimpleMeshDrawOpHelper_DEFINED 10 11 #include "GrMeshDrawOp.h" 12 #include "GrOpFlushState.h" 13 #include "GrPipeline.h" 14 15 struct SkRect; 16 17 /** 18 * This class can be used to help implement simple mesh draw ops. It reduces the amount of 19 * boilerplate code to type and also provides a mechanism for optionally allocating space for a 20 * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single 21 * GrPipeline for a uniform primitive color and a GrPaint. 22 */ 23 class GrSimpleMeshDrawOpHelper { 24 public: 25 struct MakeArgs; 26 27 /** 28 * This can be used by a Op class to perform allocation and initialization such that a 29 * GrProcessorSet (if required) is allocated as part of the the same allocation that as 30 * the Op instance. It requires that Op implements a constructor of the form: 31 * Op(MakeArgs, GrColor, OpArgs...) 32 * which is public or made accessible via 'friend'. 33 */ 34 template <typename Op, typename... OpArgs> 35 static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs); 36 37 enum class Flags : uint32_t { 38 kNone = 0x0, 39 kSnapVerticesToPixelCenters = 0x1, 40 }; 41 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags); 42 43 GrSimpleMeshDrawOpHelper(const MakeArgs&, GrAAType, Flags = Flags::kNone); 44 ~GrSimpleMeshDrawOpHelper(); 45 46 GrSimpleMeshDrawOpHelper() = delete; 47 GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete; 48 GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete; 49 50 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const; 51 52 bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds, 53 const SkRect& thatBounds) const; 54 55 /** 56 * Finalizes the processor set and determines whether the destination must be provided 57 * to the fragment shader as a texture for blending. 58 * 59 * @param geometryCoverage Describes the coverage output of the op's geometry processor 60 * @param geometryColor An in/out param. As input this informs processor analysis about the 61 * color the op expects to output from its geometry processor. As output 62 * this may be set to a known color in which case the op must output this 63 * color from its geometry processor instead. 64 */ 65 GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip, 66 GrProcessorAnalysisCoverage geometryCoverage, 67 GrProcessorAnalysisColor* geometryColor); 68 69 /** 70 * Version of above that can be used by ops that have a constant color geometry processor 71 * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has 72 * changed the op must override its geometry processor color output with the new color. 73 */ 74 GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*, 75 GrProcessorAnalysisCoverage geometryCoverage, 76 GrColor* geometryColor); 77 78 bool usesLocalCoords() const { 79 SkASSERT(fDidAnalysis); 80 return fUsesLocalCoords; 81 } 82 83 bool compatibleWithAlphaAsCoverage() const { return fCompatibleWithAlphaAsCoveage; } 84 85 GrPipeline* makePipeline(GrMeshDrawOp::Target* target) const { 86 return target->allocPipeline(this->pipelineInitArgs(target)); 87 } 88 89 struct MakeArgs { 90 private: 91 MakeArgs() = default; 92 93 GrProcessorSet* fProcessorSet; 94 uint32_t fSRGBFlags; 95 96 friend class GrSimpleMeshDrawOpHelper; 97 }; 98 99 SkString dumpInfo() const; 100 101 protected: 102 GrAAType aaType() const { return static_cast<GrAAType>(fAAType); } 103 uint32_t pipelineFlags() const { return fPipelineFlags; } 104 const GrProcessorSet& processors() const { 105 return fProcessors ? *fProcessors : GrProcessorSet::EmptySet(); 106 } 107 108 GrPipeline::InitArgs pipelineInitArgs(GrMeshDrawOp::Target* target) const; 109 110 private: 111 GrProcessorSet* fProcessors; 112 unsigned fPipelineFlags : 8; 113 unsigned fAAType : 2; 114 unsigned fRequiresDstTexture : 1; 115 unsigned fUsesLocalCoords : 1; 116 unsigned fCompatibleWithAlphaAsCoveage : 1; 117 SkDEBUGCODE(unsigned fDidAnalysis : 1;) 118 }; 119 120 /** 121 * This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This 122 * uses private inheritance because it non-virtually overrides methods in the base class and should 123 * never be used with a GrSimpleMeshDrawOpHelper pointer or reference. 124 */ 125 class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper { 126 public: 127 using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs; 128 using Flags = GrSimpleMeshDrawOpHelper::Flags; 129 130 // using declarations can't be templated, so this is a pass through function instead. 131 template <typename Op, typename... OpArgs> 132 static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs) { 133 return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>( 134 std::move(paint), std::forward<OpArgs>(opArgs)...); 135 } 136 137 GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs&, GrAAType, const GrUserStencilSettings*, 138 Flags = Flags::kNone); 139 140 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const; 141 142 using GrSimpleMeshDrawOpHelper::xpRequiresDstTexture; 143 using GrSimpleMeshDrawOpHelper::usesLocalCoords; 144 using GrSimpleMeshDrawOpHelper::compatibleWithAlphaAsCoverage; 145 146 bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&, 147 const SkRect& thisBounds, const SkRect& thatBounds) const; 148 149 const GrPipeline* makePipeline(GrMeshDrawOp::Target*) const; 150 151 SkString dumpInfo() const; 152 153 private: 154 const GrUserStencilSettings* fStencilSettings; 155 typedef GrSimpleMeshDrawOpHelper INHERITED; 156 }; 157 158 template <typename Op, typename... OpArgs> 159 std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrPaint&& paint, 160 OpArgs... opArgs) { 161 MakeArgs makeArgs; 162 makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint); 163 GrColor color = paint.getColor(); 164 if (paint.isTrivial()) { 165 makeArgs.fProcessorSet = nullptr; 166 return std::unique_ptr<GrDrawOp>(new Op(makeArgs, color, std::forward<OpArgs>(opArgs)...)); 167 } else { 168 char* mem = (char*)GrOp::operator new(sizeof(Op) + sizeof(GrProcessorSet)); 169 char* setMem = mem + sizeof(Op); 170 makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint)); 171 return std::unique_ptr<GrDrawOp>( 172 new (mem) Op(makeArgs, color, std::forward<OpArgs>(opArgs)...)); 173 } 174 } 175 176 GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::Flags) 177 178 #endif 179