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