• 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 "include/core/SkMatrix.h"
12 #include "include/core/SkRefCnt.h"
13 #include "src/gpu/GrColor.h"
14 #include "src/gpu/GrFragmentProcessor.h"
15 #include "src/gpu/GrNonAtomicRef.h"
16 #include "src/gpu/GrPendingIOResource.h"
17 #include "src/gpu/GrProcessorSet.h"
18 #include "src/gpu/GrProgramDesc.h"
19 #include "src/gpu/GrScissorState.h"
20 #include "src/gpu/GrUserStencilSettings.h"
21 #include "src/gpu/GrWindowRectsState.h"
22 #include "src/gpu/effects/GrCoverageSetOpXP.h"
23 #include "src/gpu/effects/GrDisableColorXP.h"
24 #include "src/gpu/effects/GrPorterDuffXferProcessor.h"
25 #include "src/gpu/effects/generated/GrSimpleTextureEffect.h"
26 #include "src/gpu/geometry/GrRect.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     // Pipeline options that the caller may enable.
43     // NOTE: This enum is extended later by GrPipeline::Flags.
44     enum class InputFlags : uint8_t {
45         kNone = 0,
46         /**
47          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
48          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
49          * the 3D API.
50          */
51         kHWAntialias = (1 << 0),
52         /**
53          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
54          */
55         kSnapVerticesToPixelCenters = (1 << 1),  // This value must be last. (See kLastInputFlag.)
56     };
57 
58     struct InitArgs {
59         InputFlags fInputFlags = InputFlags::kNone;
60         const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
61         const GrCaps* fCaps = nullptr;
62         GrXferProcessor::DstProxy fDstProxy;
63         GrSwizzle fOutputSwizzle;
64     };
65 
66     /**
67      * Some state can be changed between GrMeshes without changing GrPipelines. This is generally
68      * less expensive then using multiple pipelines. Such state is called "dynamic state". It can
69      * be specified in two ways:
70      * 1) FixedDynamicState - use this to specify state that does not vary between GrMeshes.
71      * 2) DynamicStateArrays - use this to specify per mesh values for dynamic state.
72      **/
73     struct FixedDynamicState {
FixedDynamicStateFixedDynamicState74         explicit FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {}
75         FixedDynamicState() = default;
76         SkIRect fScissorRect = SkIRect::EmptyIRect();
77         // Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers
78         // or textures are passed using DynamicStateArrays.
79         GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
80     };
81 
82     /**
83      * Any non-null array overrides the FixedDynamicState on a mesh-by-mesh basis. Arrays must
84      * have one entry for each GrMesh.
85      */
86     struct DynamicStateArrays {
87         const SkIRect* fScissorRects = nullptr;
88         // Must have GrPrimitiveProcessor::numTextureSamplers() * num_meshes entries.
89         // Can be null if no samplers or to use the same textures for all meshes via'
90         // FixedDynamicState.
91         GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
92     };
93 
94     /**
95      * Creates a simple pipeline with default settings and no processors. The provided blend mode
96      * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
97      * specify a scissor rectangle through the DynamicState struct.
98      **/
99     GrPipeline(GrScissorTest scissor, SkBlendMode blend, const GrSwizzle& outputSwizzle,
100                InputFlags flags = InputFlags::kNone,
101                const GrUserStencilSettings* stencil = &GrUserStencilSettings::kUnused)
GrPipeline(scissor,GrPorterDuffXPFactory::MakeNoCoverageXP (blend),outputSwizzle,flags,stencil)102             : GrPipeline(scissor, GrPorterDuffXPFactory::MakeNoCoverageXP(blend), outputSwizzle,
103                          flags, stencil) {
104     }
105 
106     GrPipeline(GrScissorTest, sk_sp<const GrXferProcessor>, const GrSwizzle& outputSwizzle,
107                InputFlags = InputFlags::kNone,
108                const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
109 
110     GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
111 
112     GrPipeline(const GrPipeline&) = delete;
113     GrPipeline& operator=(const GrPipeline&) = delete;
114 
115     /// @}
116 
117     ///////////////////////////////////////////////////////////////////////////
118     /// @name GrFragmentProcessors
119 
numColorFragmentProcessors()120     int numColorFragmentProcessors() const { return fNumColorProcessors; }
numCoverageFragmentProcessors()121     int numCoverageFragmentProcessors() const {
122         return fFragmentProcessors.count() - fNumColorProcessors;
123     }
numFragmentProcessors()124     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
125 
getXferProcessor()126     const GrXferProcessor& getXferProcessor() const {
127         if (fXferProcessor) {
128             return *fXferProcessor.get();
129         } else {
130             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
131             // mechanism is not thread safe so we do not hold a ref on this global.
132             return GrPorterDuffXPFactory::SimpleSrcOverXP();
133         }
134     }
135 
136     /**
137      * If the GrXferProcessor uses a texture to access the dst color, then this returns that
138      * texture and the offset to the dst contents within that texture.
139      */
140     GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const {
141         if (offset) {
142             *offset = fDstTextureOffset;
143         }
144 
145         return fDstTextureProxy ? fDstTextureProxy->asTextureProxy() : nullptr;
146     }
147 
148     GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
149         if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) {
150             return dstProxy->peekTexture();
151         }
152 
153         return nullptr;
154     }
155 
getColorFragmentProcessor(int idx)156     const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
157         SkASSERT(idx < this->numColorFragmentProcessors());
158         return *fFragmentProcessors[idx].get();
159     }
160 
getCoverageFragmentProcessor(int idx)161     const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
162         SkASSERT(idx < this->numCoverageFragmentProcessors());
163         return *fFragmentProcessors[fNumColorProcessors + idx].get();
164     }
165 
getFragmentProcessor(int idx)166     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
167         return *fFragmentProcessors[idx].get();
168     }
169 
170     /// @}
171 
getUserStencil()172     const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
173 
isScissorEnabled()174     bool isScissorEnabled() const {
175         return SkToBool(fFlags & Flags::kScissorEnabled);
176     }
177 
getWindowRectsState()178     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
179 
isHWAntialiasState()180     bool isHWAntialiasState() const { return SkToBool(fFlags & InputFlags::kHWAntialias); }
snapVerticesToPixelCenters()181     bool snapVerticesToPixelCenters() const {
182         return SkToBool(fFlags & InputFlags::kSnapVerticesToPixelCenters);
183     }
hasStencilClip()184     bool hasStencilClip() const {
185         return SkToBool(fFlags & Flags::kHasStencilClip);
186     }
isStencilEnabled()187     bool isStencilEnabled() const {
188         return SkToBool(fFlags & Flags::kStencilEnabled);
189     }
190     SkDEBUGCODE(bool isBad() const { return SkToBool(fFlags & Flags::kIsBad); })
191 
192     GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const;
193 
194     // Used by Vulkan and Metal to cache their respective pipeline objects
195     uint32_t getBlendInfoKey() const;
196 
outputSwizzle()197     const GrSwizzle& outputSwizzle() const { return fOutputSwizzle; }
198 
199 private:
200 
201     SkDEBUGCODE(void markAsBad() { fFlags |= Flags::kIsBad; })
202 
203     static constexpr uint8_t kLastInputFlag = (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
204 
205     /** This is a continuation of the public "InputFlags" enum. */
206     enum class Flags : uint8_t {
207         kHasStencilClip = (kLastInputFlag << 1),
208         kStencilEnabled = (kLastInputFlag << 2),
209         kScissorEnabled = (kLastInputFlag << 3),
210 #ifdef SK_DEBUG
211         kIsBad = (kLastInputFlag << 4),
212 #endif
213     };
214 
215     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
216 
217     friend bool operator&(Flags, InputFlags);
218 
219     using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>;
220 
221     GrProxyPendingIO fDstTextureProxy;
222     SkIPoint fDstTextureOffset;
223     GrWindowRectsState fWindowRectsState;
224     const GrUserStencilSettings* fUserStencilSettings;
225     Flags fFlags;
226     sk_sp<const GrXferProcessor> fXferProcessor;
227     FragmentProcessorArray fFragmentProcessors;
228 
229     // This value is also the index in fFragmentProcessors where coverage processors begin.
230     int fNumColorProcessors;
231 
232     GrSwizzle fOutputSwizzle;
233 };
234 
235 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags);
236 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags);
237 
238 inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) {
239     return (flags & (GrPipeline::Flags)inputFlag);
240 }
241 
242 #endif
243