blob: 9bef15b5a3e989bad0c74c0a1c8ebf609be8cd04 [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
egdanielb109ac22014-10-07 06:45:44 -070011#include "GrColor.h"
bsalomonac856c92015-08-27 06:30:17 -070012#include "GrFragmentProcessor.h"
joshualittdbe1e6f2015-07-16 08:12:45 -070013#include "GrNonAtomicRef.h"
Brian Salomonae5f9532018-07-31 11:03:40 -040014#include "GrPendingIOResource.h"
Brian Salomon5298dc82017-02-22 11:52:03 -050015#include "GrProcessorSet.h"
joshualitt79f8fae2014-10-28 17:59:26 -070016#include "GrProgramDesc.h"
Brian Salomona4677b52017-05-04 12:39:56 -040017#include "GrRect.h"
csmartdaltonbf4a8f92016-09-06 10:01:06 -070018#include "GrScissorState.h"
csmartdaltonc633abb2016-11-01 08:55:55 -070019#include "GrUserStencilSettings.h"
csmartdaltonbf4a8f92016-09-06 10:01:06 -070020#include "GrWindowRectsState.h"
egdanielb109ac22014-10-07 06:45:44 -070021#include "SkMatrix.h"
22#include "SkRefCnt.h"
robertphillips5fa7f302016-07-21 09:21:04 -070023#include "effects/GrCoverageSetOpXP.h"
24#include "effects/GrDisableColorXP.h"
25#include "effects/GrPorterDuffXferProcessor.h"
26#include "effects/GrSimpleTextureEffect.h"
27
Brian Salomon652ecb52017-01-17 12:39:53 -050028class GrAppliedClip;
Brian Salomon25a88092016-12-01 09:36:50 -050029class GrOp;
Brian Salomon25a88092016-12-01 09:36:50 -050030class GrRenderTargetContext;
egdaniel3658f382014-09-15 07:01:59 -070031
Brian Salomon92aee3d2016-12-21 09:20:25 -050032/**
Brian Salomone5b399e2017-07-19 13:50:54 -040033 * This immutable object contains information needed to set build a shader program and set API
34 * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric
35 * data (GrMesh or GrPath) to draw.
egdaniel3658f382014-09-15 07:01:59 -070036 */
Brian Salomon16351462017-07-19 16:35:31 -040037class GrPipeline {
egdaniel3658f382014-09-15 07:01:59 -070038public:
bsalomoncb02b382015-08-12 11:14:50 -070039 ///////////////////////////////////////////////////////////////////////////
40 /// @name Creation
41
Chris Daltonbaa1b352019-04-03 12:03:00 -060042 // Pipeline options that the caller may enable.
43 // NOTE: This enum is extended later by GrPipeline::Flags.
44 enum class InputFlags : uint8_t {
45 kNone = 0,
Brian Salomon189098e72017-01-19 09:55:19 -050046 /**
47 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
48 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
49 * the 3D API.
50 */
Chris Daltonbaa1b352019-04-03 12:03:00 -060051 kHWAntialias = (1 << 0),
Brian Salomon189098e72017-01-19 09:55:19 -050052 /**
53 * Modifies the vertex shader so that vertices will be positioned at pixel centers.
54 */
Chris Daltonbaa1b352019-04-03 12:03:00 -060055 kSnapVerticesToPixelCenters = (1 << 1), // This value must be last. (See kLastInputFlag.)
Brian Salomon189098e72017-01-19 09:55:19 -050056 };
57
Brian Salomonb5cb6832017-02-24 11:01:15 -050058 struct InitArgs {
Chris Daltonbaa1b352019-04-03 12:03:00 -060059 InputFlags fInputFlags = InputFlags::kNone;
Brian Salomon189098e72017-01-19 09:55:19 -050060 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
Brian Salomon189098e72017-01-19 09:55:19 -050061 const GrCaps* fCaps = nullptr;
Robert Phillips9bee2e52017-05-29 12:37:20 -040062 GrResourceProvider* fResourceProvider = nullptr;
Robert Phillipsbb581ce2017-05-29 15:05:15 -040063 GrXferProcessor::DstProxy fDstProxy;
bsalomona387a112015-08-11 14:47:42 -070064 };
65
Brian Salomonb5cb6832017-02-24 11:01:15 -050066 /**
Brian Salomon49348902018-06-26 09:12:38 -040067 * Some state can be changed between GrMeshes without changing GrPipelines. This is generally
68 * less expensive then using multiple pipelines. Such state is called "dynamic state". It can
69 * be specified in two ways:
70 * 1) FixedDynamicState - use this to specify state that does not vary between GrMeshes.
71 * 2) DynamicStateArrays - use this to specify per mesh values for dynamic state.
Chris Dalton46983b72017-06-06 12:27:16 -060072 **/
Brian Salomon49348902018-06-26 09:12:38 -040073 struct FixedDynamicState {
Brian Salomon7eae3e02018-08-07 14:02:38 +000074 explicit FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {}
75 FixedDynamicState() = default;
76 SkIRect fScissorRect = SkIRect::EmptyIRect();
Brian Salomonf7232642018-09-19 08:58:08 -040077 // Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers
78 // or textures are passed using DynamicStateArrays.
Brian Salomon7eae3e02018-08-07 14:02:38 +000079 GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
Chris Dalton46983b72017-06-06 12:27:16 -060080 };
81
82 /**
Brian Salomon49348902018-06-26 09:12:38 -040083 * Any non-null array overrides the FixedDynamicState on a mesh-by-mesh basis. Arrays must
84 * have one entry for each GrMesh.
85 */
86 struct DynamicStateArrays {
87 const SkIRect* fScissorRects = nullptr;
Brian Salomonf7232642018-09-19 08:58:08 -040088 // Must have GrPrimitiveProcessor::numTextureSamplers() * num_meshes entries.
89 // Can be null if no samplers or to use the same textures for all meshes via'
90 // FixedDynamicState.
91 GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
Brian Salomon49348902018-06-26 09:12:38 -040092 };
93
94 /**
csmartdalton119fb2b2017-02-08 14:41:05 -050095 * Creates a simple pipeline with default settings and no processors. The provided blend mode
Chris Dalton916c4982018-08-15 00:53:25 -060096 * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
Chris Dalton46983b72017-06-06 12:27:16 -060097 * specify a scissor rectangle through the DynamicState struct.
csmartdalton119fb2b2017-02-08 14:41:05 -050098 **/
Chris Daltonbaa1b352019-04-03 12:03:00 -060099 GrPipeline(GrScissorTest, SkBlendMode, InputFlags = InputFlags::kNone,
Chris Daltond7291ba2019-03-07 14:17:03 -0700100 const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
csmartdalton119fb2b2017-02-08 14:41:05 -0500101
Brian Salomonbfd18cd2017-08-09 16:27:09 -0400102 GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400103
Brian Salomon16351462017-07-19 16:35:31 -0400104 GrPipeline(const GrPipeline&) = delete;
105 GrPipeline& operator=(const GrPipeline&) = delete;
106
egdaniel89af44a2014-09-26 06:15:04 -0700107 /// @}
108
109 ///////////////////////////////////////////////////////////////////////////
bsalomon6be6f7c2015-02-26 13:05:21 -0800110 /// @name GrFragmentProcessors
egdaniel89af44a2014-09-26 06:15:04 -0700111
Robert Phillipsd261e102017-06-23 12:37:20 -0400112 // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline
113 void addDependenciesTo(GrOpList* recipient, const GrCaps&) const;
bsalomon6be6f7c2015-02-26 13:05:21 -0800114
bsalomonac856c92015-08-27 06:30:17 -0700115 int numColorFragmentProcessors() const { return fNumColorProcessors; }
116 int numCoverageFragmentProcessors() const {
117 return fFragmentProcessors.count() - fNumColorProcessors;
118 }
119 int numFragmentProcessors() const { return fFragmentProcessors.count(); }
egdaniel89af44a2014-09-26 06:15:04 -0700120
bsalomon2047b782015-12-21 13:12:54 -0800121 const GrXferProcessor& getXferProcessor() const {
Brian Salomond61c9d92017-04-10 10:54:25 -0400122 if (fXferProcessor) {
bsalomon2047b782015-12-21 13:12:54 -0800123 return *fXferProcessor.get();
124 } else {
125 // A null xp member means the common src-over case. GrXferProcessor's ref'ing
126 // mechanism is not thread safe so we do not hold a ref on this global.
127 return GrPorterDuffXPFactory::SimpleSrcOverXP();
128 }
129 }
egdaniel378092f2014-12-03 10:40:13 -0800130
Brian Salomon18dfa982017-04-03 16:57:43 -0400131 /**
132 * If the GrXferProcessor uses a texture to access the dst color, then this returns that
133 * texture and the offset to the dst contents within that texture.
134 */
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400135 GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const {
Brian Salomon18dfa982017-04-03 16:57:43 -0400136 if (offset) {
137 *offset = fDstTextureOffset;
138 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400139 return fDstTextureProxy.get();
140 }
141
142 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
143 if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400144 return dstProxy->peekTexture();
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400145 }
146
147 return nullptr;
Brian Salomon18dfa982017-04-03 16:57:43 -0400148 }
149
bsalomonac856c92015-08-27 06:30:17 -0700150 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
151 SkASSERT(idx < this->numColorFragmentProcessors());
152 return *fFragmentProcessors[idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700153 }
bsalomonac856c92015-08-27 06:30:17 -0700154
155 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
156 SkASSERT(idx < this->numCoverageFragmentProcessors());
157 return *fFragmentProcessors[fNumColorProcessors + idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700158 }
bsalomonac856c92015-08-27 06:30:17 -0700159
160 const GrFragmentProcessor& getFragmentProcessor(int idx) const {
161 return *fFragmentProcessors[idx].get();
bsalomonae59b772014-11-19 08:23:49 -0800162 }
egdaniel89af44a2014-09-26 06:15:04 -0700163
164 /// @}
165
csmartdaltonc633abb2016-11-01 08:55:55 -0700166 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
egdaniel89af44a2014-09-26 06:15:04 -0700167
Chris Dalton916c4982018-08-15 00:53:25 -0600168 bool isScissorEnabled() const {
Chris Daltonbaa1b352019-04-03 12:03:00 -0600169 return SkToBool(fFlags & Flags::kScissorEnabled);
Brian Salomon49348902018-06-26 09:12:38 -0400170 }
joshualitt54e0c122014-11-19 09:38:51 -0800171
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700172 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
csmartdalton28341fa2016-08-17 10:00:21 -0700173
Chris Daltonbaa1b352019-04-03 12:03:00 -0600174 bool isHWAntialiasState() const { return SkToBool(fFlags & InputFlags::kHWAntialias); }
Brian Salomon189098e72017-01-19 09:55:19 -0500175 bool snapVerticesToPixelCenters() const {
Chris Daltonbaa1b352019-04-03 12:03:00 -0600176 return SkToBool(fFlags & InputFlags::kSnapVerticesToPixelCenters);
Brian Salomon189098e72017-01-19 09:55:19 -0500177 }
cdalton193d9cf2016-05-12 11:52:02 -0700178 bool hasStencilClip() const {
Chris Daltonbaa1b352019-04-03 12:03:00 -0600179 return SkToBool(fFlags & Flags::kHasStencilClip);
cdalton193d9cf2016-05-12 11:52:02 -0700180 }
csmartdaltonc633abb2016-11-01 08:55:55 -0700181 bool isStencilEnabled() const {
Chris Daltonbaa1b352019-04-03 12:03:00 -0600182 return SkToBool(fFlags & Flags::kStencilEnabled);
csmartdaltonc633abb2016-11-01 08:55:55 -0700183 }
Chris Daltonbaa1b352019-04-03 12:03:00 -0600184 bool isBad() const { return SkToBool(fFlags & Flags::kIsBad); }
bsalomonae59b772014-11-19 08:23:49 -0800185
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500186 GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const;
bsalomoncb02b382015-08-12 11:14:50 -0700187
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500188 // Used by Vulkan and Metal to cache their respective pipeline objects
189 uint32_t getBlendInfoKey() const;
190
bsalomonae59b772014-11-19 08:23:49 -0800191private:
Chris Daltonbaa1b352019-04-03 12:03:00 -0600192 void markAsBad() { fFlags |= Flags::kIsBad; }
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400193
Chris Daltonbaa1b352019-04-03 12:03:00 -0600194 static constexpr uint8_t kLastInputFlag = (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
195
196 /** This is a continuation of the public "InputFlags" enum. */
197 enum class Flags : uint8_t {
198 kHasStencilClip = (kLastInputFlag << 1),
199 kStencilEnabled = (kLastInputFlag << 2),
200 kScissorEnabled = (kLastInputFlag << 3),
201 kIsBad = (kLastInputFlag << 4),
bsalomon04ddf892014-11-19 12:36:22 -0800202 };
203
Chris Daltonbaa1b352019-04-03 12:03:00 -0600204 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
205
206 friend bool operator&(Flags, InputFlags);
207
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400208 using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>;
Brian Salomonaff329b2017-08-11 09:40:37 -0400209 using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>;
Brian Salomon18dfa982017-04-03 16:57:43 -0400210
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400211 DstTextureProxy fDstTextureProxy;
Brian Salomon18dfa982017-04-03 16:57:43 -0400212 SkIPoint fDstTextureOffset;
Brian Salomon18dfa982017-04-03 16:57:43 -0400213 GrWindowRectsState fWindowRectsState;
214 const GrUserStencilSettings* fUserStencilSettings;
Chris Daltonbaa1b352019-04-03 12:03:00 -0600215 Flags fFlags;
Brian Salomond61c9d92017-04-10 10:54:25 -0400216 sk_sp<const GrXferProcessor> fXferProcessor;
Brian Salomon18dfa982017-04-03 16:57:43 -0400217 FragmentProcessorArray fFragmentProcessors;
egdanield9aa2182014-10-09 13:47:05 -0700218
bsalomonac856c92015-08-27 06:30:17 -0700219 // This value is also the index in fFragmentProcessors where coverage processors begin.
Brian Salomon18dfa982017-04-03 16:57:43 -0400220 int fNumColorProcessors;
egdaniel3658f382014-09-15 07:01:59 -0700221};
222
Chris Daltonbaa1b352019-04-03 12:03:00 -0600223GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags);
224GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags);
225
226inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) {
227 return (flags & (GrPipeline::Flags)inputFlag);
228}
229
egdaniel3658f382014-09-15 07:01:59 -0700230#endif