blob: 67e137c82a3b94c42c7176672da1c3037bf88388 [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"
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;
joshualitt79f8fae2014-10-28 17:59:26 -070029class GrDeviceCoordTexture;
Brian Salomon25a88092016-12-01 09:36:50 -050030class GrOp;
egdaniel8dd688b2015-01-22 10:16:09 -080031class GrPipelineBuilder;
Brian Salomon25a88092016-12-01 09:36:50 -050032class GrRenderTargetContext;
egdaniel3658f382014-09-15 07:01:59 -070033
Brian Salomon92aee3d2016-12-21 09:20:25 -050034/**
egdaniel8dd688b2015-01-22 10:16:09 -080035 * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
36 * class, and contains all data needed to set the state for a gpu draw.
egdaniel3658f382014-09-15 07:01:59 -070037 */
cdalton4833f392016-02-02 22:46:16 -080038class GrPipeline : public GrNonAtomicRef<GrPipeline> {
egdaniel3658f382014-09-15 07:01:59 -070039public:
bsalomoncb02b382015-08-12 11:14:50 -070040 ///////////////////////////////////////////////////////////////////////////
41 /// @name Creation
42
Brian Salomon189098e72017-01-19 09:55:19 -050043 enum Flags {
44 /**
45 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
46 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
47 * the 3D API.
48 */
49 kHWAntialias_Flag = 0x1,
Brian Salomon189098e72017-01-19 09:55:19 -050050 /**
51 * Modifies the vertex shader so that vertices will be positioned at pixel centers.
52 */
53 kSnapVerticesToPixelCenters_Flag = 0x2,
Brian Salomon611572c2017-04-28 08:57:12 -040054 /** Disables conversion to sRGB from linear when writing to a sRGB destination. */
55 kDisableOutputConversionToSRGB_Flag = 0x4,
56 /** Allows conversion from sRGB to linear when reading from processor's sRGB texture. */
57 kAllowSRGBInputs_Flag = 0x8,
Brian Salomon189098e72017-01-19 09:55:19 -050058 };
59
Brian Salomon611572c2017-04-28 08:57:12 -040060 static uint32_t SRGBFlagsFromPaint(const GrPaint& paint) {
61 uint32_t flags = 0;
62 if (paint.getAllowSRGBInputs()) {
63 flags |= kAllowSRGBInputs_Flag;
64 }
65 if (paint.getDisableOutputConversionToSRGB()) {
66 flags |= kDisableOutputConversionToSRGB_Flag;
67 }
68 return flags;
69 }
70
Brian Salomonb5cb6832017-02-24 11:01:15 -050071 struct InitArgs {
Brian Salomon189098e72017-01-19 09:55:19 -050072 uint32_t fFlags = 0;
Brian Salomon48d1b4c2017-04-08 07:38:53 -040073 const GrProcessorSet* fProcessors = nullptr; // Must be finalized
Brian Salomon189098e72017-01-19 09:55:19 -050074 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
Brian Salomonb5cb6832017-02-24 11:01:15 -050075 const GrAppliedClip* fAppliedClip = nullptr;
Brian Salomonb16e8ac2017-02-22 11:52:36 -050076 GrRenderTarget* fRenderTarget = nullptr;
Brian Salomon189098e72017-01-19 09:55:19 -050077 const GrCaps* fCaps = nullptr;
Robert Phillipsc3757042017-05-17 13:00:14 +000078 GrXferProcessor::DstTexture fDstTexture;
bsalomona387a112015-08-11 14:47:42 -070079 };
80
Brian Salomonb5cb6832017-02-24 11:01:15 -050081 /**
82 * A Default constructed pipeline is unusable until init() is called.
83 **/
84 GrPipeline() = default;
egdanielb109ac22014-10-07 06:45:44 -070085
csmartdalton119fb2b2017-02-08 14:41:05 -050086 /**
87 * Creates a simple pipeline with default settings and no processors. The provided blend mode
Brian Salomonb5cb6832017-02-24 11:01:15 -050088 * must be "Porter Duff" (<= kLastCoeffMode). This pipeline is initialized without requiring
89 * a call to init().
csmartdalton119fb2b2017-02-08 14:41:05 -050090 **/
91 GrPipeline(GrRenderTarget*, SkBlendMode);
92
Brian Salomon6d4b65e2017-05-03 17:06:09 -040093 GrPipeline(const InitArgs& args) { this->init(args); }
94
Brian Salomonb5cb6832017-02-24 11:01:15 -050095 /** (Re)initializes a pipeline. After initialization the pipeline can be used. */
Brian Salomone7d30482017-03-29 12:09:15 -040096 void init(const InitArgs&);
Brian Salomonb5cb6832017-02-24 11:01:15 -050097
98 /** True if the pipeline has been initialized. */
99 bool isInitialized() const { return SkToBool(fRenderTarget.get()); }
100
bsalomoncb02b382015-08-12 11:14:50 -0700101 /// @}
102
103 ///////////////////////////////////////////////////////////////////////////
104 /// @name Comparisons
105
106 /**
joshualitt2fe79232015-08-05 12:02:27 -0700107 * Returns true if these pipelines are equivalent. Coord transforms may be applied either on
108 * the GPU or the CPU. When we apply them on the CPU then the matrices need not agree in order
109 * to combine draws. Therefore we take a param that indicates whether coord transforms should be
110 * compared."
joshualitt9b989322014-12-15 14:16:27 -0800111 */
bsalomon7312ff82016-09-12 08:55:38 -0700112 static bool AreEqual(const GrPipeline& a, const GrPipeline& b);
bsalomoncb02b382015-08-12 11:14:50 -0700113
114 /**
Brian Salomon09d994e2016-12-21 11:14:46 -0500115 * Allows a GrOp subclass to determine whether two GrOp instances can combine. This is a
116 * stricter test than isEqual because it also considers blend barriers when the two ops'
117 * bounds overlap
bsalomoncb02b382015-08-12 11:14:50 -0700118 */
119 static bool CanCombine(const GrPipeline& a, const SkRect& aBounds,
120 const GrPipeline& b, const SkRect& bBounds,
bsalomon7312ff82016-09-12 08:55:38 -0700121 const GrCaps& caps) {
122 if (!AreEqual(a, b)) {
bsalomoncb02b382015-08-12 11:14:50 -0700123 return false;
124 }
125 if (a.xferBarrierType(caps)) {
Brian Salomona4677b52017-05-04 12:39:56 -0400126 return !GrRectsTouchOrOverlap(aBounds, bBounds);
bsalomoncb02b382015-08-12 11:14:50 -0700127 }
128 return true;
129 }
egdaniel89af44a2014-09-26 06:15:04 -0700130
131 /// @}
132
133 ///////////////////////////////////////////////////////////////////////////
bsalomon6be6f7c2015-02-26 13:05:21 -0800134 /// @name GrFragmentProcessors
egdaniel89af44a2014-09-26 06:15:04 -0700135
Robert Phillipsf2361d22016-10-25 14:20:06 -0400136 // Make the renderTarget's GrOpList (if it exists) be dependent on any
137 // GrOpLists in this pipeline
Robert Phillipsc589b0b2017-04-17 07:53:07 -0400138 void addDependenciesTo(GrRenderTargetProxy*) const;
bsalomon6be6f7c2015-02-26 13:05:21 -0800139
bsalomonac856c92015-08-27 06:30:17 -0700140 int numColorFragmentProcessors() const { return fNumColorProcessors; }
141 int numCoverageFragmentProcessors() const {
142 return fFragmentProcessors.count() - fNumColorProcessors;
143 }
144 int numFragmentProcessors() const { return fFragmentProcessors.count(); }
egdaniel89af44a2014-09-26 06:15:04 -0700145
bsalomon2047b782015-12-21 13:12:54 -0800146 const GrXferProcessor& getXferProcessor() const {
Brian Salomond61c9d92017-04-10 10:54:25 -0400147 if (fXferProcessor) {
bsalomon2047b782015-12-21 13:12:54 -0800148 return *fXferProcessor.get();
149 } else {
150 // A null xp member means the common src-over case. GrXferProcessor's ref'ing
151 // mechanism is not thread safe so we do not hold a ref on this global.
152 return GrPorterDuffXPFactory::SimpleSrcOverXP();
153 }
154 }
egdaniel378092f2014-12-03 10:40:13 -0800155
Brian Salomon18dfa982017-04-03 16:57:43 -0400156 /**
157 * If the GrXferProcessor uses a texture to access the dst color, then this returns that
158 * texture and the offset to the dst contents within that texture.
159 */
Robert Phillipsc3757042017-05-17 13:00:14 +0000160 GrTexture* dstTexture(SkIPoint* offset = nullptr) const {
Brian Salomon18dfa982017-04-03 16:57:43 -0400161 if (offset) {
162 *offset = fDstTextureOffset;
163 }
Robert Phillipsc3757042017-05-17 13:00:14 +0000164 return fDstTexture.get();
Brian Salomon18dfa982017-04-03 16:57:43 -0400165 }
166
bsalomonac856c92015-08-27 06:30:17 -0700167 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
168 SkASSERT(idx < this->numColorFragmentProcessors());
169 return *fFragmentProcessors[idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700170 }
bsalomonac856c92015-08-27 06:30:17 -0700171
172 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
173 SkASSERT(idx < this->numCoverageFragmentProcessors());
174 return *fFragmentProcessors[fNumColorProcessors + idx].get();
egdanield9aa2182014-10-09 13:47:05 -0700175 }
bsalomonac856c92015-08-27 06:30:17 -0700176
177 const GrFragmentProcessor& getFragmentProcessor(int idx) const {
178 return *fFragmentProcessors[idx].get();
bsalomonae59b772014-11-19 08:23:49 -0800179 }
egdaniel89af44a2014-09-26 06:15:04 -0700180
181 /// @}
182
egdaniel89af44a2014-09-26 06:15:04 -0700183 /**
184 * Retrieves the currently set render-target.
185 *
186 * @return The currently set render target.
187 */
bsalomon37dd3312014-11-03 08:47:23 -0800188 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
egdaniel89af44a2014-09-26 06:15:04 -0700189
csmartdaltonc633abb2016-11-01 08:55:55 -0700190 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
egdaniel89af44a2014-09-26 06:15:04 -0700191
bsalomon3e791242014-12-17 13:43:13 -0800192 const GrScissorState& getScissorState() const { return fScissorState; }
joshualitt54e0c122014-11-19 09:38:51 -0800193
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700194 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
csmartdalton28341fa2016-08-17 10:00:21 -0700195
Brian Salomon189098e72017-01-19 09:55:19 -0500196 bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
197 bool snapVerticesToPixelCenters() const {
198 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
199 }
brianosman64d094d2016-03-25 06:01:59 -0700200 bool getDisableOutputConversionToSRGB() const {
201 return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
202 }
brianosman898235c2016-04-06 07:38:23 -0700203 bool getAllowSRGBInputs() const {
204 return SkToBool(fFlags & kAllowSRGBInputs_Flag);
205 }
dvonbeck9b03e7b2016-08-01 11:01:56 -0700206 bool usesDistanceVectorField() const {
207 return SkToBool(fFlags & kUsesDistanceVectorField_Flag);
208 }
cdalton193d9cf2016-05-12 11:52:02 -0700209 bool hasStencilClip() const {
210 return SkToBool(fFlags & kHasStencilClip_Flag);
211 }
csmartdaltonc633abb2016-11-01 08:55:55 -0700212 bool isStencilEnabled() const {
213 return SkToBool(fFlags & kStencilEnabled_Flag);
214 }
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400215 bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); }
bsalomonae59b772014-11-19 08:23:49 -0800216
bsalomoncb02b382015-08-12 11:14:50 -0700217 GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
Robert Phillipsc3757042017-05-17 13:00:14 +0000218 if (fDstTexture.get() && fDstTexture.get() == fRenderTarget.get()->asTexture()) {
Brian Salomon18dfa982017-04-03 16:57:43 -0400219 return kTexture_GrXferBarrierType;
220 }
221 return this->getXferProcessor().xferBarrierType(caps);
bsalomoncb02b382015-08-12 11:14:50 -0700222 }
223
bsalomonae59b772014-11-19 08:23:49 -0800224private:
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400225 void markAsBad() { fFlags |= kIsBad_Flag; }
226
Brian Salomonf87e2b92017-01-19 11:31:50 -0500227 /** This is a continuation of the public "Flags" enum. */
Brian Salomon189098e72017-01-19 09:55:19 -0500228 enum PrivateFlags {
229 kUsesDistanceVectorField_Flag = 0x10,
230 kHasStencilClip_Flag = 0x20,
231 kStencilEnabled_Flag = 0x40,
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400232 kIsBad_Flag = 0x80,
bsalomon04ddf892014-11-19 12:36:22 -0800233 };
234
Brian Salomon18dfa982017-04-03 16:57:43 -0400235 using RenderTarget = GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>;
Robert Phillipsc3757042017-05-17 13:00:14 +0000236 using DstTexture = GrPendingIOResource<GrTexture, kRead_GrIOType>;
Brian Salomon18dfa982017-04-03 16:57:43 -0400237 using PendingFragmentProcessor = GrPendingProgramElement<const GrFragmentProcessor>;
238 using FragmentProcessorArray = SkAutoSTArray<8, PendingFragmentProcessor>;
Brian Salomon18dfa982017-04-03 16:57:43 -0400239
Robert Phillipsc3757042017-05-17 13:00:14 +0000240 DstTexture fDstTexture;
Brian Salomon18dfa982017-04-03 16:57:43 -0400241 SkIPoint fDstTextureOffset;
242 RenderTarget fRenderTarget;
243 GrScissorState fScissorState;
244 GrWindowRectsState fWindowRectsState;
245 const GrUserStencilSettings* fUserStencilSettings;
Brian Salomon18dfa982017-04-03 16:57:43 -0400246 uint16_t fFlags;
Brian Salomond61c9d92017-04-10 10:54:25 -0400247 sk_sp<const GrXferProcessor> fXferProcessor;
Brian Salomon18dfa982017-04-03 16:57:43 -0400248 FragmentProcessorArray fFragmentProcessors;
egdanield9aa2182014-10-09 13:47:05 -0700249
bsalomonac856c92015-08-27 06:30:17 -0700250 // This value is also the index in fFragmentProcessors where coverage processors begin.
Brian Salomon18dfa982017-04-03 16:57:43 -0400251 int fNumColorProcessors;
egdaniel89af44a2014-09-26 06:15:04 -0700252
egdaniel89af44a2014-09-26 06:15:04 -0700253 typedef SkRefCnt INHERITED;
egdaniel3658f382014-09-15 07:01:59 -0700254};
255
256#endif