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 GrProcessorSet_DEFINED 9 #define GrProcessorSet_DEFINED 10 11 #include "GrFragmentProcessor.h" 12 #include "GrPaint.h" 13 #include "GrProcessorAnalysis.h" 14 #include "SkTemplates.h" 15 #include "GrXferProcessor.h" 16 17 class GrAppliedClip; 18 class GrXPFactory; 19 20 class GrProcessorSet : private SkNoncopyable { 21 private: 22 // Arbitrary constructor arg for empty set and analysis 23 enum class Empty { kEmpty }; 24 25 public: 26 GrProcessorSet(GrPaint&& paint); 27 GrProcessorSet(SkBlendMode mode); 28 GrProcessorSet(sk_sp<GrFragmentProcessor> colorFP); 29 30 ~GrProcessorSet(); 31 numColorFragmentProcessors()32 int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; } numCoverageFragmentProcessors()33 int numCoverageFragmentProcessors() const { 34 return this->numFragmentProcessors() - fColorFragmentProcessorCnt; 35 } numFragmentProcessors()36 int numFragmentProcessors() const { 37 return fFragmentProcessors.count() - fFragmentProcessorOffset; 38 } 39 colorFragmentProcessor(int idx)40 const GrFragmentProcessor* colorFragmentProcessor(int idx) const { 41 SkASSERT(idx < fColorFragmentProcessorCnt); 42 return fFragmentProcessors[idx + fFragmentProcessorOffset]; 43 } coverageFragmentProcessor(int idx)44 const GrFragmentProcessor* coverageFragmentProcessor(int idx) const { 45 return fFragmentProcessors[idx + fColorFragmentProcessorCnt + fFragmentProcessorOffset]; 46 } 47 xferProcessor()48 const GrXferProcessor* xferProcessor() const { 49 SkASSERT(this->isFinalized()); 50 return fXP.fProcessor; 51 } refXferProcessor()52 sk_sp<const GrXferProcessor> refXferProcessor() const { 53 SkASSERT(this->isFinalized()); 54 return sk_ref_sp(fXP.fProcessor); 55 } 56 57 /** Comparisons are only legal on finalized processor sets. */ 58 bool operator==(const GrProcessorSet& that) const; 59 bool operator!=(const GrProcessorSet& that) const { return !(*this == that); } 60 61 /** 62 * This is used to report results of processor analysis when a processor set is finalized (see 63 * below). 64 */ 65 class Analysis { 66 public: 67 Analysis(const Analysis&) = default; Analysis()68 Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; } 69 isInitialized()70 bool isInitialized() const { return fIsInitialized; } usesLocalCoords()71 bool usesLocalCoords() const { return fUsesLocalCoords; } requiresDstTexture()72 bool requiresDstTexture() const { return fRequiresDstTexture; } canCombineOverlappedStencilAndCover()73 bool canCombineOverlappedStencilAndCover() const { 74 return fCanCombineOverlappedStencilAndCover; 75 } requiresBarrierBetweenOverlappingDraws()76 bool requiresBarrierBetweenOverlappingDraws() const { 77 return fRequiresBarrierBetweenOverlappingDraws; 78 } isCompatibleWithCoverageAsAlpha()79 bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; } 80 inputColorIsIgnored()81 bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; } inputColorIsOverridden()82 bool inputColorIsOverridden() const { 83 return fInputColorType == kOverridden_InputColorType; 84 } 85 86 private: Analysis(Empty)87 constexpr Analysis(Empty) 88 : fUsesLocalCoords(false) 89 , fCompatibleWithCoverageAsAlpha(true) 90 , fRequiresDstTexture(false) 91 , fCanCombineOverlappedStencilAndCover(true) 92 , fRequiresBarrierBetweenOverlappingDraws(false) 93 , fIsInitialized(true) 94 , fInputColorType(kOriginal_InputColorType) {} 95 enum InputColorType : uint32_t { 96 kOriginal_InputColorType, 97 kOverridden_InputColorType, 98 kIgnored_InputColorType 99 }; 100 101 // MSVS 2015 won't pack different underlying types 102 using PackedBool = uint32_t; 103 using PackedInputColorType = uint32_t; 104 105 PackedBool fUsesLocalCoords : 1; 106 PackedBool fCompatibleWithCoverageAsAlpha : 1; 107 PackedBool fRequiresDstTexture : 1; 108 PackedBool fCanCombineOverlappedStencilAndCover : 1; 109 PackedBool fRequiresBarrierBetweenOverlappingDraws : 1; 110 PackedBool fIsInitialized : 1; 111 PackedInputColorType fInputColorType : 2; 112 113 friend class GrProcessorSet; 114 }; 115 GR_STATIC_ASSERT(sizeof(Analysis) <= sizeof(uint32_t)); 116 117 /** 118 * This analyzes the processors given an op's input color and coverage as well as a clip. The 119 * state of the processor set may change to an equivalent but more optimal set of processors. 120 * This new state requires that the caller respect the returned 'inputColorOverride'. This is 121 * indicated by the returned Analysis's inputColorIsOverriden(). 'inputColorOverride' will not 122 * be written if the analysis does not override the input color. 123 * 124 * This must be called before the processor set is used to construct a GrPipeline and may only 125 * be called once. 126 * 127 * This also puts the processors in "pending execution" state and must be called when an op 128 * that owns a processor set is recorded to ensure pending and writes are propagated to 129 * resources referred to by the processors. Otherwise, data hazards may occur. 130 */ 131 Analysis finalize(const GrProcessorAnalysisColor& colorInput, 132 const GrProcessorAnalysisCoverage coverageInput, const GrAppliedClip*, 133 bool isMixedSamples, const GrCaps&, GrColor* inputColorOverride); 134 isFinalized()135 bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); } 136 137 /** These are valid only for non-LCD coverage. */ 138 static const GrProcessorSet& EmptySet(); EmptySetAnalysis()139 static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); } 140 141 SkString dumpProcessors() const; 142 143 private: GrProcessorSet(Empty)144 GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {} 145 146 // This absurdly large limit allows Analysis and this to pack fields together. 147 static constexpr int kMaxColorProcessors = UINT8_MAX; 148 149 enum Flags : uint16_t { kFinalized_Flag = 0x1 }; 150 151 union XP { XP(const GrXPFactory * factory)152 XP(const GrXPFactory* factory) : fFactory(factory) {} XP(const GrXferProcessor * processor)153 XP(const GrXferProcessor* processor) : fProcessor(processor) {} 154 const GrXPFactory* fFactory; 155 const GrXferProcessor* fProcessor; 156 }; 157 xpFactory()158 const GrXPFactory* xpFactory() const { 159 SkASSERT(!this->isFinalized()); 160 return fXP.fFactory; 161 } 162 163 SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors; 164 XP fXP; 165 uint8_t fColorFragmentProcessorCnt = 0; 166 uint8_t fFragmentProcessorOffset = 0; 167 uint8_t fFlags; 168 }; 169 170 #endif 171