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