blob: 8d7ec9891e75c12f18ad7c64e5a362e967426bbd [file] [log] [blame]
tomhudson@google.com93813632011-10-27 20:21:16 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrDrawState_DEFINED
9#define GrDrawState_DEFINED
10
egdaniel89af44a2014-09-26 06:15:04 -070011
commit-bot@chromium.org24ab3b02013-08-14 21:56:37 +000012#include "GrBlend.h"
egdanielc0648242014-09-22 13:17:02 -070013#include "GrDrawTargetCaps.h"
bsalomon6251d172014-10-15 10:50:36 -070014#include "GrGeometryProcessor.h"
bsalomonf96ba022014-09-17 08:05:40 -070015#include "GrGpuResourceRef.h"
bsalomonae59b772014-11-19 08:23:49 -080016#include "GrFragmentStage.h"
egdanielb6cbc382014-11-13 11:00:34 -080017#include "GrProcOptInfo.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"
egdaniel95131432014-12-09 11:15:43 -080022#include "effects/GrPorterDuffXferProcessor.h"
bsalomon@google.com68b58c92013-01-17 16:50:08 +000023#include "effects/GrSimpleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000024
egdaniel89af44a2014-09-26 06:15:04 -070025class GrDrawTargetCaps;
egdaniel89af44a2014-09-26 06:15:04 -070026class GrPaint;
27class GrTexture;
egdaniel170f90b2014-09-16 12:54:40 -070028
joshualitt9853cce2014-11-17 14:22:48 -080029class GrDrawState {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000030public:
egdaniel69bb90c2014-11-11 07:32:45 -080031 GrDrawState() {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000032 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000033 this->reset();
34 }
tomhudson@google.com93813632011-10-27 20:21:16 +000035
egdaniel69bb90c2014-11-11 07:32:45 -080036 GrDrawState(const SkMatrix& initialViewMatrix) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000037 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.comeb6879f2013-06-13 19:34:18 +000038 this->reset(initialViewMatrix);
39 }
bsalomon@google.com137f1342013-05-29 21:27:53 +000040
41 /**
42 * Copies another draw state.
43 **/
joshualitt9853cce2014-11-17 14:22:48 -080044 GrDrawState(const GrDrawState& state) {
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +000045 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000046 *this = state;
47 }
48
bsalomon@google.com137f1342013-05-29 21:27:53 +000049 /**
50 * Copies another draw state with a preconcat to the view matrix.
51 **/
bsalomon8f727332014-08-05 07:50:06 -070052 GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
robertphillips@google.com9ec07532012-06-22 12:01:30 +000053
egdaniel170f90b2014-09-16 12:54:40 -070054 virtual ~GrDrawState();
bsalomon@google.com137f1342013-05-29 21:27:53 +000055
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000056 /**
joshualittb0a8a372014-09-23 09:50:21 -070057 * Resets to the default state. GrProcessors will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000058 */
bsalomon@google.com137f1342013-05-29 21:27:53 +000059 void reset() { this->onReset(NULL); }
robertphillips@google.com9ec07532012-06-22 12:01:30 +000060
bsalomon@google.com137f1342013-05-29 21:27:53 +000061 void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
bsalomon@google.comaf84e742012-10-05 13:23:24 +000062
63 /**
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000064 * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
65 * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
bsalomon9c0822a2014-08-11 11:07:48 -070066 * equivalents are set to default values with the exception of vertex attribute state which
67 * is unmodified by this function and clipping which will be enabled.
bsalomon@google.comaf84e742012-10-05 13:23:24 +000068 */
commit-bot@chromium.orgbb6a3172013-05-28 17:25:49 +000069 void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000070
jvanverth@google.com9b855c72013-03-01 18:21:22 +000071 /// @}
72
jvanverth@google.com9b855c72013-03-01 18:21:22 +000073 /**
bsalomon62c447d2014-08-08 08:08:50 -070074 * Depending on features available in the underlying 3D API and the color blend mode requested
75 * it may or may not be possible to correctly blend with fractional pixel coverage generated by
76 * the fragment shader.
77 *
78 * This function considers the current draw state and the draw target's capabilities to
79 * determine whether coverage can be handled correctly. This function assumes that the caller
joshualitt2e3b3e32014-12-09 13:31:14 -080080 * intends to specify fractional pixel coverage via a primitive processor but may not have
81 * specified it yet.
bsalomon62c447d2014-08-08 08:08:50 -070082 */
joshualitt2e3b3e32014-12-09 13:31:14 -080083 bool canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const;
bsalomon62c447d2014-08-08 08:08:50 -070084
egdaniel89af44a2014-09-26 06:15:04 -070085 /**
86 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
87 */
joshualitt56995b52014-12-11 15:44:02 -080088 bool hasSolidCoverage(const GrPrimitiveProcessor*) const;
egdaniel89af44a2014-09-26 06:15:04 -070089
egdanielcd8b6302014-11-11 14:46:05 -080090 /**
91 * This function returns true if the render target destination pixel values will be read for
92 * blending during draw.
93 */
joshualitt56995b52014-12-11 15:44:02 -080094 bool willBlendWithDst(const GrPrimitiveProcessor*) const;
joshualittbd769d02014-09-04 08:56:46 -070095
bsalomon@google.com2401ae82012-01-17 21:03:05 +000096 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.comadc65362013-01-28 14:26:09 +000097 /// @name Effect Stages
joshualittb0a8a372014-09-23 09:50:21 -070098 /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
99 /// fragment shader. Its inputs are the output from the previous stage as well as some variables
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000100 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
101 /// the fragment position, local coordinates).
102 ///
103 /// The stages are divided into two sets, color-computing and coverage-computing. The final
104 /// color stage produces the final pixel color. The coverage-computing stages function exactly
105 /// as the color-computing but the output of the final coverage stage is treated as a fractional
106 /// pixel coverage rather than as input to the src/dst color blend step.
107 ///
108 /// The input color to the first color-stage is either the constant color or interpolated
109 /// per-vertex colors. The input to the first coverage stage is either a constant coverage
110 /// (usually full-coverage) or interpolated per-vertex coverage.
111 ///
112 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
113 /// the color / coverage distinction.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000114 ////
115
egdaniel89af44a2014-09-26 06:15:04 -0700116 int numColorStages() const { return fColorStages.count(); }
117 int numCoverageStages() const { return fCoverageStages.count(); }
joshualitt4dd99882014-11-11 08:51:30 -0800118 int numFragmentStages() const { return this->numColorStages() + this->numCoverageStages(); }
egdaniel378092f2014-12-03 10:40:13 -0800119
120 const GrXPFactory* getXPFactory() const { return fXPFactory.get(); }
121
egdaniel89af44a2014-09-26 06:15:04 -0700122 const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
123 const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
124
125 /**
126 * Checks whether any of the effects will read the dst pixel color.
joshualitt2e3b3e32014-12-09 13:31:14 -0800127 * TODO remove when we have an XP
egdaniel89af44a2014-09-26 06:15:04 -0700128 */
joshualitt56995b52014-12-11 15:44:02 -0800129 bool willEffectReadDstColor(const GrPrimitiveProcessor*) const;
egdaniel89af44a2014-09-26 06:15:04 -0700130
egdaniel95131432014-12-09 11:15:43 -0800131 /**
132 * The xfer processor factory.
133 */
134 const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
135 fXPFactory.reset(SkRef(xpFactory));
136 return xpFactory;
137 }
138
139 void setPorterDuffXPFactory(SkXfermode::Mode mode) {
140 fXPFactory.reset(GrPorterDuffXPFactory::Create(mode));
141 }
142
143 void setPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) {
144 fXPFactory.reset(GrPorterDuffXPFactory::Create(src, dst));
145 }
146
joshualittb0a8a372014-09-23 09:50:21 -0700147 const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700148 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -0700149 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -0800150 fColorProcInfoValid = false;
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000151 return effect;
152 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +0000153
joshualittb0a8a372014-09-23 09:50:21 -0700154 const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
bsalomon49f085d2014-09-05 13:34:00 -0700155 SkASSERT(effect);
joshualittb0a8a372014-09-23 09:50:21 -0700156 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
egdanielb6cbc382014-11-13 11:00:34 -0800157 fCoverageProcInfoValid = false;
bsalomon@google.comadc65362013-01-28 14:26:09 +0000158 return effect;
159 }
160
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000161 /**
bsalomon@google.comc7818882013-03-20 19:19:53 +0000162 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000163 */
joshualittb0a8a372014-09-23 09:50:21 -0700164 void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
165 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000166 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000167
joshualittb0a8a372014-09-23 09:50:21 -0700168 void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
169 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000170 }
171
joshualittb0a8a372014-09-23 09:50:21 -0700172 void addColorTextureProcessor(GrTexture* texture,
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000173 const SkMatrix& matrix,
174 const GrTextureParams& params) {
joshualittb0a8a372014-09-23 09:50:21 -0700175 this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
176 }
177
178 void addCoverageTextureProcessor(GrTexture* texture,
179 const SkMatrix& matrix,
180 const GrTextureParams& params) {
181 this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000182 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000183
robertphillips@google.com972265d2012-06-13 18:49:30 +0000184 /**
bsalomon9b536522014-09-05 09:18:51 -0700185 * When this object is destroyed it will remove any color/coverage effects from the draw state
186 * that were added after its constructor.
187 *
188 * This class has strange behavior around geometry processor. If there is a GP on the draw state
189 * it will assert that the GP is not modified until after the destructor of the ARE. If the
190 * draw state has a NULL GP when the ARE is constructed then it will reset it to null in the
191 * destructor.
192 *
193 * TODO: We'd prefer for the ARE to just save and restore the GP. However, this would add
194 * significant complexity to the multi-ref architecture for deferred drawing. Once GrDrawState
195 * and GrOptDrawState are fully separated then GrDrawState will never be in the deferred
196 * execution state and GrOptDrawState always will be (and will be immutable and therefore
197 * unable to have an ARE). At this point we can restore sanity and have the ARE save and restore
198 * the GP.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000199 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000200 class AutoRestoreEffects : public ::SkNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000201 public:
bsalomon9b536522014-09-05 09:18:51 -0700202 AutoRestoreEffects()
203 : fDrawState(NULL)
bsalomon9b536522014-09-05 09:18:51 -0700204 , fColorEffectCnt(0)
205 , fCoverageEffectCnt(0) {}
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000206
bsalomon9b536522014-09-05 09:18:51 -0700207 AutoRestoreEffects(GrDrawState* ds)
208 : fDrawState(NULL)
bsalomon9b536522014-09-05 09:18:51 -0700209 , fColorEffectCnt(0)
210 , fCoverageEffectCnt(0) {
skia.committer@gmail.com5c493d52013-06-14 07:00:49 +0000211 this->set(ds);
robertphillips@google.comf09b87d2013-06-13 20:06:44 +0000212 }
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000213
214 ~AutoRestoreEffects() { this->set(NULL); }
215
bsalomon8f727332014-08-05 07:50:06 -0700216 void set(GrDrawState* ds);
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000217
bsalomon49f085d2014-09-05 13:34:00 -0700218 bool isSet() const { return SkToBool(fDrawState); }
bsalomon8af05232014-06-03 06:34:58 -0700219
robertphillips@google.com972265d2012-06-13 18:49:30 +0000220 private:
bsalomon9b536522014-09-05 09:18:51 -0700221 GrDrawState* fDrawState;
bsalomon9b536522014-09-05 09:18:51 -0700222 int fColorEffectCnt;
223 int fCoverageEffectCnt;
robertphillips@google.com972265d2012-06-13 18:49:30 +0000224 };
225
joshualitta58fe352014-10-27 08:39:00 -0700226 /**
227 * AutoRestoreStencil
228 *
229 * This simple struct saves and restores the stencil settings
230 */
231 class AutoRestoreStencil : public ::SkNoncopyable {
232 public:
233 AutoRestoreStencil() : fDrawState(NULL) {}
234
235 AutoRestoreStencil(GrDrawState* ds) : fDrawState(NULL) { this->set(ds); }
236
237 ~AutoRestoreStencil() { this->set(NULL); }
238
239 void set(GrDrawState* ds) {
240 if (fDrawState) {
241 fDrawState->setStencil(fStencilSettings);
242 }
243 fDrawState = ds;
244 if (ds) {
245 fStencilSettings = ds->getStencil();
246 }
247 }
248
249 bool isSet() const { return SkToBool(fDrawState); }
250
251 private:
252 GrDrawState* fDrawState;
253 GrStencilSettings fStencilSettings;
254 };
255
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000256 /// @}
257
258 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000259 /// @name Blending
260 ////
261
egdaniel89af44a2014-09-26 06:15:04 -0700262 /**
263 * Determines whether multiplying the computed per-pixel color by the pixel's fractional
264 * coverage before the blend will give the correct final destination color. In general it
265 * will not as coverage is applied after blending.
266 */
267 bool canTweakAlphaForCoverage() const;
268
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000269 /// @}
270
271 ///////////////////////////////////////////////////////////////////////////
272 /// @name View Matrix
273 ////
274
275 /**
egdaniel89af44a2014-09-26 06:15:04 -0700276 * Retrieves the current view matrix
277 * @return the current view matrix.
278 */
279 const SkMatrix& getViewMatrix() const { return fViewMatrix; }
280
281 /**
282 * Retrieves the inverse of the current view matrix.
283 *
284 * If the current view matrix is invertible, return true, and if matrix
285 * is non-null, copy the inverse into it. If the current view matrix is
286 * non-invertible, return false and ignore the matrix parameter.
287 *
288 * @param matrix if not null, will receive a copy of the current inverse.
289 */
290 bool getViewInverse(SkMatrix* matrix) const {
291 SkMatrix inverse;
292 if (fViewMatrix.invert(&inverse)) {
293 if (matrix) {
294 *matrix = inverse;
295 }
296 return true;
297 }
298 return false;
299 }
300
301 /**
bsalomon@google.com137f1342013-05-29 21:27:53 +0000302 * Sets the view matrix to identity and updates any installed effects to compensate for the
303 * coord system change.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000304 */
bsalomon@google.com137f1342013-05-29 21:27:53 +0000305 bool setIdentityViewMatrix();
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000306
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000307 ////////////////////////////////////////////////////////////////////////////
308
309 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000310 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.com137f1342013-05-29 21:27:53 +0000311 * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000312 */
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000313 class AutoViewMatrixRestore : public ::SkNoncopyable {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000314 public:
315 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000316
bsalomon@google.comc7818882013-03-20 19:19:53 +0000317 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000318 fDrawState = NULL;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000319 this->set(ds, preconcatMatrix);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000320 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000321
322 ~AutoViewMatrixRestore() { this->restore(); }
323
bsalomon@google.coma8347462012-10-08 18:59:39 +0000324 /**
325 * Can be called prior to destructor to restore the original matrix.
326 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000327 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000328
bsalomon@google.comc7818882013-03-20 19:19:53 +0000329 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000330
bsalomon@google.com137f1342013-05-29 21:27:53 +0000331 /** Sets the draw state's matrix to identity. This can fail because the current view matrix
332 is not invertible. */
333 bool setIdentity(GrDrawState* drawState);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000334
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000335 private:
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000336 void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
337
joshualittb0a8a372014-09-23 09:50:21 -0700338 GrDrawState* fDrawState;
339 SkMatrix fViewMatrix;
340 int fNumColorStages;
joshualitta5305a12014-10-10 17:47:00 -0700341 SkAutoSTArray<8, GrFragmentStage::SavedCoordChange> fSavedCoordChanges;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000342 };
343
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000344 /// @}
345
346 ///////////////////////////////////////////////////////////////////////////
347 /// @name Render Target
348 ////
349
350 /**
egdaniel89af44a2014-09-26 06:15:04 -0700351 * Retrieves the currently set render-target.
352 *
353 * @return The currently set render target.
354 */
bsalomon37dd3312014-11-03 08:47:23 -0800355 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
egdaniel89af44a2014-09-26 06:15:04 -0700356
357 /**
bsalomon@google.comca432082013-01-23 19:53:46 +0000358 * Sets the render-target used at the next drawing call
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000359 *
360 * @param target The render target to set.
361 */
bsalomonae59b772014-11-19 08:23:49 -0800362 void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000363
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000364 /// @}
365
366 ///////////////////////////////////////////////////////////////////////////
367 /// @name Stencil
368 ////
369
egdaniel89af44a2014-09-26 06:15:04 -0700370 const GrStencilSettings& getStencil() const { return fStencilSettings; }
371
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000372 /**
373 * Sets the stencil settings to use for the next draw.
374 * Changing the clip has the side-effect of possibly zeroing
375 * out the client settable stencil bits. So multipass algorithms
376 * using stencil should not change the clip between passes.
377 * @param settings the stencil settings to use.
378 */
bsalomon04ddf892014-11-19 12:36:22 -0800379 void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000380
381 /**
382 * Shortcut to disable stencil testing and ops.
383 */
bsalomon04ddf892014-11-19 12:36:22 -0800384 void disableStencil() { fStencilSettings.setDisabled(); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000385
bsalomon2ed5ef82014-07-07 08:44:05 -0700386 GrStencilSettings* stencil() { return &fStencilSettings; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000387
388 /// @}
389
390 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000391 /// @name State Flags
392 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000393
egdaniel89af44a2014-09-26 06:15:04 -0700394 /**
395 * Flags that affect rendering. Controlled using enable/disableState(). All
396 * default to disabled.
397 */
398 enum StateBits {
399 /**
400 * Perform dithering. TODO: Re-evaluate whether we need this bit
401 */
402 kDither_StateBit = 0x01,
403 /**
404 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
405 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
406 * the 3D API.
407 */
408 kHWAntialias_StateBit = 0x02,
409 /**
410 * Draws will respect the clip, otherwise the clip is ignored.
411 */
412 kClip_StateBit = 0x04,
413 /**
414 * Disables writing to the color buffer. Useful when performing stencil
415 * operations.
416 */
417 kNoColorWrites_StateBit = 0x08,
418
419 /**
420 * Usually coverage is applied after color blending. The color is blended using the coeffs
421 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
422 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
423 * this case there is no distinction between coverage and color and the caller needs direct
424 * control over the blend coeffs. When set, there will be a single blend step controlled by
425 * setBlendFunc() which will use coverage*color as the src color.
426 */
427 kCoverageDrawing_StateBit = 0x10,
joshualitt7a6184f2014-10-29 18:29:27 -0700428 kLast_StateBit = kCoverageDrawing_StateBit,
egdaniel89af44a2014-09-26 06:15:04 -0700429 };
430
egdaniel89af44a2014-09-26 06:15:04 -0700431 bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
432 bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
433 bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
bsalomon04ddf892014-11-19 12:36:22 -0800434 bool isDither() const { return 0 != (fFlagBits & kDither_StateBit); }
435 bool isHWAntialias() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000436
437 /**
438 * Enable render state settings.
439 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000440 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000441 */
bsalomon04ddf892014-11-19 12:36:22 -0800442 void enableState(uint32_t stateBits) { fFlagBits |= stateBits; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000443
444 /**
445 * Disable render state settings.
446 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000447 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000448 */
bsalomon04ddf892014-11-19 12:36:22 -0800449 void disableState(uint32_t stateBits) { fFlagBits &= ~(stateBits); }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000450
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000451 /**
452 * Enable or disable stateBits based on a boolean.
453 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000454 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000455 * @param enable if true enable stateBits, otherwise disable
456 */
457 void setState(uint32_t stateBits, bool enable) {
458 if (enable) {
459 this->enableState(stateBits);
460 } else {
461 this->disableState(stateBits);
462 }
463 }
464
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000465 /// @}
466
467 ///////////////////////////////////////////////////////////////////////////
468 /// @name Face Culling
469 ////
470
egdaniel89af44a2014-09-26 06:15:04 -0700471 enum DrawFace {
472 kInvalid_DrawFace = -1,
473
474 kBoth_DrawFace,
475 kCCW_DrawFace,
476 kCW_DrawFace,
477 };
478
479 /**
480 * Gets whether the target is drawing clockwise, counterclockwise,
481 * or both faces.
482 * @return the current draw face(s).
483 */
484 DrawFace getDrawFace() const { return fDrawFace; }
485
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000486 /**
487 * Controls whether clockwise, counterclockwise, or both faces are drawn.
488 * @param face the face(s) to draw.
489 */
490 void setDrawFace(DrawFace face) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000491 SkASSERT(kInvalid_DrawFace != face);
bsalomon2ed5ef82014-07-07 08:44:05 -0700492 fDrawFace = face;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000493 }
494
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000495 /// @}
496
497 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000498
bsalomon8f727332014-08-05 07:50:06 -0700499 GrDrawState& operator= (const GrDrawState& that);
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000500
501private:
joshualitt56995b52014-12-11 15:44:02 -0800502 bool isEqual(const GrDrawState& that, bool explicitLocalCoords) const;
egdaniel89af44a2014-09-26 06:15:04 -0700503
joshualitt56995b52014-12-11 15:44:02 -0800504 const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const {
505 this->calcColorInvariantOutput(pp);
egdaniel912b3d22014-11-17 07:45:53 -0800506 return fColorProcInfo;
507 }
508
joshualitt56995b52014-12-11 15:44:02 -0800509 const GrProcOptInfo& coverageProcInfo(const GrPrimitiveProcessor* pp) const {
510 this->calcCoverageInvariantOutput(pp);
egdaniel912b3d22014-11-17 07:45:53 -0800511 return fCoverageProcInfo;
512 }
513
egdaniel89af44a2014-09-26 06:15:04 -0700514 /**
joshualitt56995b52014-12-11 15:44:02 -0800515 * If fColorProcInfoValid is false, function calculates the invariant output for the color
516 * stages and results are stored in fColorProcInfo.
egdaniel89af44a2014-09-26 06:15:04 -0700517 */
joshualitt56995b52014-12-11 15:44:02 -0800518 void calcColorInvariantOutput(const GrPrimitiveProcessor*) const;
519
520 /**
521 * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
522 * stages and results are stored in fCoverageProcInfo.
523 */
524 void calcCoverageInvariantOutput(const GrPrimitiveProcessor*) const;
egdaniel89af44a2014-09-26 06:15:04 -0700525
egdanielb6cbc382014-11-13 11:00:34 -0800526 /**
527 * If fColorProcInfoValid is false, function calculates the invariant output for the color
528 * stages and results are stored in fColorProcInfo.
529 */
joshualitt2e3b3e32014-12-09 13:31:14 -0800530 void calcColorInvariantOutput(GrColor) const;
egdanielb6cbc382014-11-13 11:00:34 -0800531
532 /**
533 * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
534 * stages and results are stored in fCoverageProcInfo.
535 */
joshualitt2e3b3e32014-12-09 13:31:14 -0800536 void calcCoverageInvariantOutput(GrColor) const;
egdanielb6cbc382014-11-13 11:00:34 -0800537
bsalomon8f727332014-08-05 07:50:06 -0700538 void onReset(const SkMatrix* initialViewMatrix);
bsalomon@google.com137f1342013-05-29 21:27:53 +0000539
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000540 // Some of the auto restore objects assume that no effects are removed during their lifetime.
541 // This is used to assert that this condition holds.
commit-bot@chromium.org1acc3d72013-09-06 23:13:05 +0000542 SkDEBUGCODE(int fBlockEffectRemovalCnt;)
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000543
joshualitta5305a12014-10-10 17:47:00 -0700544 typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
egdaniel89af44a2014-09-26 06:15:04 -0700545
bsalomonae59b772014-11-19 08:23:49 -0800546 SkAutoTUnref<GrRenderTarget> fRenderTarget;
bsalomonae59b772014-11-19 08:23:49 -0800547 SkMatrix fViewMatrix;
bsalomonae59b772014-11-19 08:23:49 -0800548 uint32_t fFlagBits;
bsalomonae59b772014-11-19 08:23:49 -0800549 GrStencilSettings fStencilSettings;
bsalomonae59b772014-11-19 08:23:49 -0800550 DrawFace fDrawFace;
egdaniel378092f2014-12-03 10:40:13 -0800551 SkAutoTUnref<const GrXPFactory> fXPFactory;
bsalomonae59b772014-11-19 08:23:49 -0800552 FragmentStageArray fColorStages;
553 FragmentStageArray fCoverageStages;
egdaniel89af44a2014-09-26 06:15:04 -0700554
egdanielb6cbc382014-11-13 11:00:34 -0800555 mutable GrProcOptInfo fColorProcInfo;
556 mutable GrProcOptInfo fCoverageProcInfo;
557 mutable bool fColorProcInfoValid;
558 mutable bool fCoverageProcInfoValid;
joshualitt2e3b3e32014-12-09 13:31:14 -0800559 mutable GrColor fColorCache;
560 mutable GrColor fCoverageCache;
joshualitt56995b52014-12-11 15:44:02 -0800561 mutable const GrPrimitiveProcessor* fColorPrimProc;
562 mutable const GrPrimitiveProcessor* fCoveragePrimProc;
egdanielb6cbc382014-11-13 11:00:34 -0800563
egdanielb109ac22014-10-07 06:45:44 -0700564 friend class GrOptDrawState;
tomhudson@google.com93813632011-10-27 20:21:16 +0000565};
566
567#endif