blob: 5d6041c5ef7529420157d10a527663d270ed74c4 [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"
bsalomonac856c92015-08-27 06:30:17 -070014#include "GrPendingProgramElement.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"
Robert Phillipsc9c06d42017-06-12 10:58:31 -040018#include "GrRenderTarget.h"
csmartdaltonbf4a8f92016-09-06 10:01:06 -070019#include "GrScissorState.h"
csmartdaltonc633abb2016-11-01 08:55:55 -070020#include "GrUserStencilSettings.h"
csmartdaltonbf4a8f92016-09-06 10:01:06 -070021#include "GrWindowRectsState.h"
egdanielb109ac22014-10-07 06:45:44 -070022#include "SkMatrix.h"
23#include "SkRefCnt.h"
robertphillips5fa7f302016-07-21 09:21:04 -070024#include "effects/GrCoverageSetOpXP.h"
25#include "effects/GrDisableColorXP.h"
26#include "effects/GrPorterDuffXferProcessor.h"
27#include "effects/GrSimpleTextureEffect.h"
28
Brian Salomon652ecb52017-01-17 12:39:53 -050029class GrAppliedClip;
joshualitt79f8fae2014-10-28 17:59:26 -070030class GrDeviceCoordTexture;
Brian Salomon25a88092016-12-01 09:36:50 -050031class GrOp;
egdaniel8dd688b2015-01-22 10:16:09 -080032class GrPipelineBuilder;
Brian Salomon25a88092016-12-01 09:36:50 -050033class GrRenderTargetContext;
egdaniel3658f382014-09-15 07:01:59 -070034
Brian Salomon92aee3d2016-12-21 09:20:25 -050035/**
egdaniel8dd688b2015-01-22 10:16:09 -080036 * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
37 * class, and contains all data needed to set the state for a gpu draw.
egdaniel3658f382014-09-15 07:01:59 -070038 */
cdalton4833f392016-02-02 22:46:16 -080039class GrPipeline : public GrNonAtomicRef<GrPipeline> {
egdaniel3658f382014-09-15 07:01:59 -070040public:
bsalomoncb02b382015-08-12 11:14:50 -070041 ///////////////////////////////////////////////////////////////////////////
42 /// @name Creation
43
Brian Salomon189098e72017-01-19 09:55:19 -050044 enum Flags {
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_Flag = 0x1,
Brian Salomon189098e72017-01-19 09:55:19 -050051 /**
52 * Modifies the vertex shader so that vertices will be positioned at pixel centers.
53 */
54 kSnapVerticesToPixelCenters_Flag = 0x2,
Brian Salomon611572c2017-04-28 08:57:12 -040055 /** Disables conversion to sRGB from linear when writing to a sRGB destination. */
56 kDisableOutputConversionToSRGB_Flag = 0x4,
57 /** Allows conversion from sRGB to linear when reading from processor's sRGB texture. */
58 kAllowSRGBInputs_Flag = 0x8,
Brian Salomon189098e72017-01-19 09:55:19 -050059 };
60
Brian Salomon611572c2017-04-28 08:57:12 -040061 static uint32_t SRGBFlagsFromPaint(const GrPaint& paint) {
62 uint32_t flags = 0;
63 if (paint.getAllowSRGBInputs()) {
64 flags |= kAllowSRGBInputs_Flag;
65 }
66 if (paint.getDisableOutputConversionToSRGB()) {
67 flags |= kDisableOutputConversionToSRGB_Flag;
68 }
69 return flags;
70 }
71
Chris Dalton46983b72017-06-06 12:27:16 -060072 enum ScissorState : bool {
73 kEnabled = true,
74 kDisabled = false
75 };
76
Brian Salomonb5cb6832017-02-24 11:01:15 -050077 struct InitArgs {
Brian Salomon189098e72017-01-19 09:55:19 -050078 uint32_t fFlags = 0;
Brian Salomon48d1b4c2017-04-08 07:38:53 -040079 const GrProcessorSet* fProcessors = nullptr; // Must be finalized
Brian Salomon189098e72017-01-19 09:55:19 -050080 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
Brian Salomonb5cb6832017-02-24 11:01:15 -050081 const GrAppliedClip* fAppliedClip = nullptr;
Brian Salomonb16e8ac2017-02-22 11:52:36 -050082 GrRenderTarget* fRenderTarget = nullptr;
Brian Salomon189098e72017-01-19 09:55:19 -050083 const GrCaps* fCaps = nullptr;
Robert Phillips9bee2e52017-05-29 12:37:20 -040084 GrResourceProvider* fResourceProvider = nullptr;
Robert Phillipsbb581ce2017-05-29 15:05:15 -040085 GrXferProcessor::DstProxy fDstProxy;
bsalomona387a112015-08-11 14:47:42 -070086 };
87
Brian Salomonb5cb6832017-02-24 11:01:15 -050088 /**
Chris Dalton46983b72017-06-06 12:27:16 -060089 * Graphics state that can change dynamically without creating a new pipeline.
90 **/
91 struct DynamicState {
92 // Overrides the scissor rectangle (if scissor is enabled in the pipeline).
93 // TODO: eventually this should be the only way to specify a scissor rectangle, as is the
94 // case with the simple constructor.
95 SkIRect fScissorRect;
96 };
97
98 /**
Brian Salomonb5cb6832017-02-24 11:01:15 -050099 * A Default constructed pipeline is unusable until init() is called.
100 **/
101 GrPipeline() = default;
egdanielb109ac22014-10-07 06:45:44 -0700102
csmartdalton119fb2b2017-02-08 14:41:05 -0500103 /**
104 * Creates a simple pipeline with default settings and no processors. The provided blend mode
Chris Dalton46983b72017-06-06 12:27:16 -0600105 * must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must
106 * specify a scissor rectangle through the DynamicState struct.
csmartdalton119fb2b2017-02-08 14:41:05 -0500107 **/
Chris Dalton46983b72017-06-06 12:27:16 -0600108 GrPipeline(GrRenderTarget*, ScissorState, SkBlendMode);
csmartdalton119fb2b2017-02-08 14:41:05 -0500109
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400110 GrPipeline(const InitArgs& args) { this->init(args); }
111
Brian Salomonb5cb6832017-02-24 11:01:15 -0500112 /** (Re)initializes a pipeline. After initialization the pipeline can be used. */
Brian Salomone7d30482017-03-29 12:09:15 -0400113 void init(const InitArgs&);
Brian Salomonb5cb6832017-02-24 11:01:15 -0500114
115 /** True if the pipeline has been initialized. */
116 bool isInitialized() const { return SkToBool(fRenderTarget.get()); }
117
bsalomoncb02b382015-08-12 11:14:50 -0700118 /// @}
119
120 ///////////////////////////////////////////////////////////////////////////
121 /// @name Comparisons
122
123 /**
joshualitt2fe79232015-08-05 12:02:27 -0700124 * Returns true if these pipelines are equivalent. Coord transforms may be applied either on
125 * the GPU or the CPU. When we apply them on the CPU then the matrices need not agree in order
126 * to combine draws. Therefore we take a param that indicates whether coord transforms should be
127 * compared."
joshualitt9b989322014-12-15 14:16:27 -0800128 */
bsalomon7312ff82016-09-12 08:55:38 -0700129 static bool AreEqual(const GrPipeline& a, const GrPipeline& b);
bsalomoncb02b382015-08-12 11:14:50 -0700130
131 /**
Brian Salomon09d994e2016-12-21 11:14:46 -0500132 * Allows a GrOp subclass to determine whether two GrOp instances can combine. This is a
133 * stricter test than isEqual because it also considers blend barriers when the two ops'
134 * bounds overlap
bsalomoncb02b382015-08-12 11:14:50 -0700135 */
136 static bool CanCombine(const GrPipeline& a, const SkRect& aBounds,
137 const GrPipeline& b, const SkRect& bBounds,
bsalomon7312ff82016-09-12 08:55:38 -0700138 const GrCaps& caps) {
139 if (!AreEqual(a, b)) {
bsalomoncb02b382015-08-12 11:14:50 -0700140 return false;
141 }
142 if (a.xferBarrierType(caps)) {
Brian Salomona4677b52017-05-04 12:39:56 -0400143 return !GrRectsTouchOrOverlap(aBounds, bBounds);
bsalomoncb02b382015-08-12 11:14:50 -0700144 }
145 return true;
146 }
egdaniel89af44a2014-09-26 06:15:04 -0700147
148 /// @}
149
150 ///////////////////////////////////////////////////////////////////////////
bsalomon6be6f7c2015-02-26 13:05:21 -0800151 /// @name GrFragmentProcessors
egdaniel89af44a2014-09-26 06:15:04 -0700152
Robert Phillipsd261e102017-06-23 12:37:20 -0400153 // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline
154 void addDependenciesTo(GrOpList* recipient, const GrCaps&) const;
bsalomon6be6f7c2015-02-26 13:05:21 -0800155
bsalomonac856c92015-08-27 06:30:17 -0700156 int numColorFragmentProcessors() const { return fNumColorProcessors; }
157 int numCoverageFragmentProcessors() const {
158 return fFragmentProcessors.count() - fNumColorProcessors;
159 }
160 int numFragmentProcessors() const { return fFragmentProcessors.count(); }
egdaniel89af44a2014-09-26 06:15:04 -0700161
bsalomon2047b782015-12-21 13:12:54 -0800162 const GrXferProcessor& getXferProcessor() const {
Brian Salomond61c9d92017-04-10 10:54:25 -0400163 if (fXferProcessor) {
bsalomon2047b782015-12-21 13:12:54 -0800164 return *fXferProcessor.get();
165 } else {
166 // A null xp member means the common src-over case. GrXferProcessor's ref'ing
167 // mechanism is not thread safe so we do not hold a ref on this global.
168 return GrPorterDuffXPFactory::SimpleSrcOverXP();
169 }
170 }
egdaniel378092f2014-12-03 10:40:13 -0800171
Brian Salomon18dfa982017-04-03 16:57:43 -0400172 /**
173 * If the GrXferProcessor uses a texture to access the dst color, then this returns that
174 * texture and the offset to the dst contents within that texture.
175 */
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400176 GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const {
Brian Salomon18dfa982017-04-03 16:57:43 -0400177 if (offset) {
178 *offset = fDstTextureOffset;
179 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400180 return fDstTextureProxy.get();
181 }
182
183 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
184 if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) {
185 return dstProxy->priv().peekTexture();
186 }
187
188 return nullptr;
Brian Salomon18dfa982017-04-03 16:57:43 -0400189 }
190
bsalomonac856c92015-08-27 06:30:17 -0700191 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
192 SkASSERT(idx < this->numColorFragmentProcessors());
193 return *fFragmentProcessors[idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700194 }
bsalomonac856c92015-08-27 06:30:17 -0700195
196 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
197 SkASSERT(idx < this->numCoverageFragmentProcessors());
198 return *fFragmentProcessors[fNumColorProcessors + idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700199 }
bsalomonac856c92015-08-27 06:30:17 -0700200
201 const GrFragmentProcessor& getFragmentProcessor(int idx) const {
202 return *fFragmentProcessors[idx].get();
bsalomonae59b772014-11-19 08:23:49 -0800203 }
egdaniel89af44a2014-09-26 06:15:04 -0700204
205 /// @}
206
egdaniel89af44a2014-09-26 06:15:04 -0700207 /**
208 * Retrieves the currently set render-target.
209 *
210 * @return The currently set render target.
211 */
bsalomon37dd3312014-11-03 08:47:23 -0800212 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
egdaniel89af44a2014-09-26 06:15:04 -0700213
csmartdaltonc633abb2016-11-01 08:55:55 -0700214 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
egdaniel89af44a2014-09-26 06:15:04 -0700215
bsalomon3e791242014-12-17 13:43:13 -0800216 const GrScissorState& getScissorState() const { return fScissorState; }
joshualitt54e0c122014-11-19 09:38:51 -0800217
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700218 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
csmartdalton28341fa2016-08-17 10:00:21 -0700219
Brian Salomon189098e72017-01-19 09:55:19 -0500220 bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
221 bool snapVerticesToPixelCenters() const {
222 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
223 }
brianosman64d094d2016-03-25 06:01:59 -0700224 bool getDisableOutputConversionToSRGB() const {
225 return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
226 }
brianosman898235c2016-04-06 07:38:23 -0700227 bool getAllowSRGBInputs() const {
228 return SkToBool(fFlags & kAllowSRGBInputs_Flag);
229 }
cdalton193d9cf2016-05-12 11:52:02 -0700230 bool hasStencilClip() const {
231 return SkToBool(fFlags & kHasStencilClip_Flag);
232 }
csmartdaltonc633abb2016-11-01 08:55:55 -0700233 bool isStencilEnabled() const {
234 return SkToBool(fFlags & kStencilEnabled_Flag);
235 }
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400236 bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); }
bsalomonae59b772014-11-19 08:23:49 -0800237
Robert Phillipsc9c06d42017-06-12 10:58:31 -0400238 GrXferBarrierType xferBarrierType(const GrCaps& caps) const;
bsalomoncb02b382015-08-12 11:14:50 -0700239
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400240 static SkString DumpFlags(uint32_t flags) {
241 if (flags) {
242 SkString result;
243 if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) {
244 result.append("Snap vertices to pixel center.\n");
245 }
246 if (flags & GrPipeline::kHWAntialias_Flag) {
247 result.append("HW Antialiasing enabled.\n");
248 }
249 if (flags & GrPipeline::kDisableOutputConversionToSRGB_Flag) {
250 result.append("Disable output conversion to sRGB.\n");
251 }
252 if (flags & GrPipeline::kAllowSRGBInputs_Flag) {
253 result.append("Allow sRGB Inputs.\n");
254 }
255 return result;
256 }
257 return SkString("No pipeline flags\n");
258 }
259
bsalomonae59b772014-11-19 08:23:49 -0800260private:
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400261 void markAsBad() { fFlags |= kIsBad_Flag; }
262
Brian Salomonf87e2b92017-01-19 11:31:50 -0500263 /** This is a continuation of the public "Flags" enum. */
Brian Salomon189098e72017-01-19 09:55:19 -0500264 enum PrivateFlags {
Brian Salomone23bffd2017-06-02 11:01:10 -0400265 kHasStencilClip_Flag = 0x10,
266 kStencilEnabled_Flag = 0x20,
267 kIsBad_Flag = 0x40,
bsalomon04ddf892014-11-19 12:36:22 -0800268 };
269
Brian Salomon18dfa982017-04-03 16:57:43 -0400270 using RenderTarget = GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>;
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400271 using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>;
Brian Salomon18dfa982017-04-03 16:57:43 -0400272 using PendingFragmentProcessor = GrPendingProgramElement<const GrFragmentProcessor>;
273 using FragmentProcessorArray = SkAutoSTArray<8, PendingFragmentProcessor>;
Brian Salomon18dfa982017-04-03 16:57:43 -0400274
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400275 DstTextureProxy fDstTextureProxy;
Brian Salomon18dfa982017-04-03 16:57:43 -0400276 SkIPoint fDstTextureOffset;
277 RenderTarget fRenderTarget;
278 GrScissorState fScissorState;
279 GrWindowRectsState fWindowRectsState;
280 const GrUserStencilSettings* fUserStencilSettings;
Brian Salomon18dfa982017-04-03 16:57:43 -0400281 uint16_t fFlags;
Brian Salomond61c9d92017-04-10 10:54:25 -0400282 sk_sp<const GrXferProcessor> fXferProcessor;
Brian Salomon18dfa982017-04-03 16:57:43 -0400283 FragmentProcessorArray fFragmentProcessors;
egdanield9aa2182014-10-09 13:47:05 -0700284
bsalomonac856c92015-08-27 06:30:17 -0700285 // This value is also the index in fFragmentProcessors where coverage processors begin.
Brian Salomon18dfa982017-04-03 16:57:43 -0400286 int fNumColorProcessors;
egdaniel89af44a2014-09-26 06:15:04 -0700287
egdaniel89af44a2014-09-26 06:15:04 -0700288 typedef SkRefCnt INHERITED;
egdaniel3658f382014-09-15 07:01:59 -0700289};
290
291#endif