blob: 60fcea86c8a233ef37a7c68f2f3993403583d125 [file] [log] [blame]
tomhudson@google.com93813632011-10-27 20:21:16 +00001/*
egdaniel8dd688b2015-01-22 10:16:09 -08002 * Copyright 2015 Google Inc.
tomhudson@google.com93813632011-10-27 20:21:16 +00003 *
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 GrPipelineBuilder_DEFINED
9#define GrPipelineBuilder_DEFINED
tomhudson@google.com93813632011-10-27 20:21:16 +000010
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +000011#include "GrBlend.h"
bsalomoneb1cb5c2015-05-22 08:01:09 -070012#include "GrCaps.h"
joshualitt44701df2015-02-23 14:44:57 -080013#include "GrClip.h"
bsalomonf96ba022014-09-17 08:05:40 -070014#include "GrGpuResourceRef.h"
bsalomonae59b772014-11-19 08:23:49 -080015#include "GrFragmentStage.h"
egdanielb6cbc382014-11-13 11:00:34 -080016#include "GrProcOptInfo.h"
joshualitt2cdec312015-07-09 07:31:31 -070017#include "GrProcessorDataManager.h"
egdaniel89af44a2014-09-26 06:15:04 -070018#include "GrRenderTarget.h"
19#include "GrStencil.h"
egdaniel95131432014-12-09 11:15:43 -080020#include "GrXferProcessor.h"
egdaniel89af44a2014-09-26 06:15:04 -070021#include "SkMatrix.h"
egdaniel87509242014-12-17 13:37:13 -080022#include "effects/GrCoverageSetOpXP.h"
egdaniel080e6732014-12-22 07:35:52 -080023#include "effects/GrDisableColorXP.h"
egdaniel95131432014-12-09 11:15:43 -080024#include "effects/GrPorterDuffXferProcessor.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000025#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000026
joshualitt5bf99f12015-03-13 11:47:42 -070027class GrBatch;
bsalomon4b91f762015-05-19 09:29:46 -070028class GrCaps;
egdaniel89af44a2014-09-26 06:15:04 -070029class GrPaint;
30class GrTexture;
egdaniel170f90b2014-09-16 12:54:40 -070031
egdaniel8dd688b2015-01-22 10:16:09 -080032class GrPipelineBuilder {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000033public:
egdaniel8dd688b2015-01-22 10:16:09 -080034 GrPipelineBuilder();
35
36 GrPipelineBuilder(const GrPipelineBuilder& pipelineBuilder) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000037 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
egdaniel8dd688b2015-01-22 10:16:09 -080038 *this = pipelineBuilder;
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000039 }
40
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000041 /**
joshualitt7b670db2015-07-09 13:25:02 -070042 * Initializes the GrPipelineBuilder based on a GrPaint, render target, and clip. Note
egdaniel8dd688b2015-01-22 10:16:09 -080043 * that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have
44 * no GrPaint equivalents are set to default values with the exception of vertex attribute state
45 * which is unmodified by this function and clipping which will be enabled.
bsalomon@google.comaf84e742012-10-05 13:23:24 +000046 */
joshualitt7b670db2015-07-09 13:25:02 -070047 GrPipelineBuilder(const GrPaint&, GrRenderTarget*, const GrClip&);
48
49 virtual ~GrPipelineBuilder();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000050
bsalomon@google.com2401ae82012-01-17 21:03:05 +000051 ///////////////////////////////////////////////////////////////////////////
bsalomon6be6f7c2015-02-26 13:05:21 -080052 /// @name Fragment Processors
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000053 ///
bsalomon6be6f7c2015-02-26 13:05:21 -080054 /// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage.
55 /// There are two chains of FPs, one for color and one for coverage. The first FP in each
56 /// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output
57 /// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs
58 /// feed their output to the GrXferProcessor which controls blending.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000059 ////
60
bsalomon6be6f7c2015-02-26 13:05:21 -080061 int numColorFragmentStages() const { return fColorStages.count(); }
62 int numCoverageFragmentStages() const { return fCoverageStages.count(); }
63 int numFragmentStages() const { return this->numColorFragmentStages() +
64 this->numCoverageFragmentStages(); }
egdaniel378092f2014-12-03 10:40:13 -080065
bsalomon6be6f7c2015-02-26 13:05:21 -080066 const GrFragmentStage& getColorFragmentStage(int idx) const { return fColorStages[idx]; }
67 const GrFragmentStage& getCoverageFragmentStage(int idx) const { return fCoverageStages[idx]; }
egdaniel080e6732014-12-22 07:35:52 -080068
joshualittb0a8a372014-09-23 09:50:21 -070069 const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -070070 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -070071 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -080072 fColorProcInfoValid = false;
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000073 return effect;
74 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +000075
joshualittb0a8a372014-09-23 09:50:21 -070076 const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -070077 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -070078 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -080079 fCoverageProcInfoValid = false;
bsalomon@google.comadc65362013-01-28 14:26:09 +000080 return effect;
81 }
82
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000083 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +000084 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +000085 */
joshualittb0a8a372014-09-23 09:50:21 -070086 void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
joshualitt5b4f05f2015-07-10 07:26:21 -070087 this->addColorProcessor(GrSimpleTextureEffect::Create(fProcDataManager, texture,
joshualitt5f10b5c2015-07-09 10:24:35 -070088 matrix))->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +000089 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000090
joshualittb0a8a372014-09-23 09:50:21 -070091 void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
joshualitt5b4f05f2015-07-10 07:26:21 -070092 this->addCoverageProcessor(GrSimpleTextureEffect::Create(fProcDataManager, texture,
joshualitt5f10b5c2015-07-09 10:24:35 -070093 matrix))->unref();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000094 }
95
joshualittb0a8a372014-09-23 09:50:21 -070096 void addColorTextureProcessor(GrTexture* texture,
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000097 const SkMatrix& matrix,
98 const GrTextureParams& params) {
joshualitt5b4f05f2015-07-10 07:26:21 -070099 this->addColorProcessor(GrSimpleTextureEffect::Create(fProcDataManager, texture, matrix,
joshualitt5f10b5c2015-07-09 10:24:35 -0700100 params))->unref();
joshualittb0a8a372014-09-23 09:50:21 -0700101 }
102
103 void addCoverageTextureProcessor(GrTexture* texture,
104 const SkMatrix& matrix,
105 const GrTextureParams& params) {
joshualitt5b4f05f2015-07-10 07:26:21 -0700106 this->addCoverageProcessor(GrSimpleTextureEffect::Create(fProcDataManager, texture, matrix,
joshualitt5f10b5c2015-07-09 10:24:35 -0700107 params))->unref();
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000108 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000109
robertphillips@google.com972265d2012-06-13 18:49:30 +0000110 /**
bsalomon6be6f7c2015-02-26 13:05:21 -0800111 * When this object is destroyed it will remove any color/coverage FPs from the pipeline builder
112 * that were added after its constructor.
joshualitt5e6ba212015-07-13 07:35:05 -0700113 * This class can transiently modify its "const" GrPipelineBuilder object but will restore it
114 * when done - so it is notionally "const" correct.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000115 */
bsalomon6be6f7c2015-02-26 13:05:21 -0800116 class AutoRestoreFragmentProcessors : public ::SkNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000117 public:
bsalomon6be6f7c2015-02-26 13:05:21 -0800118 AutoRestoreFragmentProcessors()
egdaniel8dd688b2015-01-22 10:16:09 -0800119 : fPipelineBuilder(NULL)
bsalomon9b536522014-09-05 09:18:51 -0700120 , fColorEffectCnt(0)
121 , fCoverageEffectCnt(0) {}
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000122
bsalomon6be6f7c2015-02-26 13:05:21 -0800123 AutoRestoreFragmentProcessors(GrPipelineBuilder* ds)
egdaniel8dd688b2015-01-22 10:16:09 -0800124 : fPipelineBuilder(NULL)
bsalomon9b536522014-09-05 09:18:51 -0700125 , fColorEffectCnt(0)
126 , fCoverageEffectCnt(0) {
skia.committer@gmail.com5c493d52013-06-14 07:00:49 +0000127 this->set(ds);
robertphillips@google.comf09b87d2013-06-13 20:06:44 +0000128 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000129
bsalomon6be6f7c2015-02-26 13:05:21 -0800130 ~AutoRestoreFragmentProcessors() { this->set(NULL); }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000131
joshualitt5e6ba212015-07-13 07:35:05 -0700132 void set(const GrPipelineBuilder* ds);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000133
egdaniel8dd688b2015-01-22 10:16:09 -0800134 bool isSet() const { return SkToBool(fPipelineBuilder); }
bsalomon8af05232014-06-03 06:34:58 -0700135
joshualitt5e6ba212015-07-13 07:35:05 -0700136 const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* processor) {
137 SkASSERT(this->isSet());
138 return fPipelineBuilder->addCoverageProcessor(processor);
139 }
140
robertphillips@google.com972265d2012-06-13 18:49:30 +0000141 private:
joshualitt5e6ba212015-07-13 07:35:05 -0700142 // notionally const (as marginalia)
egdaniel8dd688b2015-01-22 10:16:09 -0800143 GrPipelineBuilder* fPipelineBuilder;
joshualitt5e6ba212015-07-13 07:35:05 -0700144 int fColorEffectCnt;
145 int fCoverageEffectCnt;
robertphillips@google.com972265d2012-06-13 18:49:30 +0000146 };
147
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000148 /// @}
149
150 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000151 /// @name Blending
152 ////
153
egdaniel89af44a2014-09-26 06:15:04 -0700154 /**
cdalton1fa45722015-06-02 10:43:39 -0700155 * Returns true if this pipeline's color output will be affected by the existing render target
156 * destination pixel values (meaning we need to be careful with overlapping draws). Note that we
157 * can conflate coverage and color, so the destination color may still bleed into pixels that
158 * have partial coverage, even if this function returns false.
bsalomon6be6f7c2015-02-26 13:05:21 -0800159 */
cdalton1fa45722015-06-02 10:43:39 -0700160 bool willColorBlendWithDst(const GrPrimitiveProcessor*) const;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000161
bsalomon6be6f7c2015-02-26 13:05:21 -0800162 /**
163 * Installs a GrXPFactory. This object controls how src color, fractional pixel coverage,
164 * and the dst color are blended.
165 */
166 const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
167 fXPFactory.reset(SkRef(xpFactory));
168 return xpFactory;
169 }
170
171 /**
172 * Sets a GrXPFactory that will ignore src color and perform a set operation between the draws
173 * output coverage and the destination. This is useful to render coverage masks as CSG.
174 */
175 void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false) {
176 fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage));
177 }
178
179 /**
180 * Sets a GrXPFactory that disables color writes to the destination. This is useful when
181 * rendering to the stencil buffer.
182 */
183 void setDisableColorXPFactory() {
184 fXPFactory.reset(GrDisableColorXPFactory::Create());
185 }
186
187 const GrXPFactory* getXPFactory() const {
188 if (!fXPFactory) {
189 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
190 }
191 return fXPFactory.get();
192 }
193
194 /**
bsalomon6a44c6a2015-05-26 09:49:05 -0700195 * Checks whether the xp will need destination in a texture to correctly blend.
bsalomon6be6f7c2015-02-26 13:05:21 -0800196 */
bsalomon6a44c6a2015-05-26 09:49:05 -0700197 bool willXPNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI,
198 const GrProcOptInfo& coveragePOI) const;
joshualittd27f73e2014-12-29 07:43:36 -0800199
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000200 /// @}
201
bsalomon6be6f7c2015-02-26 13:05:21 -0800202
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000203 ///////////////////////////////////////////////////////////////////////////
204 /// @name Render Target
205 ////
206
207 /**
egdaniel89af44a2014-09-26 06:15:04 -0700208 * 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
214 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000215 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000216 *
217 * @param target The render target to set.
218 */
bsalomonae59b772014-11-19 08:23:49 -0800219 void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000220
cdalton86ae0a92015-06-08 15:11:04 -0700221 /**
222 * Returns whether the rasterizer and stencil test (if any) will run at a higher sample rate
223 * than the color buffer. In is scenario, the higher sample rate is resolved during blending.
224 */
225 bool hasMixedSamples() const {
vbuzinovdded6962015-06-12 08:59:45 -0700226 return this->isHWAntialias() && !fRenderTarget->isUnifiedMultisampled();
cdalton86ae0a92015-06-08 15:11:04 -0700227 }
228
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000229 /// @}
230
231 ///////////////////////////////////////////////////////////////////////////
232 /// @name Stencil
233 ////
234
egdaniel89af44a2014-09-26 06:15:04 -0700235 const GrStencilSettings& getStencil() const { return fStencilSettings; }
236
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000237 /**
238 * Sets the stencil settings to use for the next draw.
239 * Changing the clip has the side-effect of possibly zeroing
240 * out the client settable stencil bits. So multipass algorithms
241 * using stencil should not change the clip between passes.
242 * @param settings the stencil settings to use.
243 */
bsalomon04ddf892014-11-19 12:36:22 -0800244 void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000245
246 /**
247 * Shortcut to disable stencil testing and ops.
248 */
bsalomon04ddf892014-11-19 12:36:22 -0800249 void disableStencil() { fStencilSettings.setDisabled(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000250
bsalomon2ed5ef82014-07-07 08:44:05 -0700251 GrStencilSettings* stencil() { return &fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000252
bsalomon6be6f7c2015-02-26 13:05:21 -0800253 /**
254 * AutoRestoreStencil
255 *
256 * This simple struct saves and restores the stencil settings
joshualitt5e6ba212015-07-13 07:35:05 -0700257 * This class can transiently modify its "const" GrPipelineBuilder object but will restore it
258 * when done - so it is notionally "const" correct.
bsalomon6be6f7c2015-02-26 13:05:21 -0800259 */
260 class AutoRestoreStencil : public ::SkNoncopyable {
261 public:
262 AutoRestoreStencil() : fPipelineBuilder(NULL) {}
263
joshualitt5e6ba212015-07-13 07:35:05 -0700264 AutoRestoreStencil(const GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); }
bsalomon6be6f7c2015-02-26 13:05:21 -0800265
266 ~AutoRestoreStencil() { this->set(NULL); }
267
joshualitt5e6ba212015-07-13 07:35:05 -0700268 void set(const GrPipelineBuilder* ds) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800269 if (fPipelineBuilder) {
270 fPipelineBuilder->setStencil(fStencilSettings);
271 }
joshualitt5e6ba212015-07-13 07:35:05 -0700272 fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds);
bsalomon6be6f7c2015-02-26 13:05:21 -0800273 if (ds) {
274 fStencilSettings = ds->getStencil();
275 }
276 }
277
278 bool isSet() const { return SkToBool(fPipelineBuilder); }
279
joshualitt5e6ba212015-07-13 07:35:05 -0700280 void setStencil(const GrStencilSettings& settings) {
281 SkASSERT(this->isSet());
282 fPipelineBuilder->setStencil(settings);
283 }
284
bsalomon6be6f7c2015-02-26 13:05:21 -0800285 private:
joshualitt5e6ba212015-07-13 07:35:05 -0700286 // notionally const (as marginalia)
bsalomon6be6f7c2015-02-26 13:05:21 -0800287 GrPipelineBuilder* fPipelineBuilder;
288 GrStencilSettings fStencilSettings;
289 };
290
291
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000292 /// @}
293
294 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000295 /// @name State Flags
296 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000297
egdaniel89af44a2014-09-26 06:15:04 -0700298 /**
299 * Flags that affect rendering. Controlled using enable/disableState(). All
300 * default to disabled.
301 */
bsalomond79c5492015-04-27 10:07:04 -0700302 enum Flags {
egdaniel89af44a2014-09-26 06:15:04 -0700303 /**
304 * Perform dithering. TODO: Re-evaluate whether we need this bit
305 */
bsalomond79c5492015-04-27 10:07:04 -0700306 kDither_Flag = 0x01,
egdaniel89af44a2014-09-26 06:15:04 -0700307 /**
308 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
309 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
310 * the 3D API.
311 */
bsalomond79c5492015-04-27 10:07:04 -0700312 kHWAntialias_Flag = 0x02,
egdaniel89af44a2014-09-26 06:15:04 -0700313
bsalomond79c5492015-04-27 10:07:04 -0700314 /**
315 * Modifies the vertex shader so that vertices will be positioned at pixel centers.
316 */
317 kSnapVerticesToPixelCenters_Flag = 0x04,
318
319 kLast_Flag = kSnapVerticesToPixelCenters_Flag,
egdaniel89af44a2014-09-26 06:15:04 -0700320 };
321
bsalomond79c5492015-04-27 10:07:04 -0700322 bool isDither() const { return SkToBool(fFlags & kDither_Flag); }
323 bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); }
324 bool snapVerticesToPixelCenters() const {
325 return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000326
327 /**
328 * Enable render state settings.
329 *
bsalomond79c5492015-04-27 10:07:04 -0700330 * @param flags bitfield of Flags specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000331 */
bsalomond79c5492015-04-27 10:07:04 -0700332 void enableState(uint32_t flags) { fFlags |= flags; }
333
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000334 /**
335 * Disable render state settings.
336 *
bsalomond79c5492015-04-27 10:07:04 -0700337 * @param flags bitfield of Flags specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000338 */
bsalomond79c5492015-04-27 10:07:04 -0700339 void disableState(uint32_t flags) { fFlags &= ~(flags); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000340
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000341 /**
bsalomond79c5492015-04-27 10:07:04 -0700342 * Enable or disable flags based on a boolean.
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000343 *
bsalomond79c5492015-04-27 10:07:04 -0700344 * @param flags bitfield of Flags to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000345 * @param enable if true enable stateBits, otherwise disable
346 */
bsalomond79c5492015-04-27 10:07:04 -0700347 void setState(uint32_t flags, bool enable) {
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000348 if (enable) {
bsalomond79c5492015-04-27 10:07:04 -0700349 this->enableState(flags);
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000350 } else {
bsalomond79c5492015-04-27 10:07:04 -0700351 this->disableState(flags);
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000352 }
353 }
354
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000355 /// @}
356
357 ///////////////////////////////////////////////////////////////////////////
358 /// @name Face Culling
359 ////
360
egdaniel89af44a2014-09-26 06:15:04 -0700361 enum DrawFace {
362 kInvalid_DrawFace = -1,
363
364 kBoth_DrawFace,
365 kCCW_DrawFace,
366 kCW_DrawFace,
367 };
368
369 /**
370 * Gets whether the target is drawing clockwise, counterclockwise,
371 * or both faces.
372 * @return the current draw face(s).
373 */
374 DrawFace getDrawFace() const { return fDrawFace; }
375
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000376 /**
377 * Controls whether clockwise, counterclockwise, or both faces are drawn.
378 * @param face the face(s) to draw.
379 */
380 void setDrawFace(DrawFace face) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000381 SkASSERT(kInvalid_DrawFace != face);
bsalomon2ed5ef82014-07-07 08:44:05 -0700382 fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000383 }
384
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000385 /// @}
386
387 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000388
bsalomon6be6f7c2015-02-26 13:05:21 -0800389 GrPipelineBuilder& operator=(const GrPipelineBuilder& that);
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000390
joshualitt4d8da812015-01-28 12:53:54 -0800391 // TODO delete when we have Batch
joshualitt56995b52014-12-11 15:44:02 -0800392 const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const {
393 this->calcColorInvariantOutput(pp);
egdaniel912b3d22014-11-17 07:45:53 -0800394 return fColorProcInfo;
395 }
396
joshualitt56995b52014-12-11 15:44:02 -0800397 const GrProcOptInfo& coverageProcInfo(const GrPrimitiveProcessor* pp) const {
398 this->calcCoverageInvariantOutput(pp);
egdaniel912b3d22014-11-17 07:45:53 -0800399 return fCoverageProcInfo;
400 }
401
joshualitt4d8da812015-01-28 12:53:54 -0800402 const GrProcOptInfo& colorProcInfo(const GrBatch* batch) const {
403 this->calcColorInvariantOutput(batch);
404 return fColorProcInfo;
405 }
406
407 const GrProcOptInfo& coverageProcInfo(const GrBatch* batch) const {
408 this->calcCoverageInvariantOutput(batch);
409 return fCoverageProcInfo;
410 }
joshualitt44701df2015-02-23 14:44:57 -0800411
412 void setClip(const GrClip& clip) { fClip = clip; }
413 const GrClip& clip() const { return fClip; }
414
joshualitt5b4f05f2015-07-10 07:26:21 -0700415 GrProcessorDataManager* getProcessorDataManager() { return fProcDataManager.get(); }
416 const GrProcessorDataManager* processorDataManager() const { return fProcDataManager.get(); }
joshualitt2cdec312015-07-09 07:31:31 -0700417
joshualitt5e6ba212015-07-13 07:35:05 -0700418 /**
419 * When this object is destroyed it will remove any additions to the GrProcessorDataManager
420 * owned by the GrPipelineBuilder
421 * This class can transiently modify its "const" GrPipelineBuilder object but will restore it
422 * when done - so it is notionally "const" correct.
423 */
424 class AutoRestoreProcessorDataManager : public ::SkNoncopyable {
425 public:
426 AutoRestoreProcessorDataManager() : fPipelineBuilder(NULL), fSaveMarker(0) {}
427
428 AutoRestoreProcessorDataManager(GrPipelineBuilder* ds)
429 : fPipelineBuilder(NULL)
430 , fSaveMarker(0) {
431 this->set(ds);
432 }
433
434 ~AutoRestoreProcessorDataManager() { this->set(NULL); }
435
436 void set(const GrPipelineBuilder* ds) {
437 if (fPipelineBuilder) {
438 fPipelineBuilder->getProcessorDataManager()->restoreToSaveMarker(/*fSaveMarker*/);
439 }
440 fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds);
441 if (ds) {
442 fSaveMarker = ds->processorDataManager()->currentSaveMarker();
443 }
444 }
445
446 bool isSet() const { return SkToBool(fPipelineBuilder); }
447
448 GrProcessorDataManager* getProcessorDataManager() {
449 SkASSERT(this->isSet());
450 return fPipelineBuilder->getProcessorDataManager();
451 }
452
453 private:
454 // notionally const (as marginalia)
455 GrPipelineBuilder* fPipelineBuilder;
456 uint32_t fSaveMarker;
457 };
458
459
egdaniele36914c2015-02-13 09:00:33 -0800460private:
461 // Calculating invariant color / coverage information is expensive, so we partially cache the
462 // results.
463 //
464 // canUseFracCoveragePrimProc() - Called in regular skia draw, caches results but only for a
465 // specific color and coverage. May be called multiple times
cdalton1fa45722015-06-02 10:43:39 -0700466 // willColorBlendWithDst() - only called by Nvpr, does not cache results
egdaniele36914c2015-02-13 09:00:33 -0800467 // GrOptDrawState constructor - never caches results
joshualittd15e4e42015-01-26 13:30:10 -0800468
469 /**
joshualitt4d8da812015-01-28 12:53:54 -0800470 * Primproc variants of the calc functions
471 * TODO remove these when batch is everywhere
joshualittd5a7db42015-01-27 15:39:06 -0800472 */
joshualitt4d8da812015-01-28 12:53:54 -0800473 void calcColorInvariantOutput(const GrPrimitiveProcessor*) const;
joshualittc2893c52015-01-28 06:54:30 -0800474 void calcCoverageInvariantOutput(const GrPrimitiveProcessor*) const;
joshualittd5a7db42015-01-27 15:39:06 -0800475
476 /**
joshualitt4d8da812015-01-28 12:53:54 -0800477 * GrBatch provides the initial seed for these loops based off of its initial geometry data
478 */
479 void calcColorInvariantOutput(const GrBatch*) const;
480 void calcCoverageInvariantOutput(const GrBatch*) const;
481
482 /**
egdanielb6cbc382014-11-13 11:00:34 -0800483 * If fColorProcInfoValid is false, function calculates the invariant output for the color
bsalomon6be6f7c2015-02-26 13:05:21 -0800484 * processors and results are stored in fColorProcInfo.
egdanielb6cbc382014-11-13 11:00:34 -0800485 */
joshualitt2e3b3e32014-12-09 13:31:14 -0800486 void calcColorInvariantOutput(GrColor) const;
egdanielb6cbc382014-11-13 11:00:34 -0800487
488 /**
489 * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
bsalomon6be6f7c2015-02-26 13:05:21 -0800490 * processors and results are stored in fCoverageProcInfo.
egdanielb6cbc382014-11-13 11:00:34 -0800491 */
joshualitt2e3b3e32014-12-09 13:31:14 -0800492 void calcCoverageInvariantOutput(GrColor) const;
egdanielb6cbc382014-11-13 11:00:34 -0800493
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000494 // Some of the auto restore objects assume that no effects are removed during their lifetime.
495 // This is used to assert that this condition holds.
joshualitt5e6ba212015-07-13 07:35:05 -0700496 SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000497
joshualitta5305a12014-10-10 17:47:00 -0700498 typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
egdaniel89af44a2014-09-26 06:15:04 -0700499
joshualitt5b4f05f2015-07-10 07:26:21 -0700500 SkAutoTUnref<GrProcessorDataManager> fProcDataManager;
bsalomonae59b772014-11-19 08:23:49 -0800501 SkAutoTUnref<GrRenderTarget> fRenderTarget;
bsalomond79c5492015-04-27 10:07:04 -0700502 uint32_t fFlags;
bsalomonae59b772014-11-19 08:23:49 -0800503 GrStencilSettings fStencilSettings;
bsalomonae59b772014-11-19 08:23:49 -0800504 DrawFace fDrawFace;
joshualitt2fdeda02015-01-22 07:11:44 -0800505 mutable SkAutoTUnref<const GrXPFactory> fXPFactory;
bsalomonae59b772014-11-19 08:23:49 -0800506 FragmentStageArray fColorStages;
507 FragmentStageArray fCoverageStages;
joshualitt44701df2015-02-23 14:44:57 -0800508 GrClip fClip;
egdaniel89af44a2014-09-26 06:15:04 -0700509
egdanielb6cbc382014-11-13 11:00:34 -0800510 mutable GrProcOptInfo fColorProcInfo;
511 mutable GrProcOptInfo fCoverageProcInfo;
512 mutable bool fColorProcInfoValid;
513 mutable bool fCoverageProcInfoValid;
joshualitt2e3b3e32014-12-09 13:31:14 -0800514 mutable GrColor fColorCache;
515 mutable GrColor fCoverageCache;
egdanielb6cbc382014-11-13 11:00:34 -0800516
egdaniel8dd688b2015-01-22 10:16:09 -0800517 friend class GrPipeline;
tomhudson@google.com93813632011-10-27 20:21:16 +0000518};
519
520#endif