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