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