• 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/SkRefCnt.h"
12 #include "src/gpu/ganesh/GrColor.h"
13 #include "src/gpu/ganesh/GrDstProxyView.h"
14 #include "src/gpu/ganesh/GrFragmentProcessor.h"
15 #include "src/gpu/ganesh/GrProcessorSet.h"
16 #include "src/gpu/ganesh/GrScissorState.h"
17 #include "src/gpu/ganesh/GrSurfaceProxyView.h"
18 #include "src/gpu/ganesh/GrTextureProxy.h"
19 #include "src/gpu/ganesh/GrUserStencilSettings.h"
20 #include "src/gpu/ganesh/GrWindowRectsState.h"
21 #include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h"
22 
23 class GrAppliedClip;
24 class GrAppliedHardClip;
25 struct GrGLSLBuiltinUniformHandles;
26 class GrGLSLProgramDataManager;
27 class GrOp;
28 class GrTextureEffect;
29 
30 /**
31  * This immutable object contains information needed to build a shader program and set API
32  * state for a draw. It is used along with a GrGeometryProcessor and a source of geometric
33  * data to draw.
34  */
35 class GrPipeline {
36 public:
37     ///////////////////////////////////////////////////////////////////////////
38     /// @name Creation
39 
40     // Pipeline options that the caller may enable.
41     // NOTE: This enum is extended later by GrPipeline::Flags.
42     enum class InputFlags : uint8_t {
43         kNone = 0,
44         /**
45          * Cause every pixel to be rasterized that is touched by the triangle anywhere (not just at
46          * pixel center). Additionally, if using MSAA, the sample mask will always have 100%
47          * coverage.
48          * NOTE: The primitive type must be a triangle type.
49          */
50         kConservativeRaster = (1 << 1),
51         /**
52          * Draws triangles as outlines.
53          */
54         kWireframe = (1 << 2),
55         /**
56          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
57          */
58         kSnapVerticesToPixelCenters = (1 << 3),  // This value must be last. (See kLastInputFlag.)
59     };
60 
61     struct InitArgs {
62         InputFlags fInputFlags = InputFlags::kNone;
63         const GrCaps* fCaps = nullptr;
64         GrDstProxyView fDstProxyView;
65         skgpu::Swizzle fWriteSwizzle;
66     };
67 
68     /**
69      * Creates a simple pipeline with default settings and no processors. The provided blend mode
70      * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
71      * specify a scissor rectangle through the DynamicState struct.
72      **/
73     GrPipeline(GrScissorTest scissor,
74                SkBlendMode blend,
75                const skgpu::Swizzle& writeSwizzle,
76                InputFlags flags = InputFlags::kNone)
GrPipeline(scissor,GrPorterDuffXPFactory::MakeNoCoverageXP (blend),writeSwizzle,flags)77             : GrPipeline(scissor,
78                          GrPorterDuffXPFactory::MakeNoCoverageXP(blend),
79                          writeSwizzle,
80                          flags) {}
81 
82     GrPipeline(GrScissorTest,
83                sk_sp<const GrXferProcessor>,
84                const skgpu::Swizzle& writeSwizzle,
85                InputFlags = InputFlags::kNone);
86 
87     GrPipeline(const InitArgs& args, sk_sp<const GrXferProcessor>, const GrAppliedHardClip&);
88     GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
89 
90     GrPipeline(const GrPipeline&) = delete;
91     GrPipeline& operator=(const GrPipeline&) = delete;
92 
93     /// @}
94 
95     ///////////////////////////////////////////////////////////////////////////
96     /// @name GrFragmentProcessors
97 
numFragmentProcessors()98     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
numColorFragmentProcessors()99     int numColorFragmentProcessors() const { return fNumColorProcessors; }
isColorFragmentProcessor(int idx)100     bool isColorFragmentProcessor(int idx) const { return idx < fNumColorProcessors; }
isCoverageFragmentProcessor(int idx)101     bool isCoverageFragmentProcessor(int idx) const { return idx >= fNumColorProcessors; }
102 
usesLocalCoords()103     bool usesLocalCoords() const {
104         // The sample coords for the top level FPs are implicitly the GP's local coords.
105         for (const auto& fp : fFragmentProcessors) {
106             if (fp->usesSampleCoords()) {
107                 return true;
108             }
109         }
110         return false;
111     }
112 
113     void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
114 
getXferProcessor()115     const GrXferProcessor& getXferProcessor() const {
116         if (fXferProcessor) {
117             return *fXferProcessor;
118         } else {
119             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
120             // mechanism is not thread safe so we do not hold a ref on this global.
121             return GrPorterDuffXPFactory::SimpleSrcOverXP();
122         }
123     }
124 
125     // Helper functions to quickly know if this GrPipeline will access the dst as a texture or an
126     // input attachment.
usesDstTexture()127     bool usesDstTexture() const { return this->dstProxyView() && !this->usesDstInputAttachment(); }
usesDstInputAttachment()128     bool usesDstInputAttachment() const {
129         return this->dstSampleFlags() & GrDstSampleFlags::kAsInputAttachment;
130     }
131 
132     /**
133      * This returns the GrSurfaceProxyView for the texture used to access the dst color. If the
134      * GrXferProcessor does not use the dst color then the proxy on the GrSurfaceProxyView will be
135      * nullptr.
136      */
dstProxyView()137     const GrSurfaceProxyView& dstProxyView() const { return fDstProxy.proxyView(); }
138 
dstTextureOffset()139     SkIPoint dstTextureOffset() const { return fDstProxy.offset(); }
140 
dstSampleFlags()141     GrDstSampleFlags dstSampleFlags() const { return fDstProxy.dstSampleFlags(); }
142 
143     /** If this GrXferProcessor uses a texture to access the dst color, returns that texture. */
peekDstTexture()144     GrTexture* peekDstTexture() const {
145         if (!this->usesDstTexture()) {
146             return nullptr;
147         }
148 
149         if (GrTextureProxy* dstProxy = this->dstProxyView().asTextureProxy()) {
150             return dstProxy->peekTexture();
151         }
152 
153         return nullptr;
154     }
155 
getFragmentProcessor(int idx)156     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
157         return *fFragmentProcessors[idx];
158     }
159 
160     /// @}
161 
isScissorTestEnabled()162     bool isScissorTestEnabled() const {
163         return SkToBool(fFlags & Flags::kScissorTestEnabled);
164     }
165 
getWindowRectsState()166     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
167 
usesConservativeRaster()168     bool usesConservativeRaster() const { return fFlags & InputFlags::kConservativeRaster; }
isWireframe()169     bool isWireframe() const { return fFlags & InputFlags::kWireframe; }
snapVerticesToPixelCenters()170     bool snapVerticesToPixelCenters() const {
171         return fFlags & InputFlags::kSnapVerticesToPixelCenters;
172     }
hasStencilClip()173     bool hasStencilClip() const {
174         return SkToBool(fFlags & Flags::kHasStencilClip);
175     }
176 #ifdef SK_DEBUG
allProxiesInstantiated()177     bool allProxiesInstantiated() const {
178         for (int i = 0; i < fFragmentProcessors.count(); ++i) {
179             if (!fFragmentProcessors[i]->isInstantiated()) {
180                 return false;
181             }
182         }
183         if (this->dstProxyView().proxy()) {
184             return this->dstProxyView().proxy()->isInstantiated();
185         }
186 
187         return true;
188     }
189 #endif
190 
191     GrXferBarrierType xferBarrierType(const GrCaps&) const;
192 
193     // Used by Vulkan and Metal to cache their respective pipeline objects
194     void genKey(skgpu::KeyBuilder*, const GrCaps&) const;
195 
writeSwizzle()196     const skgpu::Swizzle& writeSwizzle() const { return fWriteSwizzle; }
197 
198     void visitProxies(const GrVisitProxyFunc&) const;
199 
200     void setDstTextureUniforms(const GrGLSLProgramDataManager& pdm,
201                                GrGLSLBuiltinUniformHandles* fBuiltinUniformHandles) const;
202 
203 private:
204     inline static constexpr uint8_t kLastInputFlag =
205             (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
206 
207     /** This is a continuation of the public "InputFlags" enum. */
208     enum class Flags : uint8_t {
209         kHasStencilClip = (kLastInputFlag << 1),
210         kScissorTestEnabled = (kLastInputFlag << 2),
211     };
212 
213     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
214 
215     friend bool operator&(Flags, InputFlags);
216 
217     // A pipeline can contain up to three processors: color, paint coverage, and clip coverage.
218     using FragmentProcessorArray =
219             skia_private::AutoSTArray<3, std::unique_ptr<const GrFragmentProcessor>>;
220 
221     GrDstProxyView fDstProxy;
222     GrWindowRectsState fWindowRectsState;
223     Flags fFlags;
224     sk_sp<const GrXferProcessor> fXferProcessor;
225     FragmentProcessorArray fFragmentProcessors;
226 
227     // This value is also the index in fFragmentProcessors where coverage processors begin.
228     int fNumColorProcessors = 0;
229 
230     skgpu::Swizzle fWriteSwizzle;
231 };
232 
233 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags)
GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags)234 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags)
235 
236 inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) {
237     return (flags & (GrPipeline::Flags)inputFlag);
238 }
239 
240 #endif
241