blob: 3c6c3a371a2aaf11802204a78d815168f4d15dd4 [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
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000011#include "GrBackendEffectFactory.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000012#include "GrColor.h"
13#include "GrMatrix.h"
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000014#include "GrRefCnt.h"
bsalomon@google.com08283af2012-10-26 13:01:20 +000015#include "GrEffectStage.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000016#include "GrStencil.h"
bsalomon@google.com64aef2b2012-06-11 15:36:13 +000017#include "GrTexture.h"
robertphillips@google.com9ec07532012-06-22 12:01:30 +000018#include "GrRenderTarget.h"
tomhudson@google.com1e8f0162012-07-20 16:25:18 +000019#include "effects/GrSingleTextureEffect.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000020
21#include "SkXfermode.h"
22
bsalomon@google.comaf84e742012-10-05 13:23:24 +000023class GrPaint;
tomhudson@google.com93813632011-10-27 20:21:16 +000024
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000025class GrDrawState : public GrRefCnt {
bsalomon@google.com2e3d1442012-03-26 20:33:54 +000026public:
reed@google.comfa35e3d2012-06-26 20:16:17 +000027 SK_DECLARE_INST_COUNT(GrDrawState)
rmistry@google.comd6176b02012-08-23 18:14:13 +000028
tomhudson@google.com93813632011-10-27 20:21:16 +000029 /**
bsalomon@google.com13221342012-10-26 13:41:59 +000030 * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
31 * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
32 * output from the previous enabled stage and a position. The position is either derived from
33 * the interpolated vertex positions or explicit per-vertex coords, depending upon the
34 * GrVertexLayout used to draw.
robertphillips@google.combf5cad42012-05-10 12:40:40 +000035 *
bsalomon@google.com13221342012-10-26 13:41:59 +000036 * The stages are divided into two sets, color-computing and coverage-computing. The final color
37 * stage produces the final pixel color. The coverage-computing stages function exactly as the
38 * color-computing but the output of the final coverage stage is treated as a fractional pixel
39 * coverage rather than as input to the src/dst color blend step.
40 *
41 * The input color to the first enabled color-stage is either the constant color or interpolated
42 * per-vertex colors, depending upon GrVertexLayout. The input to the first coverage stage is
43 * either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or
44 * edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a
45 * GrEffect).
46 *
47 * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
48 * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
49 * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +000050 * by GrClipMaskManager.
tomhudson@google.com93813632011-10-27 20:21:16 +000051 */
52 enum {
twiz@google.com58071162012-07-18 21:41:50 +000053 kNumStages = 5,
tomhudson@google.com93813632011-10-27 20:21:16 +000054 kMaxTexCoords = kNumStages
55 };
56
rmistry@google.comd6176b02012-08-23 18:14:13 +000057 GrDrawState()
robertphillips@google.com9ec07532012-06-22 12:01:30 +000058 : fRenderTarget(NULL) {
59
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000060 this->reset();
61 }
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000062
rmistry@google.comd6176b02012-08-23 18:14:13 +000063 GrDrawState(const GrDrawState& state)
robertphillips@google.com9ec07532012-06-22 12:01:30 +000064 : fRenderTarget(NULL) {
65
bsalomon@google.com46f7afb2012-01-18 19:51:55 +000066 *this = state;
67 }
68
robertphillips@google.com9ec07532012-06-22 12:01:30 +000069 virtual ~GrDrawState() {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000070 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000071 GrSafeSetNull(fRenderTarget);
72 }
73
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000074 /**
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000075 * Resets to the default state.
bsalomon@google.com08283af2012-10-26 13:01:20 +000076 * GrEffects will be removed from all stages.
rmistry@google.comd6176b02012-08-23 18:14:13 +000077 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000078 void reset() {
robertphillips@google.com9ec07532012-06-22 12:01:30 +000079
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +000080 this->disableStages();
robertphillips@google.com9ec07532012-06-22 12:01:30 +000081
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000082 fColor = 0xffffffff;
bsalomon@google.com861b3a22012-09-26 17:28:25 +000083 fViewMatrix.reset();
84 GrSafeSetNull(fRenderTarget);
bsalomon@google.com47059542012-06-06 20:51:20 +000085 fSrcBlend = kOne_GrBlendCoeff;
86 fDstBlend = kZero_GrBlendCoeff;
bsalomon@google.com861b3a22012-09-26 17:28:25 +000087 fBlendConstant = 0x0;
88 fFlagBits = 0x0;
89 fVertexEdgeType = kHairLine_EdgeType;
90 fStencilSettings.setDisabled();
91 fFirstCoverageStage = kNumStages;
92 fCoverage = 0xffffffff;
93 fColorFilterMode = SkXfermode::kDst_Mode;
94 fColorFilterColor = 0x0;
95 fDrawFace = kBoth_DrawFace;
bsalomon@google.comaf84e742012-10-05 13:23:24 +000096 }
97
98 /**
99 * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000100 * encompasses more than GrPaint. Aspects of GrDrawState that have no
bsalomon@google.comaf84e742012-10-05 13:23:24 +0000101 * GrPaint equivalents are not modified. GrPaint has fewer stages than
102 * GrDrawState. The extra GrDrawState stages are disabled.
103 */
104 void setFromPaint(const GrPaint& paint);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000105
106 ///////////////////////////////////////////////////////////////////////////
107 /// @name Color
108 ////
109
110 /**
111 * Sets color for next draw to a premultiplied-alpha color.
112 *
113 * @param color the color to set.
114 */
115 void setColor(GrColor color) { fColor = color; }
116
117 GrColor getColor() const { return fColor; }
118
119 /**
120 * Sets the color to be used for the next draw to be
121 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
122 *
123 * @param alpha The alpha value to set as the color.
124 */
125 void setAlpha(uint8_t a) {
126 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
127 }
128
129 /**
130 * Add a color filter that can be represented by a color and a mode. Applied
131 * after color-computing texture stages.
132 */
133 void setColorFilter(GrColor c, SkXfermode::Mode mode) {
134 fColorFilterColor = c;
135 fColorFilterMode = mode;
136 }
137
138 GrColor getColorFilterColor() const { return fColorFilterColor; }
139 SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
140
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000141 /**
142 * Constructor sets the color to be 'color' which is undone by the destructor.
143 */
144 class AutoColorRestore : public ::GrNoncopyable {
145 public:
146 AutoColorRestore(GrDrawState* drawState, GrColor color) {
147 fDrawState = drawState;
148 fOldColor = fDrawState->getColor();
149 fDrawState->setColor(color);
150 }
151 ~AutoColorRestore() {
152 fDrawState->setColor(fOldColor);
153 }
154 private:
155 GrDrawState* fDrawState;
156 GrColor fOldColor;
157 };
158
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000159 /// @}
160
161 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000162 /// @name Coverage
163 ////
164
165 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000166 * Sets a constant fractional coverage to be applied to the draw. The
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000167 * initial value (after construction or reset()) is 0xff. The constant
168 * coverage is ignored when per-vertex coverage is provided.
169 */
170 void setCoverage(uint8_t coverage) {
171 fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
172 }
173
174 /**
175 * Version of above that specifies 4 channel per-vertex color. The value
176 * should be premultiplied.
177 */
178 void setCoverage4(GrColor coverage) {
179 fCoverage = coverage;
180 }
181
182 GrColor getCoverage() const {
183 return fCoverage;
184 }
185
186 /// @}
187
188 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000189 /// @name Textures
190 ////
191
192 /**
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000193 * Creates a GrSingleTextureEffect.
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000194 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000195 void createTextureEffect(int stageIdx, GrTexture* texture) {
196 GrAssert(!this->getStage(stageIdx).getEffect());
197 this->stage(stageIdx)->setEffect(SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref();
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000198 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000199 void createTextureEffect(int stageIdx, GrTexture* texture, const GrMatrix& matrix) {
200 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000201 GrEffect* effect = SkNEW_ARGS(GrSingleTextureEffect, (texture));
bsalomon@google.com08283af2012-10-26 13:01:20 +0000202 this->stage(stageIdx)->setEffect(effect, matrix)->unref();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000203 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000204 void createTextureEffect(int stageIdx,
205 GrTexture* texture,
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000206 const GrMatrix& matrix,
207 const GrTextureParams& params) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000208 GrAssert(!this->getStage(stageIdx).getEffect());
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000209 GrEffect* effect = SkNEW_ARGS(GrSingleTextureEffect, (texture, params));
bsalomon@google.com08283af2012-10-26 13:01:20 +0000210 this->stage(stageIdx)->setEffect(effect, matrix)->unref();
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000211 }
212
tomhudson@google.com1e8f0162012-07-20 16:25:18 +0000213
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000214 bool stagesDisabled() {
215 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000216 if (NULL != fStages[i].getEffect()) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000217 return false;
218 }
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000219 }
tomhudson@google.com3eee8fb2012-06-25 12:30:34 +0000220 return true;
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000221 }
tomhudson@google.com676e6602012-07-10 17:21:48 +0000222
bsalomon@google.com08283af2012-10-26 13:01:20 +0000223 void disableStage(int stageIdx) {
224 fStages[stageIdx].setEffect(NULL);
tomhudson@google.com676e6602012-07-10 17:21:48 +0000225 }
226
robertphillips@google.com972265d2012-06-13 18:49:30 +0000227 /**
bsalomon@google.comf271cc72012-10-24 19:35:13 +0000228 * Release all the GrEffects referred to by this draw state.
robertphillips@google.com972265d2012-06-13 18:49:30 +0000229 */
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000230 void disableStages() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000231 for (int i = 0; i < kNumStages; ++i) {
tomhudson@google.com676e6602012-07-10 17:21:48 +0000232 this->disableStage(i);
robertphillips@google.com972265d2012-06-13 18:49:30 +0000233 }
234 }
235
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000236 class AutoStageDisable : public ::GrNoncopyable {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000237 public:
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000238 AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
239 ~AutoStageDisable() {
robertphillips@google.com972265d2012-06-13 18:49:30 +0000240 if (NULL != fDrawState) {
tomhudson@google.com7d6afdd2012-06-22 20:10:50 +0000241 fDrawState->disableStages();
robertphillips@google.com972265d2012-06-13 18:49:30 +0000242 }
243 }
244 private:
245 GrDrawState* fDrawState;
246 };
247
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000248 /// @}
249
250 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com08283af2012-10-26 13:01:20 +0000251 /// @name Stages
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000252 ////
253
254 /**
bsalomon@google.com08283af2012-10-26 13:01:20 +0000255 * Returns the current stage by index.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000256 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000257 const GrEffectStage& getStage(int stageIdx) const {
258 GrAssert((unsigned)stageIdx < kNumStages);
259 return fStages[stageIdx];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000260 }
261
262 /**
bsalomon@google.com08283af2012-10-26 13:01:20 +0000263 * Writable pointer to a stage.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000264 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000265 GrEffectStage* stage(int stageIdx) {
266 GrAssert((unsigned)stageIdx < kNumStages);
267 return fStages + stageIdx;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000268 }
269
270 /**
bsalomon@google.com288d9542012-10-17 12:53:54 +0000271 * Called when the source coord system is changing. preConcat gives the transformation from the
272 * old coord system to the new coord system.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000273 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000274 void preConcatStageMatrices(const GrMatrix& preConcat) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000275 for (int i = 0; i < kNumStages; ++i) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000276 if (this->isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000277 fStages[i].preConcatCoordChange(preConcat);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000278 }
279 }
280 }
281
bsalomon@google.come3d32162012-07-20 13:37:06 +0000282 /**
bsalomon@google.com288d9542012-10-17 12:53:54 +0000283 * Called when the source coord system is changing. preConcatInverse is the inverse of the
284 * transformation from the old coord system to the new coord system. Returns false if the matrix
285 * cannot be inverted.
bsalomon@google.come3d32162012-07-20 13:37:06 +0000286 */
bsalomon@google.com08283af2012-10-26 13:01:20 +0000287 bool preConcatStageMatricesWithInverse(const GrMatrix& preConcatInverse) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000288 GrMatrix inv;
289 bool computed = false;
290 for (int i = 0; i < kNumStages; ++i) {
291 if (this->isStageEnabled(i)) {
bsalomon@google.com288d9542012-10-17 12:53:54 +0000292 if (!computed && !preConcatInverse.invert(&inv)) {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000293 return false;
294 } else {
295 computed = true;
296 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000297 fStages[i].preConcatCoordChange(preConcatInverse);
bsalomon@google.come3d32162012-07-20 13:37:06 +0000298 }
299 }
300 return true;
301 }
302
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000303 /// @}
304
305 ///////////////////////////////////////////////////////////////////////////
306 /// @name Coverage / Color Stages
307 ////
308
309 /**
310 * A common pattern is to compute a color with the initial stages and then
311 * modulate that color by a coverage value in later stage(s) (AA, mask-
rmistry@google.comd6176b02012-08-23 18:14:13 +0000312 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
313 * computed based on the pre-coverage-modulated color. The division of
314 * stages between color-computing and coverage-computing is specified by
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000315 * this method. Initially this is kNumStages (all stages
316 * are color-computing).
317 */
318 void setFirstCoverageStage(int firstCoverageStage) {
319 GrAssert((unsigned)firstCoverageStage <= kNumStages);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000320 fFirstCoverageStage = firstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000321 }
322
323 /**
324 * Gets the index of the first coverage-computing stage.
325 */
326 int getFirstCoverageStage() const {
rmistry@google.comd6176b02012-08-23 18:14:13 +0000327 return fFirstCoverageStage;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000328 }
329
330 ///@}
331
332 ///////////////////////////////////////////////////////////////////////////
333 /// @name Blending
334 ////
335
336 /**
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000337 * Sets the blending function coefficients.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000338 *
339 * The blend function will be:
340 * D' = sat(S*srcCoef + D*dstCoef)
341 *
342 * where D is the existing destination color, S is the incoming source
343 * color, and D' is the new destination color that will be written. sat()
344 * is the saturation function.
345 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000346 * @param srcCoef coefficient applied to the src color.
347 * @param dstCoef coefficient applied to the dst color.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000348 */
349 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
350 fSrcBlend = srcCoeff;
351 fDstBlend = dstCoeff;
352 #if GR_DEBUG
353 switch (dstCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000354 case kDC_GrBlendCoeff:
355 case kIDC_GrBlendCoeff:
356 case kDA_GrBlendCoeff:
357 case kIDA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000358 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
359 "coverage stages.\n");
360 break;
361 default:
362 break;
363 }
364 switch (srcCoeff) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000365 case kSC_GrBlendCoeff:
366 case kISC_GrBlendCoeff:
367 case kSA_GrBlendCoeff:
368 case kISA_GrBlendCoeff:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000369 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
370 "coverage stages.\n");
371 break;
372 default:
373 break;
374 }
375 #endif
376 }
377
378 GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
379 GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
380
381 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
382 GrBlendCoeff* dstBlendCoeff) const {
383 *srcBlendCoeff = fSrcBlend;
384 *dstBlendCoeff = fDstBlend;
385 }
386
387 /**
388 * Sets the blending function constant referenced by the following blending
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000389 * coefficients:
bsalomon@google.com47059542012-06-06 20:51:20 +0000390 * kConstC_GrBlendCoeff
391 * kIConstC_GrBlendCoeff
392 * kConstA_GrBlendCoeff
393 * kIConstA_GrBlendCoeff
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000394 *
395 * @param constant the constant to set
396 */
397 void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
398
399 /**
400 * Retrieves the last value set by setBlendConstant()
401 * @return the blending constant value
402 */
403 GrColor getBlendConstant() const { return fBlendConstant; }
404
405 /// @}
406
407 ///////////////////////////////////////////////////////////////////////////
408 /// @name View Matrix
409 ////
410
411 /**
robertphillips@google.coma72eef32012-05-01 17:22:59 +0000412 * Sets the matrix applied to vertex positions.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000413 *
414 * In the post-view-matrix space the rectangle [0,w]x[0,h]
415 * fully covers the render target. (w and h are the width and height of the
416 * the rendertarget.)
417 */
418 void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
419
420 /**
421 * Gets a writable pointer to the view matrix.
422 */
423 GrMatrix* viewMatrix() { return &fViewMatrix; }
424
425 /**
426 * Multiplies the current view matrix by a matrix
427 *
428 * After this call V' = V*m where V is the old view matrix,
429 * m is the parameter to this function, and V' is the new view matrix.
430 * (We consider positions to be column vectors so position vector p is
431 * transformed by matrix X as p' = X*p.)
432 *
433 * @param m the matrix used to modify the view matrix.
434 */
435 void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
436
437 /**
438 * Multiplies the current view matrix by a matrix
439 *
440 * After this call V' = m*V where V is the old view matrix,
441 * m is the parameter to this function, and V' is the new view matrix.
442 * (We consider positions to be column vectors so position vector p is
443 * transformed by matrix X as p' = X*p.)
444 *
445 * @param m the matrix used to modify the view matrix.
446 */
447 void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
448
449 /**
450 * Retrieves the current view matrix
451 * @return the current view matrix.
452 */
453 const GrMatrix& getViewMatrix() const { return fViewMatrix; }
454
455 /**
456 * Retrieves the inverse of the current view matrix.
457 *
458 * If the current view matrix is invertible, return true, and if matrix
459 * is non-null, copy the inverse into it. If the current view matrix is
460 * non-invertible, return false and ignore the matrix parameter.
461 *
462 * @param matrix if not null, will receive a copy of the current inverse.
463 */
464 bool getViewInverse(GrMatrix* matrix) const {
465 // TODO: determine whether we really need to leave matrix unmodified
466 // at call sites when inversion fails.
467 GrMatrix inverse;
468 if (fViewMatrix.invert(&inverse)) {
469 if (matrix) {
470 *matrix = inverse;
471 }
472 return true;
473 }
474 return false;
475 }
476
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000477 ////////////////////////////////////////////////////////////////////////////
478
479 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000480 * Preconcats the current view matrix and restores the previous view matrix in the destructor.
bsalomon@google.comc196b522012-10-25 21:52:43 +0000481 * Effect matrices are automatically adjusted to compensate.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000482 */
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000483 class AutoViewMatrixRestore : public ::GrNoncopyable {
484 public:
485 AutoViewMatrixRestore() : fDrawState(NULL) {}
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000486
487 AutoViewMatrixRestore(GrDrawState* ds,
488 const GrMatrix& preconcatMatrix,
489 uint32_t explicitCoordStageMask = 0) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000490 fDrawState = NULL;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000491 this->set(ds, preconcatMatrix, explicitCoordStageMask);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000492 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000493
494 ~AutoViewMatrixRestore() { this->restore(); }
495
bsalomon@google.coma8347462012-10-08 18:59:39 +0000496 /**
497 * Can be called prior to destructor to restore the original matrix.
498 */
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000499 void restore();
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000500
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000501 void set(GrDrawState* drawState,
502 const GrMatrix& preconcatMatrix,
503 uint32_t explicitCoordStageMask = 0);
504
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000505 bool isSet() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000506
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000507 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000508 GrDrawState* fDrawState;
509 GrMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000510 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000511 uint32_t fRestoreMask;
tomhudson@google.com93813632011-10-27 20:21:16 +0000512 };
513
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000514 ////////////////////////////////////////////////////////////////////////////
515
516 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000517 * This sets the view matrix to identity and adjusts stage matrices to compensate. The
518 * destructor undoes the changes, restoring the view matrix that was set before the
519 * constructor. It is similar to passing the inverse of the current view matrix to
520 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000521 */
522 class AutoDeviceCoordDraw : ::GrNoncopyable {
523 public:
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000524 AutoDeviceCoordDraw() : fDrawState(NULL) {}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000525 /**
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000526 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
527 * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
528 * to specify such stages.
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000529 */
530 AutoDeviceCoordDraw(GrDrawState* drawState,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000531 uint32_t explicitCoordStageMask = 0) {
532 fDrawState = NULL;
533 this->set(drawState, explicitCoordStageMask);
534 }
535
bsalomon@google.coma8347462012-10-08 18:59:39 +0000536 ~AutoDeviceCoordDraw() { this->restore(); }
537
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000538 bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
539
bsalomon@google.coma8347462012-10-08 18:59:39 +0000540 /**
541 * Returns true if this object was successfully initialized on to a GrDrawState. It may
542 * return false because a non-default constructor or set() were never called or because
543 * the view matrix was not invertible.
544 */
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000545 bool succeeded() const { return NULL != fDrawState; }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000546
bsalomon@google.coma8347462012-10-08 18:59:39 +0000547 /**
548 * Returns the matrix that was set previously set on the drawState. This is only valid
549 * if succeeded returns true.
550 */
551 const GrMatrix& getOriginalMatrix() const {
552 GrAssert(this->succeeded());
553 return fViewMatrix;
554 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000555
bsalomon@google.coma8347462012-10-08 18:59:39 +0000556 /**
557 * Can be called prior to destructor to restore the original matrix.
558 */
559 void restore();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000560
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000561 private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000562 GrDrawState* fDrawState;
563 GrMatrix fViewMatrix;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000564 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages];
bsalomon@google.com288d9542012-10-17 12:53:54 +0000565 uint32_t fRestoreMask;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000566 };
567
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000568 /// @}
569
570 ///////////////////////////////////////////////////////////////////////////
571 /// @name Render Target
572 ////
573
574 /**
575 * Sets the rendertarget used at the next drawing call
576 *
577 * @param target The render target to set.
578 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000579 void setRenderTarget(GrRenderTarget* target) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000580 GrSafeAssign(fRenderTarget, target);
581 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000582
583 /**
584 * Retrieves the currently set rendertarget.
585 *
586 * @return The currently set render target.
587 */
588 const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
589 GrRenderTarget* getRenderTarget() { return fRenderTarget; }
590
591 class AutoRenderTargetRestore : public ::GrNoncopyable {
592 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000593 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000594 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
595 fDrawState = NULL;
robertphillips@google.com7460b372012-04-25 16:54:51 +0000596 fSavedTarget = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000597 this->set(ds, newTarget);
598 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000599 ~AutoRenderTargetRestore() { this->restore(); }
600
601 void restore() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000602 if (NULL != fDrawState) {
603 fDrawState->setRenderTarget(fSavedTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000604 fDrawState = NULL;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000605 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000606 GrSafeSetNull(fSavedTarget);
607 }
608
609 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
610 this->restore();
611
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000612 if (NULL != ds) {
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000613 GrAssert(NULL == fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000614 fSavedTarget = ds->getRenderTarget();
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000615 SkSafeRef(fSavedTarget);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000616 ds->setRenderTarget(newTarget);
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000617 fDrawState = ds;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000618 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000619 }
620 private:
621 GrDrawState* fDrawState;
622 GrRenderTarget* fSavedTarget;
623 };
624
625 /// @}
626
627 ///////////////////////////////////////////////////////////////////////////
628 /// @name Stencil
629 ////
630
631 /**
632 * Sets the stencil settings to use for the next draw.
633 * Changing the clip has the side-effect of possibly zeroing
634 * out the client settable stencil bits. So multipass algorithms
635 * using stencil should not change the clip between passes.
636 * @param settings the stencil settings to use.
637 */
638 void setStencil(const GrStencilSettings& settings) {
639 fStencilSettings = settings;
640 }
641
642 /**
643 * Shortcut to disable stencil testing and ops.
644 */
645 void disableStencil() {
646 fStencilSettings.setDisabled();
647 }
648
649 const GrStencilSettings& getStencil() const { return fStencilSettings; }
650
651 GrStencilSettings* stencil() { return &fStencilSettings; }
652
653 /// @}
654
655 ///////////////////////////////////////////////////////////////////////////
656 // @name Edge AA
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000657 // Edge equations can be specified to perform anti-aliasing. Because the
bsalomon@google.com7ffe6812012-05-11 17:32:43 +0000658 // edges are specified as per-vertex data, vertices that are shared by
659 // multiple edges must be split.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000660 //
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000661 ////
662
663 /**
tomhudson@google.com93813632011-10-27 20:21:16 +0000664 * When specifying edges as vertex data this enum specifies what type of
665 * edges are in use. The edges are always 4 GrScalars in memory, even when
666 * the edge type requires fewer than 4.
bsalomon@google.com93c96602012-04-27 13:05:21 +0000667 *
668 * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
669 * (either adjust in VS or use origin_upper_left in GLSL)
tomhudson@google.com93813632011-10-27 20:21:16 +0000670 */
671 enum VertexEdgeType {
672 /* 1-pixel wide line
673 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
674 kHairLine_EdgeType,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000675 /* Quadratic specified by u^2-v canonical coords (only 2
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000676 components used). Coverage based on signed distance with negative
bsalomon@google.com93c96602012-04-27 13:05:21 +0000677 being inside, positive outside. Edge specified in window space
678 (y-down) */
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000679 kQuad_EdgeType,
680 /* Same as above but for hairline quadratics. Uses unsigned distance.
681 Coverage is min(0, 1-distance). */
682 kHairQuad_EdgeType,
bsalomon@google.com93c96602012-04-27 13:05:21 +0000683 /* Circle specified as center_x, center_y, outer_radius, inner_radius
684 all in window space (y-down). */
685 kCircle_EdgeType,
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000686
687 kVertexEdgeTypeCnt
tomhudson@google.com93813632011-10-27 20:21:16 +0000688 };
689
690 /**
rmistry@google.comd6176b02012-08-23 18:14:13 +0000691 * Determines the interpretation per-vertex edge data when the
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000692 * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
693 * are not specified the value of this setting has no effect.
694 */
695 void setVertexEdgeType(VertexEdgeType type) {
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000696 GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000697 fVertexEdgeType = type;
698 }
699
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000700 VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000701
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000702 /// @}
tomhudson@google.com62b09682011-11-09 16:39:17 +0000703
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000704 ///////////////////////////////////////////////////////////////////////////
705 /// @name State Flags
706 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000707
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000708 /**
709 * Flags that affect rendering. Controlled using enable/disableState(). All
710 * default to disabled.
711 */
712 enum StateBits {
713 /**
714 * Perform dithering. TODO: Re-evaluate whether we need this bit
715 */
716 kDither_StateBit = 0x01,
717 /**
718 * Perform HW anti-aliasing. This means either HW FSAA, if supported
719 * by the render target, or smooth-line rendering if a line primitive
720 * is drawn and line smoothing is supported by the 3D API.
721 */
722 kHWAntialias_StateBit = 0x02,
723 /**
724 * Draws will respect the clip, otherwise the clip is ignored.
725 */
726 kClip_StateBit = 0x04,
727 /**
728 * Disables writing to the color buffer. Useful when performing stencil
729 * operations.
730 */
731 kNoColorWrites_StateBit = 0x08,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000732
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000733 // Users of the class may add additional bits to the vector
734 kDummyStateBit,
735 kLastPublicStateBit = kDummyStateBit-1,
736 };
737
738 void resetStateFlags() {
739 fFlagBits = 0;
740 }
741
742 /**
743 * Enable render state settings.
744 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000745 * @param stateBits bitfield of StateBits specifying the states to enable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000746 */
747 void enableState(uint32_t stateBits) {
748 fFlagBits |= stateBits;
749 }
750
751 /**
752 * Disable render state settings.
753 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000754 * @param stateBits bitfield of StateBits specifying the states to disable
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000755 */
756 void disableState(uint32_t stateBits) {
757 fFlagBits &= ~(stateBits);
758 }
759
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000760 /**
761 * Enable or disable stateBits based on a boolean.
762 *
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000763 * @param stateBits bitfield of StateBits to enable or disable
bsalomon@google.comd5d69ff2012-10-04 19:42:00 +0000764 * @param enable if true enable stateBits, otherwise disable
765 */
766 void setState(uint32_t stateBits, bool enable) {
767 if (enable) {
768 this->enableState(stateBits);
769 } else {
770 this->disableState(stateBits);
771 }
772 }
773
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000774 bool isDitherState() const {
775 return 0 != (fFlagBits & kDither_StateBit);
776 }
777
778 bool isHWAntialiasState() const {
779 return 0 != (fFlagBits & kHWAntialias_StateBit);
780 }
781
782 bool isClipState() const {
783 return 0 != (fFlagBits & kClip_StateBit);
784 }
785
786 bool isColorWriteDisabled() const {
787 return 0 != (fFlagBits & kNoColorWrites_StateBit);
788 }
789
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000790 bool isStateFlagEnabled(uint32_t stateBit) const {
791 return 0 != (stateBit & fFlagBits);
792 }
793
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000794 /// @}
795
796 ///////////////////////////////////////////////////////////////////////////
797 /// @name Face Culling
798 ////
799
800 enum DrawFace {
bsalomon@google.com978c8c62012-05-21 14:45:49 +0000801 kInvalid_DrawFace = -1,
802
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000803 kBoth_DrawFace,
804 kCCW_DrawFace,
805 kCW_DrawFace,
806 };
807
808 /**
809 * Controls whether clockwise, counterclockwise, or both faces are drawn.
810 * @param face the face(s) to draw.
811 */
812 void setDrawFace(DrawFace face) {
bsalomon@google.com978c8c62012-05-21 14:45:49 +0000813 GrAssert(kInvalid_DrawFace != face);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000814 fDrawFace = face;
815 }
816
817 /**
818 * Gets whether the target is drawing clockwise, counterclockwise,
819 * or both faces.
820 * @return the current draw face(s).
821 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000822 DrawFace getDrawFace() const { return fDrawFace; }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000823
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000824 /// @}
825
826 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000827
tomhudson@google.comf13f5882012-06-25 17:27:28 +0000828 bool isStageEnabled(int s) const {
829 GrAssert((unsigned)s < kNumStages);
bsalomon@google.com08283af2012-10-26 13:01:20 +0000830 return (NULL != fStages[s].getEffect());
tomhudson@google.comf13f5882012-06-25 17:27:28 +0000831 }
832
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000833 // Most stages are usually not used, so conditionals here
834 // reduce the expected number of bytes touched by 50%.
835 bool operator ==(const GrDrawState& s) const {
bsalomon@google.com861b3a22012-09-26 17:28:25 +0000836 if (fColor != s.fColor ||
837 !s.fViewMatrix.cheapEqualTo(fViewMatrix) ||
838 fRenderTarget != s.fRenderTarget ||
839 fSrcBlend != s.fSrcBlend ||
840 fDstBlend != s.fDstBlend ||
841 fBlendConstant != s.fBlendConstant ||
842 fFlagBits != s.fFlagBits ||
843 fVertexEdgeType != s.fVertexEdgeType ||
844 fStencilSettings != s.fStencilSettings ||
845 fFirstCoverageStage != s.fFirstCoverageStage ||
846 fCoverage != s.fCoverage ||
847 fColorFilterMode != s.fColorFilterMode ||
848 fColorFilterColor != s.fColorFilterColor ||
849 fDrawFace != s.fDrawFace) {
bsalomon@google.com8fe84b52012-03-26 15:24:27 +0000850 return false;
851 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000852
853 for (int i = 0; i < kNumStages; i++) {
bsalomon@google.comf2f8fc32012-07-18 18:25:07 +0000854 bool enabled = this->isStageEnabled(i);
855 if (enabled != s.isStageEnabled(i)) {
856 return false;
857 }
bsalomon@google.com08283af2012-10-26 13:01:20 +0000858 if (enabled && this->fStages[i] != s.fStages[i]) {
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000859 return false;
860 }
861 }
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000862 return true;
863 }
864 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
865
rmistry@google.comd6176b02012-08-23 18:14:13 +0000866 // Most stages are usually not used, so conditionals here
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000867 // reduce the expected number of bytes touched by 50%.
868 GrDrawState& operator =(const GrDrawState& s) {
bsalomon@google.com861b3a22012-09-26 17:28:25 +0000869 fColor = s.fColor;
bsalomon@google.com8fe84b52012-03-26 15:24:27 +0000870 fViewMatrix = s.fViewMatrix;
bsalomon@google.com861b3a22012-09-26 17:28:25 +0000871 SkRefCnt_SafeAssign(fRenderTarget, s.fRenderTarget);
872 fSrcBlend = s.fSrcBlend;
873 fDstBlend = s.fDstBlend;
874 fBlendConstant = s.fBlendConstant;
875 fFlagBits = s.fFlagBits;
876 fVertexEdgeType = s.fVertexEdgeType;
877 fStencilSettings = s.fStencilSettings;
878 fFirstCoverageStage = s.fFirstCoverageStage;
879 fCoverage = s.fCoverage;
880 fColorFilterMode = s.fColorFilterMode;
881 fColorFilterColor = s.fColorFilterColor;
882 fDrawFace = s.fDrawFace;
bsalomon@google.com8fe84b52012-03-26 15:24:27 +0000883
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000884 for (int i = 0; i < kNumStages; i++) {
tomhudson@google.come742bf02012-07-13 19:54:19 +0000885 if (s.isStageEnabled(i)) {
bsalomon@google.com08283af2012-10-26 13:01:20 +0000886 this->fStages[i] = s.fStages[i];
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000887 }
888 }
robertphillips@google.com9ec07532012-06-22 12:01:30 +0000889
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000890 return *this;
891 }
892
893private:
bsalomon@google.com2e3d1442012-03-26 20:33:54 +0000894
bsalomon@google.com1e269b52012-10-15 14:25:31 +0000895 // These fields are roughly sorted by decreasing likelihood of being different in op==
bsalomon@google.com861b3a22012-09-26 17:28:25 +0000896 GrColor fColor;
897 GrMatrix fViewMatrix;
898 GrRenderTarget* fRenderTarget;
899 GrBlendCoeff fSrcBlend;
900 GrBlendCoeff fDstBlend;
901 GrColor fBlendConstant;
902 uint32_t fFlagBits;
robertphillips@google.comc077d1e2012-05-28 14:10:15 +0000903 VertexEdgeType fVertexEdgeType;
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000904 GrStencilSettings fStencilSettings;
robertphillips@google.com69ffcf02012-06-26 21:01:05 +0000905 int fFirstCoverageStage;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000906 GrColor fCoverage;
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000907 SkXfermode::Mode fColorFilterMode;
bsalomon@google.com861b3a22012-09-26 17:28:25 +0000908 GrColor fColorFilterColor;
909 DrawFace fDrawFace;
bsalomon@google.com8fe84b52012-03-26 15:24:27 +0000910
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000911 // This field must be last; it will not be copied or compared
912 // if the corresponding fTexture[] is NULL.
bsalomon@google.com08283af2012-10-26 13:01:20 +0000913 GrEffectStage fStages[kNumStages];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000914
reed@google.comfa35e3d2012-06-26 20:16:17 +0000915 typedef GrRefCnt INHERITED;
tomhudson@google.com93813632011-10-27 20:21:16 +0000916};
917
918#endif