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 // Advanced Filter: Check fFragmentProcessors recursively to find out AF status
203 bool checkAFRecursively() const;
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 = SkAutoSTArray<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 GrSwizzle 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