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