• 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/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/GrCoverageSetOpXP.h"
21 #include "src/gpu/effects/GrDisableColorXP.h"
22 #include "src/gpu/effects/GrPorterDuffXferProcessor.h"
23 #include "src/gpu/effects/GrTextureEffect.h"
24 #include "src/gpu/geometry/GrRect.h"
25 
26 class GrAppliedClip;
27 class GrAppliedHardClip;
28 class GrOp;
29 class GrSurfaceDrawContext;
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          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
47          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
48          * the 3D API.
49          */
50         kHWAntialias = (1 << 0),
51         /**
52          * Cause every pixel to be rasterized that is touched by the triangle anywhere (not just at
53          * pixel center). Additionally, if using MSAA, the sample mask will always have 100%
54          * coverage.
55          * NOTE: The primitive type must be a triangle type.
56          */
57         kConservativeRaster = (1 << 1),
58         /**
59          * Draws triangles as outlines.
60          */
61         kWireframe = (1 << 2),
62         /**
63          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
64          */
65         kSnapVerticesToPixelCenters = (1 << 3),  // This value must be last. (See kLastInputFlag.)
66     };
67 
68     struct InitArgs {
69         InputFlags fInputFlags = InputFlags::kNone;
70         const GrCaps* fCaps = nullptr;
71         GrXferProcessor::DstProxyView fDstProxyView;
72         GrSwizzle fWriteSwizzle;
73     };
74 
75     /**
76      * Creates a simple pipeline with default settings and no processors. The provided blend mode
77      * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
78      * specify a scissor rectangle through the DynamicState struct.
79      **/
80     GrPipeline(GrScissorTest scissor,
81                SkBlendMode blend,
82                const GrSwizzle& writeSwizzle,
83                InputFlags flags = InputFlags::kNone)
GrPipeline(scissor,GrPorterDuffXPFactory::MakeNoCoverageXP (blend),writeSwizzle,flags)84             : GrPipeline(scissor,
85                          GrPorterDuffXPFactory::MakeNoCoverageXP(blend),
86                          writeSwizzle,
87                          flags) {}
88 
89     GrPipeline(GrScissorTest,
90                sk_sp<const GrXferProcessor>,
91                const GrSwizzle& writeSwizzle,
92                InputFlags = InputFlags::kNone);
93 
94     GrPipeline(const InitArgs& args, sk_sp<const GrXferProcessor>, const GrAppliedHardClip&);
95     GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
96 
97     GrPipeline(const GrPipeline&) = delete;
98     GrPipeline& operator=(const GrPipeline&) = delete;
99 
100     /// @}
101 
102     ///////////////////////////////////////////////////////////////////////////
103     /// @name GrFragmentProcessors
104 
numFragmentProcessors()105     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
numColorFragmentProcessors()106     int numColorFragmentProcessors() const { return fNumColorProcessors; }
isColorFragmentProcessor(int idx)107     bool isColorFragmentProcessor(int idx) const { return idx < fNumColorProcessors; }
isCoverageFragmentProcessor(int idx)108     bool isCoverageFragmentProcessor(int idx) const { return idx >= fNumColorProcessors; }
109 
110     void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
111 
getXferProcessor()112     const GrXferProcessor& getXferProcessor() const {
113         if (fXferProcessor) {
114             return *fXferProcessor;
115         } else {
116             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
117             // mechanism is not thread safe so we do not hold a ref on this global.
118             return GrPorterDuffXPFactory::SimpleSrcOverXP();
119         }
120     }
121 
dstSampleType()122     GrDstSampleType dstSampleType() const {
123         return fDstSampleType;
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 {
129         return GrDstSampleTypeUsesTexture(fDstSampleType);
130     }
usesInputAttachment()131     bool usesInputAttachment() const {
132         return fDstSampleType == GrDstSampleType::kAsInputAttachment;
133     }
134 
135     /**
136      * This returns the GrSurfaceProxyView for the texture used to access the dst color. If the
137      * GrXferProcessor does not use the dst color then the proxy on the GrSurfaceProxyView will be
138      * nullptr.
139      */
dstProxyView()140     const GrSurfaceProxyView& dstProxyView() const { return fDstProxyView; }
141 
142     /**
143      * If the GrXferProcessor uses a texture to access the dst color, then this returns that
144      * texture and the offset to the dst contents within that texture.
145      */
146     GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
147         if (!this->usesDstTexture()) {
148             return nullptr;
149         }
150         if (offset) {
151             *offset = fDstTextureOffset;
152         }
153 
154         if (GrTextureProxy* dstProxy = fDstProxyView.asTextureProxy()) {
155             return dstProxy->peekTexture();
156         }
157 
158         return nullptr;
159     }
160 
getFragmentProcessor(int idx)161     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
162         return *fFragmentProcessors[idx];
163     }
164 
165     /// @}
166 
isScissorTestEnabled()167     bool isScissorTestEnabled() const {
168         return SkToBool(fFlags & Flags::kScissorTestEnabled);
169     }
170 
getWindowRectsState()171     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
172 
isHWAntialiasState()173     bool isHWAntialiasState() const { return fFlags & InputFlags::kHWAntialias; }
usesConservativeRaster()174     bool usesConservativeRaster() const { return fFlags & InputFlags::kConservativeRaster; }
isWireframe()175     bool isWireframe() const { return fFlags & InputFlags::kWireframe; }
snapVerticesToPixelCenters()176     bool snapVerticesToPixelCenters() const {
177         return fFlags & InputFlags::kSnapVerticesToPixelCenters;
178     }
hasStencilClip()179     bool hasStencilClip() const {
180         return SkToBool(fFlags & Flags::kHasStencilClip);
181     }
182 #ifdef SK_DEBUG
allProxiesInstantiated()183     bool allProxiesInstantiated() const {
184         for (int i = 0; i < fFragmentProcessors.count(); ++i) {
185             if (!fFragmentProcessors[i]->isInstantiated()) {
186                 return false;
187             }
188         }
189         if (fDstProxyView.proxy()) {
190             return fDstProxyView.proxy()->isInstantiated();
191         }
192 
193         return true;
194     }
195 #endif
196 
197     GrXferBarrierType xferBarrierType(const GrCaps&) const;
198 
199     // Used by Vulkan and Metal to cache their respective pipeline objects
200     void genKey(GrProcessorKeyBuilder*, const GrCaps&) const;
201 
writeSwizzle()202     const GrSwizzle& writeSwizzle() const { return fWriteSwizzle; }
203 
204     void visitProxies(const GrOp::VisitProxyFunc&) const;
205 
206 private:
207     static constexpr uint8_t kLastInputFlag = (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
208 
209     /** This is a continuation of the public "InputFlags" enum. */
210     enum class Flags : uint8_t {
211         kHasStencilClip = (kLastInputFlag << 1),
212         kScissorTestEnabled = (kLastInputFlag << 2),
213     };
214 
215     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
216 
217     friend bool operator&(Flags, InputFlags);
218 
219     // A pipeline can contain up to three processors: color, paint coverage, and clip coverage.
220     using FragmentProcessorArray = SkAutoSTArray<3, std::unique_ptr<const GrFragmentProcessor>>;
221 
222     GrSurfaceProxyView fDstProxyView;
223     SkIPoint fDstTextureOffset;
224     // This is the GrDstSampleType that is used for the render pass that this GrPipeline will be
225     // used in (i.e. if this GrPipeline does read the dst, it will do so using this
226     // GrDstSampleType).
227     GrDstSampleType fDstSampleType = GrDstSampleType::kNone;
228     GrWindowRectsState fWindowRectsState;
229     Flags fFlags;
230     sk_sp<const GrXferProcessor> fXferProcessor;
231     FragmentProcessorArray fFragmentProcessors;
232 
233     // This value is also the index in fFragmentProcessors where coverage processors begin.
234     int fNumColorProcessors = 0;
235 
236     GrSwizzle fWriteSwizzle;
237 };
238 
239 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags);
240 GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags);
241 
242 inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) {
243     return (flags & (GrPipeline::Flags)inputFlag);
244 }
245 
246 #endif
247