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