• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrPendingIOResource.h"
15 #include "GrProcessorSet.h"
16 #include "GrProgramDesc.h"
17 #include "GrRect.h"
18 #include "GrScissorState.h"
19 #include "GrUserStencilSettings.h"
20 #include "GrWindowRectsState.h"
21 #include "SkMatrix.h"
22 #include "SkRefCnt.h"
23 #include "effects/GrCoverageSetOpXP.h"
24 #include "effects/GrDisableColorXP.h"
25 #include "effects/GrPorterDuffXferProcessor.h"
26 #include "effects/GrSimpleTextureEffect.h"
27 
28 class GrAppliedClip;
29 class GrOp;
30 class GrRenderTargetContext;
31 
32 /**
33  * This immutable object contains information needed to set build a shader program and set API
34  * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric
35  * data (GrMesh or GrPath) to draw.
36  */
37 class 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          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
51          */
52         kSnapVerticesToPixelCenters_Flag = 0x2,
53     };
54 
55     struct InitArgs {
56         uint32_t fFlags = 0;
57         const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
58         const GrCaps* fCaps = nullptr;
59         GrResourceProvider* fResourceProvider = nullptr;
60         GrXferProcessor::DstProxy fDstProxy;
61     };
62 
63     /**
64      * Some state can be changed between GrMeshes without changing GrPipelines. This is generally
65      * less expensive then using multiple pipelines. Such state is called "dynamic state". It can
66      * be specified in two ways:
67      * 1) FixedDynamicState - use this to specify state that does not vary between GrMeshes.
68      * 2) DynamicStateArrays - use this to specify per mesh values for dynamic state.
69      **/
70     struct FixedDynamicState {
FixedDynamicStateFixedDynamicState71         explicit FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {}
72         FixedDynamicState() = default;
73         SkIRect fScissorRect = SkIRect::EmptyIRect();
74         // Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers
75         // or textures are passed using DynamicStateArrays.
76         GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
77     };
78 
79     /**
80      * Any non-null array overrides the FixedDynamicState on a mesh-by-mesh basis. Arrays must
81      * have one entry for each GrMesh.
82      */
83     struct DynamicStateArrays {
84         const SkIRect* fScissorRects = nullptr;
85         // Must have GrPrimitiveProcessor::numTextureSamplers() * num_meshes entries.
86         // Can be null if no samplers or to use the same textures for all meshes via'
87         // FixedDynamicState.
88         GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
89     };
90 
91     /**
92      * Creates a simple pipeline with default settings and no processors. The provided blend mode
93      * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
94      * specify a scissor rectangle through the DynamicState struct.
95      **/
96     GrPipeline(GrScissorTest, SkBlendMode, uint32_t flags = 0,
97                const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
98 
99     GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
100 
101     GrPipeline(const GrPipeline&) = delete;
102     GrPipeline& operator=(const GrPipeline&) = delete;
103 
104     /// @}
105 
106     ///////////////////////////////////////////////////////////////////////////
107     /// @name GrFragmentProcessors
108 
109     // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline
110     void addDependenciesTo(GrOpList* recipient, const GrCaps&) const;
111 
numColorFragmentProcessors()112     int numColorFragmentProcessors() const { return fNumColorProcessors; }
numCoverageFragmentProcessors()113     int numCoverageFragmentProcessors() const {
114         return fFragmentProcessors.count() - fNumColorProcessors;
115     }
numFragmentProcessors()116     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
117 
getXferProcessor()118     const GrXferProcessor& getXferProcessor() const {
119         if (fXferProcessor) {
120             return *fXferProcessor.get();
121         } else {
122             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
123             // mechanism is not thread safe so we do not hold a ref on this global.
124             return GrPorterDuffXPFactory::SimpleSrcOverXP();
125         }
126     }
127 
128     /**
129      * If the GrXferProcessor uses a texture to access the dst color, then this returns that
130      * texture and the offset to the dst contents within that texture.
131      */
132     GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const {
133         if (offset) {
134             *offset = fDstTextureOffset;
135         }
136         return fDstTextureProxy.get();
137     }
138 
139     GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
140         if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) {
141             return dstProxy->peekTexture();
142         }
143 
144         return nullptr;
145     }
146 
getColorFragmentProcessor(int idx)147     const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
148         SkASSERT(idx < this->numColorFragmentProcessors());
149         return *fFragmentProcessors[idx].get();
150     }
151 
getCoverageFragmentProcessor(int idx)152     const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
153         SkASSERT(idx < this->numCoverageFragmentProcessors());
154         return *fFragmentProcessors[fNumColorProcessors + idx].get();
155     }
156 
getFragmentProcessor(int idx)157     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
158         return *fFragmentProcessors[idx].get();
159     }
160 
161     /// @}
162 
getUserStencil()163     const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
164 
isScissorEnabled()165     bool isScissorEnabled() const {
166         return SkToBool(fFlags & kScissorEnabled_Flag);
167     }
168 
getWindowRectsState()169     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
170 
isHWAntialiasState()171     bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
snapVerticesToPixelCenters()172     bool snapVerticesToPixelCenters() const {
173         return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
174     }
hasStencilClip()175     bool hasStencilClip() const {
176         return SkToBool(fFlags & kHasStencilClip_Flag);
177     }
isStencilEnabled()178     bool isStencilEnabled() const {
179         return SkToBool(fFlags & kStencilEnabled_Flag);
180     }
isBad()181     bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); }
182 
183     GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const;
184 
DumpFlags(uint32_t flags)185     static SkString DumpFlags(uint32_t flags) {
186         if (flags) {
187             SkString result;
188             if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) {
189                 result.append("Snap vertices to pixel center.\n");
190             }
191             if (flags & GrPipeline::kHWAntialias_Flag) {
192                 result.append("HW Antialiasing enabled.\n");
193             }
194             return result;
195         }
196         return SkString("No pipeline flags\n");
197     }
198 
199     // Used by Vulkan and Metal to cache their respective pipeline objects
200     uint32_t getBlendInfoKey() const;
201 
202 private:
markAsBad()203     void markAsBad() { fFlags |= kIsBad_Flag; }
204 
205     /** This is a continuation of the public "Flags" enum. */
206     enum PrivateFlags {
207         kHasStencilClip_Flag = 0x10,
208         kStencilEnabled_Flag = 0x20,
209         kScissorEnabled_Flag = 0x40,
210         kIsBad_Flag = 0x80,
211     };
212 
213     using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>;
214     using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>;
215 
216     DstTextureProxy fDstTextureProxy;
217     SkIPoint fDstTextureOffset;
218     GrWindowRectsState fWindowRectsState;
219     const GrUserStencilSettings* fUserStencilSettings;
220     uint16_t fFlags;
221     sk_sp<const GrXferProcessor> fXferProcessor;
222     FragmentProcessorArray fFragmentProcessors;
223 
224     // This value is also the index in fFragmentProcessors where coverage processors begin.
225     int fNumColorProcessors;
226 };
227 
228 #endif
229