blob: 59210622486a827879b1246de4e42be5695b48b6 [file] [log] [blame]
egdaniel3658f382014-09-15 07:01:59 -07001/*
egdaniel8dd688b2015-01-22 10:16:09 -08002 * Copyright 2015 Google Inc.
egdaniel3658f382014-09-15 07:01:59 -07003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
egdaniel8dd688b2015-01-22 10:16:09 -08008#ifndef GrPipeline_DEFINED
9#define GrPipeline_DEFINED
egdaniel3658f382014-09-15 07:01:59 -070010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkMatrix.h"
12#include "include/core/SkRefCnt.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040013#include "src/gpu/GrColor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/GrFragmentProcessor.h"
15#include "src/gpu/GrNonAtomicRef.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/GrProcessorSet.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/gpu/GrScissorState.h"
Greg Daniel524e28b2019-11-01 11:48:53 -040018#include "src/gpu/GrSurfaceProxyView.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/gpu/GrUserStencilSettings.h"
20#include "src/gpu/GrWindowRectsState.h"
21#include "src/gpu/effects/GrCoverageSetOpXP.h"
22#include "src/gpu/effects/GrDisableColorXP.h"
23#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
24#include "src/gpu/effects/generated/GrSimpleTextureEffect.h"
Michael Ludwig663afe52019-06-03 16:46:19 -040025#include "src/gpu/geometry/GrRect.h"
robertphillips5fa7f302016-07-21 09:21:04 -070026
Brian Salomon652ecb52017-01-17 12:39:53 -050027class GrAppliedClip;
Brian Salomon25a88092016-12-01 09:36:50 -050028class GrOp;
Brian Salomon25a88092016-12-01 09:36:50 -050029class GrRenderTargetContext;
egdaniel3658f382014-09-15 07:01:59 -070030
Brian Salomon92aee3d2016-12-21 09:20:25 -050031/**
Brian Salomone5b399e2017-07-19 13:50:54 -040032 * This immutable object contains information needed to set build a shader program and set API
33 * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric
34 * data (GrMesh or GrPath) to draw.
egdaniel3658f382014-09-15 07:01:59 -070035 */
Brian Salomon16351462017-07-19 16:35:31 -040036class GrPipeline {
egdaniel3658f382014-09-15 07:01:59 -070037public:
bsalomoncb02b382015-08-12 11:14:50 -070038 ///////////////////////////////////////////////////////////////////////////
39 /// @name Creation
40
Chris Daltonbaa1b352019-04-03 12:03:00 -060041 // 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,
Brian Salomon189098e72017-01-19 09:55:19 -050045 /**
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 */
Chris Daltonbaa1b352019-04-03 12:03:00 -060050 kHWAntialias = (1 << 0),
Brian Salomon189098e72017-01-19 09:55:19 -050051 /**
52 * Modifies the vertex shader so that vertices will be positioned at pixel centers.
53 */
Robert Phillips368570d2019-11-05 19:51:18 +000054 kSnapVerticesToPixelCenters = (1 << 1), // This value must be last. (See kLastInputFlag.)
Brian Salomon189098e72017-01-19 09:55:19 -050055 };
56
Brian Salomonb5cb6832017-02-24 11:01:15 -050057 struct InitArgs {
Chris Daltonbaa1b352019-04-03 12:03:00 -060058 InputFlags fInputFlags = InputFlags::kNone;
Brian Salomon189098e72017-01-19 09:55:19 -050059 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
Brian Salomon189098e72017-01-19 09:55:19 -050060 const GrCaps* fCaps = nullptr;
Greg Daniel524e28b2019-11-01 11:48:53 -040061 GrXferProcessor::DstProxyView fDstProxyView;
Greg Daniel2c3398d2019-06-19 11:58:01 -040062 GrSwizzle fOutputSwizzle;
bsalomona387a112015-08-11 14:47:42 -070063 };
64
Brian Salomonb5cb6832017-02-24 11:01:15 -050065 /**
Brian Salomon49348902018-06-26 09:12:38 -040066 * Some state can be changed between GrMeshes without changing GrPipelines. This is generally
67 * less expensive then using multiple pipelines. Such state is called "dynamic state". It can
68 * be specified in two ways:
69 * 1) FixedDynamicState - use this to specify state that does not vary between GrMeshes.
70 * 2) DynamicStateArrays - use this to specify per mesh values for dynamic state.
Chris Dalton46983b72017-06-06 12:27:16 -060071 **/
Brian Salomon49348902018-06-26 09:12:38 -040072 struct FixedDynamicState {
Brian Salomon7eae3e02018-08-07 14:02:38 +000073 explicit FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {}
74 FixedDynamicState() = default;
75 SkIRect fScissorRect = SkIRect::EmptyIRect();
Brian Salomonf7232642018-09-19 08:58:08 -040076 // Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers
77 // or textures are passed using DynamicStateArrays.
Michael Ludwigfcdd0612019-11-25 08:34:31 -050078 GrSurfaceProxy** fPrimitiveProcessorTextures = nullptr;
Chris Dalton46983b72017-06-06 12:27:16 -060079 };
80
81 /**
Brian Salomon49348902018-06-26 09:12:38 -040082 * Any non-null array overrides the FixedDynamicState on a mesh-by-mesh basis. Arrays must
83 * have one entry for each GrMesh.
84 */
85 struct DynamicStateArrays {
86 const SkIRect* fScissorRects = nullptr;
Brian Salomonf7232642018-09-19 08:58:08 -040087 // Must have GrPrimitiveProcessor::numTextureSamplers() * num_meshes entries.
88 // Can be null if no samplers or to use the same textures for all meshes via'
89 // FixedDynamicState.
Michael Ludwigfcdd0612019-11-25 08:34:31 -050090 GrSurfaceProxy** fPrimitiveProcessorTextures = nullptr;
Brian Salomon49348902018-06-26 09:12:38 -040091 };
92
93 /**
csmartdalton119fb2b2017-02-08 14:41:05 -050094 * Creates a simple pipeline with default settings and no processors. The provided blend mode
Chris Dalton916c4982018-08-15 00:53:25 -060095 * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
Chris Dalton46983b72017-06-06 12:27:16 -060096 * specify a scissor rectangle through the DynamicState struct.
csmartdalton119fb2b2017-02-08 14:41:05 -050097 **/
Chris Daltonc3318f02019-07-19 14:20:53 -060098 GrPipeline(GrScissorTest scissor, SkBlendMode blend, const GrSwizzle& outputSwizzle,
99 InputFlags flags = InputFlags::kNone,
100 const GrUserStencilSettings* stencil = &GrUserStencilSettings::kUnused)
101 : GrPipeline(scissor, GrPorterDuffXPFactory::MakeNoCoverageXP(blend), outputSwizzle,
102 flags, stencil) {
103 }
104
105 GrPipeline(GrScissorTest, sk_sp<const GrXferProcessor>, const GrSwizzle& outputSwizzle,
Greg Daniel2c3398d2019-06-19 11:58:01 -0400106 InputFlags = InputFlags::kNone,
Chris Daltond7291ba2019-03-07 14:17:03 -0700107 const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
csmartdalton119fb2b2017-02-08 14:41:05 -0500108
Brian Salomonbfd18cd2017-08-09 16:27:09 -0400109 GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400110
Brian Salomon16351462017-07-19 16:35:31 -0400111 GrPipeline(const GrPipeline&) = delete;
112 GrPipeline& operator=(const GrPipeline&) = delete;
113
egdaniel89af44a2014-09-26 06:15:04 -0700114 /// @}
115
116 ///////////////////////////////////////////////////////////////////////////
bsalomon6be6f7c2015-02-26 13:05:21 -0800117 /// @name GrFragmentProcessors
egdaniel89af44a2014-09-26 06:15:04 -0700118
bsalomonac856c92015-08-27 06:30:17 -0700119 int numColorFragmentProcessors() const { return fNumColorProcessors; }
120 int numCoverageFragmentProcessors() const {
121 return fFragmentProcessors.count() - fNumColorProcessors;
122 }
123 int numFragmentProcessors() const { return fFragmentProcessors.count(); }
egdaniel89af44a2014-09-26 06:15:04 -0700124
bsalomon2047b782015-12-21 13:12:54 -0800125 const GrXferProcessor& getXferProcessor() const {
Brian Salomond61c9d92017-04-10 10:54:25 -0400126 if (fXferProcessor) {
bsalomon2047b782015-12-21 13:12:54 -0800127 return *fXferProcessor.get();
128 } else {
129 // A null xp member means the common src-over case. GrXferProcessor's ref'ing
130 // mechanism is not thread safe so we do not hold a ref on this global.
131 return GrPorterDuffXPFactory::SimpleSrcOverXP();
132 }
133 }
egdaniel378092f2014-12-03 10:40:13 -0800134
Brian Salomon18dfa982017-04-03 16:57:43 -0400135 /**
Greg Daniel524e28b2019-11-01 11:48:53 -0400136 * 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 */
140 const GrSurfaceProxyView& dstProxyView() const {
141 return fDstProxyView;
142 }
143
144 /**
Brian Salomon18dfa982017-04-03 16:57:43 -0400145 * If the GrXferProcessor uses a texture to access the dst color, then this returns that
146 * texture and the offset to the dst contents within that texture.
147 */
Greg Daniel524e28b2019-11-01 11:48:53 -0400148 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
Brian Salomon18dfa982017-04-03 16:57:43 -0400149 if (offset) {
150 *offset = fDstTextureOffset;
151 }
Robert Phillips3d4cac52019-06-11 08:08:08 -0400152
Greg Daniel524e28b2019-11-01 11:48:53 -0400153 if (GrTextureProxy* dstProxy = fDstProxyView.asTextureProxy()) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400154 return dstProxy->peekTexture();
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400155 }
156
157 return nullptr;
Brian Salomon18dfa982017-04-03 16:57:43 -0400158 }
159
bsalomonac856c92015-08-27 06:30:17 -0700160 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
161 SkASSERT(idx < this->numColorFragmentProcessors());
162 return *fFragmentProcessors[idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700163 }
bsalomonac856c92015-08-27 06:30:17 -0700164
165 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
166 SkASSERT(idx < this->numCoverageFragmentProcessors());
167 return *fFragmentProcessors[fNumColorProcessors + idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700168 }
bsalomonac856c92015-08-27 06:30:17 -0700169
170 const GrFragmentProcessor& getFragmentProcessor(int idx) const {
171 return *fFragmentProcessors[idx].get();
bsalomonae59b772014-11-19 08:23:49 -0800172 }
egdaniel89af44a2014-09-26 06:15:04 -0700173
174 /// @}
175
csmartdaltonc633abb2016-11-01 08:55:55 -0700176 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
egdaniel89af44a2014-09-26 06:15:04 -0700177
Chris Dalton916c4982018-08-15 00:53:25 -0600178 bool isScissorEnabled() const {
Chris Daltonbaa1b352019-04-03 12:03:00 -0600179 return SkToBool(fFlags & Flags::kScissorEnabled);
Brian Salomon49348902018-06-26 09:12:38 -0400180 }
joshualitt54e0c122014-11-19 09:38:51 -0800181
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700182 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
csmartdalton28341fa2016-08-17 10:00:21 -0700183
Robert Phillips368570d2019-11-05 19:51:18 +0000184 bool isHWAntialiasState() const { return SkToBool(fFlags & InputFlags::kHWAntialias); }
Brian Salomon189098e72017-01-19 09:55:19 -0500185 bool snapVerticesToPixelCenters() const {
Robert Phillips368570d2019-11-05 19:51:18 +0000186 return SkToBool(fFlags & InputFlags::kSnapVerticesToPixelCenters);
Brian Salomon189098e72017-01-19 09:55:19 -0500187 }
cdalton193d9cf2016-05-12 11:52:02 -0700188 bool hasStencilClip() const {
Chris Daltonbaa1b352019-04-03 12:03:00 -0600189 return SkToBool(fFlags & Flags::kHasStencilClip);
cdalton193d9cf2016-05-12 11:52:02 -0700190 }
csmartdaltonc633abb2016-11-01 08:55:55 -0700191 bool isStencilEnabled() const {
Chris Daltonbaa1b352019-04-03 12:03:00 -0600192 return SkToBool(fFlags & Flags::kStencilEnabled);
csmartdaltonc633abb2016-11-01 08:55:55 -0700193 }
Robert Phillips8053c972019-11-21 10:44:53 -0500194#ifdef SK_DEBUG
195 bool allProxiesInstantiated() const {
196 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
197 if (!fFragmentProcessors[i]->isInstantiated()) {
198 return false;
199 }
200 }
201 if (fDstProxyView.proxy()) {
202 return fDstProxyView.proxy()->isInstantiated();
203 }
204
205 return true;
206 }
207#endif
bsalomonae59b772014-11-19 08:23:49 -0800208
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500209 GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const;
bsalomoncb02b382015-08-12 11:14:50 -0700210
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500211 // Used by Vulkan and Metal to cache their respective pipeline objects
Chris Daltonb204e4c2019-11-07 12:43:13 -0700212 void genKey(GrProcessorKeyBuilder*, const GrCaps&) const;
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500213
Greg Daniel2c3398d2019-06-19 11:58:01 -0400214 const GrSwizzle& outputSwizzle() const { return fOutputSwizzle; }
215
Brian Salomonc241b582019-11-27 08:57:17 -0500216 void visitProxies(const GrOp::VisitProxyFunc&) const;
Robert Phillips8053c972019-11-21 10:44:53 -0500217
bsalomonae59b772014-11-19 08:23:49 -0800218private:
Chris Daltonbaa1b352019-04-03 12:03:00 -0600219 static constexpr uint8_t kLastInputFlag = (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
220
221 /** This is a continuation of the public "InputFlags" enum. */
222 enum class Flags : uint8_t {
223 kHasStencilClip = (kLastInputFlag << 1),
224 kStencilEnabled = (kLastInputFlag << 2),
225 kScissorEnabled = (kLastInputFlag << 3),
bsalomon04ddf892014-11-19 12:36:22 -0800226 };
227
Chris Daltonbaa1b352019-04-03 12:03:00 -0600228 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
229
230 friend bool operator&(Flags, InputFlags);
231
Brian Salomonaff329b2017-08-11 09:40:37 -0400232 using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>;
Brian Salomon18dfa982017-04-03 16:57:43 -0400233
Greg Daniel524e28b2019-11-01 11:48:53 -0400234 GrSurfaceProxyView fDstProxyView;
Brian Salomon18dfa982017-04-03 16:57:43 -0400235 SkIPoint fDstTextureOffset;
Brian Salomon18dfa982017-04-03 16:57:43 -0400236 GrWindowRectsState fWindowRectsState;
237 const GrUserStencilSettings* fUserStencilSettings;
Chris Daltonbaa1b352019-04-03 12:03:00 -0600238 Flags fFlags;
Brian Salomond61c9d92017-04-10 10:54:25 -0400239 sk_sp<const GrXferProcessor> fXferProcessor;
Brian Salomon18dfa982017-04-03 16:57:43 -0400240 FragmentProcessorArray fFragmentProcessors;
egdanield9aa2182014-10-09 13:47:05 -0700241
bsalomonac856c92015-08-27 06:30:17 -0700242 // This value is also the index in fFragmentProcessors where coverage processors begin.
Brian Salomon18dfa982017-04-03 16:57:43 -0400243 int fNumColorProcessors;
Greg Daniel2c3398d2019-06-19 11:58:01 -0400244
245 GrSwizzle fOutputSwizzle;
egdaniel3658f382014-09-15 07:01:59 -0700246};
247
Chris Daltonbaa1b352019-04-03 12:03:00 -0600248GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags);
249GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags);
250
251inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) {
252 return (flags & (GrPipeline::Flags)inputFlag);
253}
254
egdaniel3658f382014-09-15 07:01:59 -0700255#endif