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