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