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