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 "include/private/base/SkTemplates.h" 12 #include "src/gpu/ganesh/GrFragmentProcessor.h" 13 #include "src/gpu/ganesh/GrPaint.h" 14 #include "src/gpu/ganesh/GrProcessorAnalysis.h" 15 #include "src/gpu/ganesh/GrXferProcessor.h" 16 17 struct GrUserStencilSettings; 18 class GrAppliedClip; 19 class GrXPFactory; 20 21 class GrProcessorSet { 22 private: 23 // Arbitrary constructor arg for empty set and analysis 24 enum class Empty { kEmpty }; 25 26 public: 27 GrProcessorSet(GrPaint&&); 28 GrProcessorSet(SkBlendMode); 29 GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP); 30 GrProcessorSet(GrProcessorSet&&); 31 GrProcessorSet(const GrProcessorSet&) = delete; 32 GrProcessorSet& operator=(const GrProcessorSet&) = delete; 33 34 ~GrProcessorSet(); 35 hasColorFragmentProcessor()36 bool hasColorFragmentProcessor() const { return fColorFragmentProcessor != nullptr; } hasCoverageFragmentProcessor()37 bool hasCoverageFragmentProcessor() const { return fCoverageFragmentProcessor != nullptr; } 38 colorFragmentProcessor()39 const GrFragmentProcessor* colorFragmentProcessor() const { 40 return fColorFragmentProcessor.get(); 41 } coverageFragmentProcessor()42 const GrFragmentProcessor* coverageFragmentProcessor() const { 43 return fCoverageFragmentProcessor.get(); 44 } 45 xferProcessor()46 const GrXferProcessor* xferProcessor() const { 47 SkASSERT(this->isFinalized()); 48 return fXP.fProcessor; 49 } refXferProcessor()50 sk_sp<const GrXferProcessor> refXferProcessor() const { 51 SkASSERT(this->isFinalized()); 52 return sk_ref_sp(fXP.fProcessor); 53 } 54 detachColorFragmentProcessor()55 std::unique_ptr<GrFragmentProcessor> detachColorFragmentProcessor() { 56 return std::move(fColorFragmentProcessor); 57 } 58 detachCoverageFragmentProcessor()59 std::unique_ptr<GrFragmentProcessor> detachCoverageFragmentProcessor() { 60 return std::move(fCoverageFragmentProcessor); 61 } 62 63 /** Comparisons are only legal on finalized processor sets. */ 64 bool operator==(const GrProcessorSet& that) const; 65 bool operator!=(const GrProcessorSet& that) const { return !(*this == that); } 66 67 /** 68 * This is used to report results of processor analysis when a processor set is finalized (see 69 * below). 70 */ 71 class Analysis { 72 public: 73 Analysis(const Analysis&) = default; Analysis()74 Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; } 75 76 Analysis& operator=(const Analysis &other) = default; 77 isInitialized()78 bool isInitialized() const { return fIsInitialized; } usesLocalCoords()79 bool usesLocalCoords() const { return fUsesLocalCoords; } requiresDstTexture()80 bool requiresDstTexture() const { return fRequiresDstTexture; } requiresNonOverlappingDraws()81 bool requiresNonOverlappingDraws() const { return fRequiresNonOverlappingDraws; } isCompatibleWithCoverageAsAlpha()82 bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; } 83 // Indicates whether all color fragment processors were eliminated in the analysis. hasColorFragmentProcessor()84 bool hasColorFragmentProcessor() const { return fHasColorFragmentProcessor; } 85 inputColorIsIgnored()86 bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; } inputColorIsOverridden()87 bool inputColorIsOverridden() const { 88 return fInputColorType == kOverridden_InputColorType; 89 } usesNonCoherentHWBlending()90 bool usesNonCoherentHWBlending() const { return fUsesNonCoherentHWBlending; } unaffectedByDstValue()91 bool unaffectedByDstValue() const { return fUnaffectedByDstValue; } 92 93 private: Analysis(Empty)94 constexpr Analysis(Empty) 95 : fUsesLocalCoords(false) 96 , fCompatibleWithCoverageAsAlpha(true) 97 , fRequiresDstTexture(false) 98 , fRequiresNonOverlappingDraws(false) 99 , fHasColorFragmentProcessor(false) 100 , fIsInitialized(true) 101 , fUsesNonCoherentHWBlending(false) 102 , fUnaffectedByDstValue(false) 103 , fInputColorType(kOriginal_InputColorType) {} 104 enum InputColorType : uint32_t { 105 kOriginal_InputColorType, 106 kOverridden_InputColorType, 107 kIgnored_InputColorType 108 }; 109 110 // MSVS 2015 won't pack different underlying types 111 using PackedBool = uint32_t; 112 using PackedInputColorType = uint32_t; 113 114 PackedBool fUsesLocalCoords : 1; 115 PackedBool fCompatibleWithCoverageAsAlpha : 1; 116 PackedBool fRequiresDstTexture : 1; 117 PackedBool fRequiresNonOverlappingDraws : 1; 118 PackedBool fHasColorFragmentProcessor : 1; 119 PackedBool fIsInitialized : 1; 120 PackedBool fUsesNonCoherentHWBlending : 1; 121 PackedBool fUnaffectedByDstValue : 1; 122 PackedInputColorType fInputColorType : 2; 123 124 friend class GrProcessorSet; 125 }; 126 static_assert(sizeof(Analysis) <= sizeof(uint32_t)); 127 128 /** 129 * This analyzes the processors given an op's input color and coverage as well as a clip. The 130 * state of the processor set may change to an equivalent but more optimal set of processors. 131 * This new state requires that the caller respect the returned 'inputColorOverride'. This is 132 * indicated by the returned Analysis's inputColorIsOverridden(). 'inputColorOverride' will not 133 * be written if the analysis does not override the input color. 134 * 135 * This must be called before the processor set is used to construct a GrPipeline and may only 136 * be called once. 137 * 138 * This also puts the processors in "pending execution" state and must be called when an op 139 * that owns a processor set is recorded to ensure pending and writes are propagated to 140 * resources referred to by the processors. Otherwise, data hazards may occur. 141 */ 142 Analysis finalize(const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage, 143 const GrAppliedClip*, const GrUserStencilSettings*, const GrCaps&, 144 GrClampType, SkPMColor4f* inputColorOverride); 145 isFinalized()146 bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); } 147 148 /** These are valid only for non-LCD coverage. */ 149 static const GrProcessorSet& EmptySet(); 150 static GrProcessorSet MakeEmptySet(); EmptySetAnalysis()151 static constexpr Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); } 152 153 #if GR_TEST_UTILS 154 SkString dumpProcessors() const; 155 #endif 156 157 void visitProxies(const GrVisitProxyFunc&) const; 158 159 private: GrProcessorSet(Empty)160 GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {} 161 numFragmentProcessors()162 int numFragmentProcessors() const { 163 return (fColorFragmentProcessor ? 1 : 0) + (fCoverageFragmentProcessor ? 1 : 0); 164 } 165 166 enum Flags : uint16_t { kFinalized_Flag = 0x1 }; 167 168 union XP { XP(const GrXPFactory * factory)169 XP(const GrXPFactory* factory) : fFactory(factory) {} XP(const GrXferProcessor * processor)170 XP(const GrXferProcessor* processor) : fProcessor(processor) {} XP(XP && that)171 explicit XP(XP&& that) : fProcessor(that.fProcessor) { 172 SkASSERT(fProcessor == that.fProcessor); 173 that.fProcessor = nullptr; 174 } 175 const GrXPFactory* fFactory; 176 const GrXferProcessor* fProcessor; 177 }; 178 xpFactory()179 const GrXPFactory* xpFactory() const { 180 SkASSERT(!this->isFinalized()); 181 return fXP.fFactory; 182 } 183 184 std::unique_ptr<GrFragmentProcessor> fColorFragmentProcessor; 185 std::unique_ptr<GrFragmentProcessor> fCoverageFragmentProcessor; 186 XP fXP; 187 uint8_t fFlags = 0; 188 }; 189 190 #endif 191