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 15struct 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 */ 23class GrSimpleMeshDrawOpHelper { 24public: 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 GrPixelConfigIsClamped dstIsClamped, 67 GrProcessorAnalysisCoverage geometryCoverage, 68 GrProcessorAnalysisColor* geometryColor); 69 70 /** 71 * Version of above that can be used by ops that have a constant color geometry processor 72 * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has 73 * changed the op must override its geometry processor color output with the new color. 74 */ 75 GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*, 76 GrPixelConfigIsClamped dstIsClamped, 77 GrProcessorAnalysisCoverage geometryCoverage, 78 GrColor* geometryColor); 79 80 bool usesLocalCoords() const { 81 SkASSERT(fDidAnalysis); 82 return fUsesLocalCoords; 83 } 84 85 bool compatibleWithAlphaAsCoverage() const { return fCompatibleWithAlphaAsCoveage; } 86 87 /** Makes a pipeline that consumes the processor set and the op's applied clip. */ 88 GrPipeline* makePipeline(GrMeshDrawOp::Target* target) { 89 return this->internalMakePipeline(target, this->pipelineInitArgs(target)); 90 } 91 92 struct MakeArgs { 93 private: 94 MakeArgs() = default; 95 96 GrProcessorSet* fProcessorSet; 97 uint32_t fSRGBFlags; 98 99 friend class GrSimpleMeshDrawOpHelper; 100 }; 101 102 void visitProxies(const std::function<void(GrSurfaceProxy*)>& func) const { 103 if (fProcessors) { 104 fProcessors->visitProxies(func); 105 } 106 } 107 108 SkString dumpInfo() const; 109 110protected: 111 GrAAType aaType() const { return static_cast<GrAAType>(fAAType); } 112 uint32_t pipelineFlags() const { return fPipelineFlags; } 113 114 GrPipeline::InitArgs pipelineInitArgs(GrMeshDrawOp::Target* target) const; 115 116 GrPipeline* internalMakePipeline(GrMeshDrawOp::Target*, const GrPipeline::InitArgs&); 117 118private: 119 GrProcessorSet* fProcessors; 120 unsigned fPipelineFlags : 8; 121 unsigned fAAType : 2; 122 unsigned fRequiresDstTexture : 1; 123 unsigned fUsesLocalCoords : 1; 124 unsigned fCompatibleWithAlphaAsCoveage : 1; 125 SkDEBUGCODE(unsigned fMadePipeline : 1;) 126 SkDEBUGCODE(unsigned fDidAnalysis : 1;) 127}; 128 129/** 130 * This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This 131 * uses private inheritance because it non-virtually overrides methods in the base class and should 132 * never be used with a GrSimpleMeshDrawOpHelper pointer or reference. 133 */ 134class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper { 135public: 136 using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs; 137 using Flags = GrSimpleMeshDrawOpHelper::Flags; 138 using GrSimpleMeshDrawOpHelper::visitProxies; 139 140 // using declarations can't be templated, so this is a pass through function instead. 141 template <typename Op, typename... OpArgs> 142 static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs) { 143 return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>( 144 std::move(paint), std::forward<OpArgs>(opArgs)...); 145 } 146 147 GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs&, GrAAType, const GrUserStencilSettings*, 148 Flags = Flags::kNone); 149 150 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const; 151 152 using GrSimpleMeshDrawOpHelper::xpRequiresDstTexture; 153 using GrSimpleMeshDrawOpHelper::usesLocalCoords; 154 using GrSimpleMeshDrawOpHelper::compatibleWithAlphaAsCoverage; 155 156 bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&, 157 const SkRect& thisBounds, const SkRect& thatBounds) const; 158 159 const GrPipeline* makePipeline(GrMeshDrawOp::Target*); 160 161 SkString dumpInfo() const; 162 163private: 164 const GrUserStencilSettings* fStencilSettings; 165 typedef GrSimpleMeshDrawOpHelper INHERITED; 166}; 167 168template <typename Op, typename... OpArgs> 169std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrPaint&& paint, 170 OpArgs... opArgs) { 171 MakeArgs makeArgs; 172 makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint); 173 GrColor color = paint.getColor(); 174 if (paint.isTrivial()) { 175 makeArgs.fProcessorSet = nullptr; 176 return std::unique_ptr<GrDrawOp>(new Op(makeArgs, color, std::forward<OpArgs>(opArgs)...)); 177 } else { 178 char* mem = (char*)GrOp::operator new(sizeof(Op) + sizeof(GrProcessorSet)); 179 char* setMem = mem + sizeof(Op); 180 makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint)); 181 return std::unique_ptr<GrDrawOp>( 182 new (mem) Op(makeArgs, color, std::forward<OpArgs>(opArgs)...)); 183 } 184} 185 186GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::Flags) 187 188#endif 189