Line data Source code
1 : /*
2 : * Copyright 2015 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 GrPipeline_DEFINED
9 : #define GrPipeline_DEFINED
10 :
11 : #include "GrColor.h"
12 : #include "GrFragmentProcessor.h"
13 : #include "GrNonAtomicRef.h"
14 : #include "GrPendingProgramElement.h"
15 : #include "GrProcessorSet.h"
16 : #include "GrProgramDesc.h"
17 : #include "GrScissorState.h"
18 : #include "GrUserStencilSettings.h"
19 : #include "GrWindowRectsState.h"
20 : #include "SkMatrix.h"
21 : #include "SkRefCnt.h"
22 : #include "effects/GrCoverageSetOpXP.h"
23 : #include "effects/GrDisableColorXP.h"
24 : #include "effects/GrPorterDuffXferProcessor.h"
25 : #include "effects/GrSimpleTextureEffect.h"
26 :
27 : class GrAppliedClip;
28 : class GrDeviceCoordTexture;
29 : class GrOp;
30 : class GrPipelineBuilder;
31 : class GrRenderTargetContext;
32 :
33 : /**
34 : * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
35 : * class, and contains all data needed to set the state for a gpu draw.
36 : */
37 0 : class GrPipeline : public GrNonAtomicRef<GrPipeline> {
38 : public:
39 : ///////////////////////////////////////////////////////////////////////////
40 : /// @name Creation
41 :
42 : enum Flags {
43 : /**
44 : * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
45 : * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
46 : * the 3D API.
47 : */
48 : kHWAntialias_Flag = 0x1,
49 :
50 : /**
51 : * Modifies the vertex shader so that vertices will be positioned at pixel centers.
52 : */
53 : kSnapVerticesToPixelCenters_Flag = 0x2,
54 : };
55 :
56 0 : struct InitArgs {
57 : uint32_t fFlags = 0;
58 : GrDrawFace fDrawFace = GrDrawFace::kBoth;
59 : const GrProcessorSet* fProcessors = nullptr; // Must be finalized
60 : const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
61 : const GrAppliedClip* fAppliedClip = nullptr;
62 : GrRenderTarget* fRenderTarget = nullptr;
63 : const GrCaps* fCaps = nullptr;
64 : GrXferProcessor::DstTexture fDstTexture;
65 : };
66 :
67 : /**
68 : * A Default constructed pipeline is unusable until init() is called.
69 : **/
70 0 : GrPipeline() = default;
71 :
72 : /**
73 : * Creates a simple pipeline with default settings and no processors. The provided blend mode
74 : * must be "Porter Duff" (<= kLastCoeffMode). This pipeline is initialized without requiring
75 : * a call to init().
76 : **/
77 : GrPipeline(GrRenderTarget*, SkBlendMode);
78 :
79 : /** (Re)initializes a pipeline. After initialization the pipeline can be used. */
80 : void init(const InitArgs&);
81 :
82 : /** True if the pipeline has been initialized. */
83 0 : bool isInitialized() const { return SkToBool(fRenderTarget.get()); }
84 :
85 : /// @}
86 :
87 : ///////////////////////////////////////////////////////////////////////////
88 : /// @name Comparisons
89 :
90 : /**
91 : * Returns true if these pipelines are equivalent. Coord transforms may be applied either on
92 : * the GPU or the CPU. When we apply them on the CPU then the matrices need not agree in order
93 : * to combine draws. Therefore we take a param that indicates whether coord transforms should be
94 : * compared."
95 : */
96 : static bool AreEqual(const GrPipeline& a, const GrPipeline& b);
97 :
98 : /**
99 : * Allows a GrOp subclass to determine whether two GrOp instances can combine. This is a
100 : * stricter test than isEqual because it also considers blend barriers when the two ops'
101 : * bounds overlap
102 : */
103 0 : static bool CanCombine(const GrPipeline& a, const SkRect& aBounds,
104 : const GrPipeline& b, const SkRect& bBounds,
105 : const GrCaps& caps) {
106 0 : if (!AreEqual(a, b)) {
107 0 : return false;
108 : }
109 0 : if (a.xferBarrierType(caps)) {
110 0 : return aBounds.fRight <= bBounds.fLeft ||
111 0 : aBounds.fBottom <= bBounds.fTop ||
112 0 : bBounds.fRight <= aBounds.fLeft ||
113 0 : bBounds.fBottom <= aBounds.fTop;
114 : }
115 0 : return true;
116 : }
117 :
118 : /// @}
119 :
120 : ///////////////////////////////////////////////////////////////////////////
121 : /// @name GrFragmentProcessors
122 :
123 : // Make the renderTarget's GrOpList (if it exists) be dependent on any
124 : // GrOpLists in this pipeline
125 : void addDependenciesTo(GrRenderTarget* rt) const;
126 :
127 0 : int numColorFragmentProcessors() const { return fNumColorProcessors; }
128 0 : int numCoverageFragmentProcessors() const {
129 0 : return fFragmentProcessors.count() - fNumColorProcessors;
130 : }
131 0 : int numFragmentProcessors() const { return fFragmentProcessors.count(); }
132 :
133 0 : const GrXferProcessor& getXferProcessor() const {
134 0 : if (fXferProcessor) {
135 0 : return *fXferProcessor.get();
136 : } else {
137 : // A null xp member means the common src-over case. GrXferProcessor's ref'ing
138 : // mechanism is not thread safe so we do not hold a ref on this global.
139 0 : return GrPorterDuffXPFactory::SimpleSrcOverXP();
140 : }
141 : }
142 :
143 : /**
144 : * If the GrXferProcessor uses a texture to access the dst color, then this returns that
145 : * texture and the offset to the dst contents within that texture.
146 : */
147 0 : GrTexture* dstTexture(SkIPoint* offset = nullptr) const {
148 0 : if (offset) {
149 0 : *offset = fDstTextureOffset;
150 : }
151 0 : return fDstTexture.get();
152 : }
153 :
154 0 : const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
155 0 : SkASSERT(idx < this->numColorFragmentProcessors());
156 0 : return *fFragmentProcessors[idx].get();
157 : }
158 :
159 0 : const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
160 0 : SkASSERT(idx < this->numCoverageFragmentProcessors());
161 0 : return *fFragmentProcessors[fNumColorProcessors + idx].get();
162 : }
163 :
164 0 : const GrFragmentProcessor& getFragmentProcessor(int idx) const {
165 0 : return *fFragmentProcessors[idx].get();
166 : }
167 :
168 : /// @}
169 :
170 : /**
171 : * Retrieves the currently set render-target.
172 : *
173 : * @return The currently set render target.
174 : */
175 0 : GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
176 :
177 0 : const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
178 :
179 0 : const GrScissorState& getScissorState() const { return fScissorState; }
180 :
181 0 : const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
182 :
183 0 : bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
184 0 : bool snapVerticesToPixelCenters() const {
185 0 : return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
186 : }
187 0 : bool getDisableOutputConversionToSRGB() const {
188 0 : return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
189 : }
190 0 : bool getAllowSRGBInputs() const {
191 0 : return SkToBool(fFlags & kAllowSRGBInputs_Flag);
192 : }
193 0 : bool usesDistanceVectorField() const {
194 0 : return SkToBool(fFlags & kUsesDistanceVectorField_Flag);
195 : }
196 0 : bool hasStencilClip() const {
197 0 : return SkToBool(fFlags & kHasStencilClip_Flag);
198 : }
199 0 : bool isStencilEnabled() const {
200 0 : return SkToBool(fFlags & kStencilEnabled_Flag);
201 : }
202 :
203 0 : GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
204 0 : if (fDstTexture.get() && fDstTexture.get() == fRenderTarget.get()->asTexture()) {
205 0 : return kTexture_GrXferBarrierType;
206 : }
207 0 : return this->getXferProcessor().xferBarrierType(caps);
208 : }
209 :
210 : /**
211 : * Gets whether the target is drawing clockwise, counterclockwise,
212 : * or both faces.
213 : * @return the current draw face(s).
214 : */
215 0 : GrDrawFace getDrawFace() const { return static_cast<GrDrawFace>(fDrawFace); }
216 :
217 : private:
218 : /** This is a continuation of the public "Flags" enum. */
219 : enum PrivateFlags {
220 : kDisableOutputConversionToSRGB_Flag = 0x4,
221 : kAllowSRGBInputs_Flag = 0x8,
222 : kUsesDistanceVectorField_Flag = 0x10,
223 : kHasStencilClip_Flag = 0x20,
224 : kStencilEnabled_Flag = 0x40,
225 : };
226 :
227 : using RenderTarget = GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>;
228 : using DstTexture = GrPendingIOResource<GrTexture, kRead_GrIOType>;
229 : using PendingFragmentProcessor = GrPendingProgramElement<const GrFragmentProcessor>;
230 : using FragmentProcessorArray = SkAutoSTArray<8, PendingFragmentProcessor>;
231 :
232 : DstTexture fDstTexture;
233 : SkIPoint fDstTextureOffset;
234 : RenderTarget fRenderTarget;
235 : GrScissorState fScissorState;
236 : GrWindowRectsState fWindowRectsState;
237 : const GrUserStencilSettings* fUserStencilSettings;
238 : uint16_t fDrawFace;
239 : uint16_t fFlags;
240 : sk_sp<const GrXferProcessor> fXferProcessor;
241 : FragmentProcessorArray fFragmentProcessors;
242 :
243 : // This value is also the index in fFragmentProcessors where coverage processors begin.
244 : int fNumColorProcessors;
245 :
246 : typedef SkRefCnt INHERITED;
247 : };
248 :
249 : #endif
|