xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrProcessorSet.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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