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