• 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 "GrFragmentProcessor.h"
12 #include "GrPaint.h"
13 #include "GrProcessorAnalysis.h"
14 #include "SkTemplates.h"
15 #include "GrXferProcessor.h"
16 
17 class GrAppliedClip;
18 class GrXPFactory;
19 
20 class GrProcessorSet : private SkNoncopyable {
21 private:
22     // Arbitrary constructor arg for empty set and analysis
23     enum class Empty { kEmpty };
24 
25 public:
26     GrProcessorSet(GrPaint&& paint);
27     GrProcessorSet(SkBlendMode mode);
28     GrProcessorSet(sk_sp<GrFragmentProcessor> colorFP);
29 
30     ~GrProcessorSet();
31 
numColorFragmentProcessors()32     int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
numCoverageFragmentProcessors()33     int numCoverageFragmentProcessors() const {
34         return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
35     }
numFragmentProcessors()36     int numFragmentProcessors() const {
37         return fFragmentProcessors.count() - fFragmentProcessorOffset;
38     }
39 
colorFragmentProcessor(int idx)40     const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
41         SkASSERT(idx < fColorFragmentProcessorCnt);
42         return fFragmentProcessors[idx + fFragmentProcessorOffset];
43     }
coverageFragmentProcessor(int idx)44     const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
45         return fFragmentProcessors[idx + fColorFragmentProcessorCnt + fFragmentProcessorOffset];
46     }
47 
xferProcessor()48     const GrXferProcessor* xferProcessor() const {
49         SkASSERT(this->isFinalized());
50         return fXP.fProcessor;
51     }
refXferProcessor()52     sk_sp<const GrXferProcessor> refXferProcessor() const {
53         SkASSERT(this->isFinalized());
54         return sk_ref_sp(fXP.fProcessor);
55     }
56 
57     /** Comparisons are only legal on finalized processor sets. */
58     bool operator==(const GrProcessorSet& that) const;
59     bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
60 
61     /**
62      * This is used to report results of processor analysis when a processor set is finalized (see
63      * below).
64      */
65     class Analysis {
66     public:
67         Analysis(const Analysis&) = default;
Analysis()68         Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
69 
isInitialized()70         bool isInitialized() const { return fIsInitialized; }
usesLocalCoords()71         bool usesLocalCoords() const { return fUsesLocalCoords; }
requiresDstTexture()72         bool requiresDstTexture() const { return fRequiresDstTexture; }
canCombineOverlappedStencilAndCover()73         bool canCombineOverlappedStencilAndCover() const {
74             return fCanCombineOverlappedStencilAndCover;
75         }
requiresBarrierBetweenOverlappingDraws()76         bool requiresBarrierBetweenOverlappingDraws() const {
77             return fRequiresBarrierBetweenOverlappingDraws;
78         }
isCompatibleWithCoverageAsAlpha()79         bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
80 
inputColorIsIgnored()81         bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
inputColorIsOverridden()82         bool inputColorIsOverridden() const {
83             return fInputColorType == kOverridden_InputColorType;
84         }
85 
86     private:
Analysis(Empty)87         constexpr Analysis(Empty)
88                 : fUsesLocalCoords(false)
89                 , fCompatibleWithCoverageAsAlpha(true)
90                 , fRequiresDstTexture(false)
91                 , fCanCombineOverlappedStencilAndCover(true)
92                 , fRequiresBarrierBetweenOverlappingDraws(false)
93                 , fIsInitialized(true)
94                 , fInputColorType(kOriginal_InputColorType) {}
95         enum InputColorType : uint32_t {
96             kOriginal_InputColorType,
97             kOverridden_InputColorType,
98             kIgnored_InputColorType
99         };
100 
101         // MSVS 2015 won't pack different underlying types
102         using PackedBool = uint32_t;
103         using PackedInputColorType = uint32_t;
104 
105         PackedBool fUsesLocalCoords : 1;
106         PackedBool fCompatibleWithCoverageAsAlpha : 1;
107         PackedBool fRequiresDstTexture : 1;
108         PackedBool fCanCombineOverlappedStencilAndCover : 1;
109         PackedBool fRequiresBarrierBetweenOverlappingDraws : 1;
110         PackedBool fIsInitialized : 1;
111         PackedInputColorType fInputColorType : 2;
112 
113         friend class GrProcessorSet;
114     };
115     GR_STATIC_ASSERT(sizeof(Analysis) <= sizeof(uint32_t));
116 
117     /**
118      * This analyzes the processors given an op's input color and coverage as well as a clip. The
119      * state of the processor set may change to an equivalent but more optimal set of processors.
120      * This new state requires that the caller respect the returned 'inputColorOverride'. This is
121      * indicated by the returned Analysis's inputColorIsOverriden(). 'inputColorOverride' will not
122      * be written if the analysis does not override the input color.
123      *
124      * This must be called before the processor set is used to construct a GrPipeline and may only
125      * be called once.
126      *
127      * This also puts the processors in "pending execution" state and must be called when an op
128      * that owns a processor set is recorded to ensure pending and writes are propagated to
129      * resources referred to by the processors. Otherwise, data hazards may occur.
130      */
131     Analysis finalize(const GrProcessorAnalysisColor& colorInput,
132                       const GrProcessorAnalysisCoverage coverageInput, const GrAppliedClip*,
133                       bool isMixedSamples, const GrCaps&, GrColor* inputColorOverride);
134 
isFinalized()135     bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
136 
137     /** These are valid only for non-LCD coverage. */
138     static const GrProcessorSet& EmptySet();
EmptySetAnalysis()139     static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
140 
141     SkString dumpProcessors() const;
142 
143 private:
GrProcessorSet(Empty)144     GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
145 
146     // This absurdly large limit allows Analysis and this to pack fields together.
147     static constexpr int kMaxColorProcessors = UINT8_MAX;
148 
149     enum Flags : uint16_t { kFinalized_Flag = 0x1 };
150 
151     union XP {
XP(const GrXPFactory * factory)152         XP(const GrXPFactory* factory) : fFactory(factory) {}
XP(const GrXferProcessor * processor)153         XP(const GrXferProcessor* processor) : fProcessor(processor) {}
154         const GrXPFactory* fFactory;
155         const GrXferProcessor* fProcessor;
156     };
157 
xpFactory()158     const GrXPFactory* xpFactory() const {
159         SkASSERT(!this->isFinalized());
160         return fXP.fFactory;
161     }
162 
163     SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors;
164     XP fXP;
165     uint8_t fColorFragmentProcessorCnt = 0;
166     uint8_t fFragmentProcessorOffset = 0;
167     uint8_t fFlags;
168 };
169 
170 #endif
171