• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
11 #include "GrBackendEffectFactory.h"
12 #include "GrColor.h"
13 #include "GrEffectStage.h"
14 #include "GrRefCnt.h"
15 #include "GrRenderTarget.h"
16 #include "GrStencil.h"
17 #include "GrTemplates.h"
18 #include "GrTexture.h"
19 #include "effects/GrSimpleTextureEffect.h"
20 
21 #include "SkMatrix.h"
22 #include "SkXfermode.h"
23 
24 class GrPaint;
25 
26 class GrDrawState : public GrRefCnt {
27 public:
28     SK_DECLARE_INST_COUNT(GrDrawState)
29 
30     /**
31      * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
32      * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
33      * output from the previous enabled stage and a position. The position is either derived from
34      * the interpolated vertex positions or explicit per-vertex coords, depending upon the
35      * GrVertexLayout used to draw.
36      *
37      * The stages are divided into two sets, color-computing and coverage-computing. The final color
38      * stage produces the final pixel color. The coverage-computing stages function exactly as the
39      * color-computing but the output of the final coverage stage is treated as a fractional pixel
40      * coverage rather than as input to the src/dst color blend step.
41      *
42      * The input color to the first enabled color-stage is either the constant color or interpolated
43      * per-vertex colors, depending upon GrVertexLayout. The input to the first coverage stage is
44      * either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or
45      * edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a
46      * GrEffect).
47      *
48      * See the documentation of kCoverageDrawing_StateBit for information about disabling the
49      * the color / coverage distinction.
50      *
51      * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
52      * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
53      * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
54      * by GrClipMaskManager.
55      */
56     enum {
57         kNumStages = 5,
58         kMaxTexCoords = kNumStages
59     };
60 
GrDrawState()61     GrDrawState() {
62 #if GR_DEBUG
63         VertexLayoutUnitTest();
64 #endif
65         this->reset();
66     }
67 
GrDrawState(const GrDrawState & state)68     GrDrawState(const GrDrawState& state) {
69         *this = state;
70     }
71 
~GrDrawState()72     virtual ~GrDrawState() {
73         this->disableStages();
74     }
75 
76     /**
77      * Resets to the default state.
78      * GrEffects will be removed from all stages.
79      */
reset()80     void reset() {
81 
82         this->disableStages();
83 
84         fRenderTarget.reset(NULL);
85 
86         fCommon.fColor = 0xffffffff;
87         fCommon.fViewMatrix.reset();
88         fCommon.fSrcBlend = kOne_GrBlendCoeff;
89         fCommon.fDstBlend = kZero_GrBlendCoeff;
90         fCommon.fBlendConstant = 0x0;
91         fCommon.fFlagBits = 0x0;
92         fCommon.fVertexEdgeType = kHairLine_EdgeType;
93         fCommon.fStencilSettings.setDisabled();
94         fCommon.fFirstCoverageStage = kNumStages;
95         fCommon.fCoverage = 0xffffffff;
96         fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
97         fCommon.fColorFilterColor = 0x0;
98         fCommon.fDrawFace = kBoth_DrawFace;
99     }
100 
101     /**
102      * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
103      * encompasses more than GrPaint. Aspects of GrDrawState that have no
104      * GrPaint equivalents are not modified. GrPaint has fewer stages than
105      * GrDrawState. The extra GrDrawState stages are disabled.
106      */
107     void setFromPaint(const GrPaint& paint);
108 
109     ///////////////////////////////////////////////////////////////////////////
110     /// @name Vertex Format
111     ////
112 
113     /**
114      * The format of vertices is represented as a bitfield of flags.
115      * Flags that indicate the layout of vertex data. Vertices always contain
116      * positions and may also contain up to GrDrawState::kMaxTexCoords sets
117      * of 2D texture coordinates, per-vertex colors, and per-vertex coverage.
118      * Each stage can
119      * use any of the texture coordinates as its input texture coordinates or it
120      * may use the positions as texture coordinates.
121      *
122      * If no texture coordinates are specified for a stage then the stage is
123      * disabled.
124      *
125      * Only one type of texture coord can be specified per stage. For
126      * example StageTexCoordVertexLayoutBit(0, 2) and
127      * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
128      *
129      * The order in memory is always (position, texture coord 0, ..., color,
130      * coverage) with any unused fields omitted. Note that this means that if
131      * only texture coordinates 1 is referenced then there is no texture
132      * coordinates 0 and the order would be (position, texture coordinate 1
133      * [, color][, coverage]).
134      */
135 
136     /**
137      * Generates a bit indicating that a texture stage uses texture coordinates
138      *
139      * @param stageIdx    the stage that will use texture coordinates.
140      * @param texCoordIdx the index of the texture coordinates to use
141      *
142      * @return the bit to add to a GrVertexLayout bitfield.
143      */
StageTexCoordVertexLayoutBit(int stageIdx,int texCoordIdx)144     static int StageTexCoordVertexLayoutBit(int stageIdx, int texCoordIdx) {
145         GrAssert(stageIdx < kNumStages);
146         GrAssert(texCoordIdx < kMaxTexCoords);
147         return 1 << (stageIdx + (texCoordIdx * kNumStages));
148     }
149 
150     static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
151 
152 private:
153     // non-stage bits start at this index.
154     static const int STAGE_BIT_CNT = kNumStages * kMaxTexCoords;
155 public:
156 
157     /**
158      * Additional Bits that can be specified in GrVertexLayout.
159      */
160     enum VertexLayoutBits {
161         /* vertices have colors (GrColor) */
162         kColor_VertexLayoutBit              = 1 << (STAGE_BIT_CNT + 0),
163         /* vertices have coverage (GrColor)
164          */
165         kCoverage_VertexLayoutBit           = 1 << (STAGE_BIT_CNT + 1),
166         /* Use text vertices. (Pos and tex coords may be a different type for
167          * text [GrGpuTextVertex vs GrPoint].)
168          */
169         kTextFormat_VertexLayoutBit         = 1 << (STAGE_BIT_CNT + 2),
170 
171         /* Each vertex specificies an edge. Distance to the edge is used to
172          * compute a coverage. See GrDrawState::setVertexEdgeType().
173          */
174         kEdge_VertexLayoutBit               = 1 << (STAGE_BIT_CNT + 3),
175         // for below assert
176         kDummyVertexLayoutBit,
177         kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
178     };
179     // make sure we haven't exceeded the number of bits in GrVertexLayout.
180     GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
181 
182     ////////////////////////////////////////////////////////////////////////////
183     // Helpers for picking apart vertex layouts
184 
185     /**
186      * Helper function to compute the size of a vertex from a vertex layout
187      * @return size of a single vertex.
188      */
189     static size_t VertexSize(GrVertexLayout vertexLayout);
190 
191     /**
192      * Helper function for determining the index of texture coordinates that
193      * is input for a texture stage. Note that a stage may instead use positions
194      * as texture coordinates, in which case the result of the function is
195      * indistinguishable from the case when the stage is disabled.
196      *
197      * @param stageIdx      the stage to query
198      * @param vertexLayout  layout to query
199      *
200      * @return the texture coordinate index or -1 if the stage doesn't use
201      *         separate (non-position) texture coordinates.
202      */
203     static int VertexTexCoordsForStage(int stageIdx, GrVertexLayout vertexLayout);
204 
205     /**
206      * Helper function to compute the offset of texture coordinates in a vertex
207      * @return offset of texture coordinates in vertex layout or -1 if the
208      *         layout has no texture coordinates. Will be 0 if positions are
209      *         used as texture coordinates for the stage.
210      */
211     static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
212 
213     /**
214      * Helper function to compute the offset of the color in a vertex
215      * @return offset of color in vertex layout or -1 if the
216      *         layout has no color.
217      */
218     static int VertexColorOffset(GrVertexLayout vertexLayout);
219 
220     /**
221      * Helper function to compute the offset of the coverage in a vertex
222      * @return offset of coverage in vertex layout or -1 if the
223      *         layout has no coverage.
224      */
225     static int VertexCoverageOffset(GrVertexLayout vertexLayout);
226 
227      /**
228       * Helper function to compute the offset of the edge pts in a vertex
229       * @return offset of edge in vertex layout or -1 if the
230       *         layout has no edge.
231       */
232      static int VertexEdgeOffset(GrVertexLayout vertexLayout);
233 
234     /**
235      * Helper function to determine if vertex layout contains explicit texture
236      * coordinates of some index.
237      *
238      * @param coordIndex    the tex coord index to query
239      * @param vertexLayout  layout to query
240      *
241      * @return true if vertex specifies texture coordinates for the index,
242      *              false otherwise.
243      */
244     static bool VertexUsesTexCoordIdx(int coordIndex,
245                                       GrVertexLayout vertexLayout);
246 
247     /**
248      * Helper function to compute the size of each vertex and the offsets of
249      * texture coordinates and color. Determines tex coord offsets by tex coord
250      * index rather than by stage. (Each stage can be mapped to any t.c. index
251      * by StageTexCoordVertexLayoutBit.)
252      *
253      * @param vertexLayout          the layout to query
254      * @param texCoordOffsetsByIdx  after return it is the offset of each
255      *                              tex coord index in the vertex or -1 if
256      *                              index isn't used. (optional)
257      * @param colorOffset           after return it is the offset of the
258      *                              color field in each vertex, or -1 if
259      *                              there aren't per-vertex colors. (optional)
260      * @param coverageOffset        after return it is the offset of the
261      *                              coverage field in each vertex, or -1 if
262      *                              there aren't per-vertex coeverages.
263      *                              (optional)
264      * @param edgeOffset            after return it is the offset of the
265      *                              edge eq field in each vertex, or -1 if
266      *                              there aren't per-vertex edge equations.
267      *                              (optional)
268      * @return size of a single vertex
269      */
270     static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
271                    int texCoordOffsetsByIdx[kMaxTexCoords],
272                    int *colorOffset,
273                    int *coverageOffset,
274                    int* edgeOffset);
275 
276     /**
277      * Helper function to compute the size of each vertex and the offsets of
278      * texture coordinates and color. Determines tex coord offsets by stage
279      * rather than by index. (Each stage can be mapped to any t.c. index
280      * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
281      * tex coords then that stage's offset will be 0 (positions are always at 0).
282      *
283      * @param vertexLayout              the layout to query
284      * @param texCoordOffsetsByStage    after return it is the offset of each
285      *                                  tex coord index in the vertex or -1 if
286      *                                  index isn't used. (optional)
287      * @param colorOffset               after return it is the offset of the
288      *                                  color field in each vertex, or -1 if
289      *                                  there aren't per-vertex colors.
290      *                                  (optional)
291      * @param coverageOffset            after return it is the offset of the
292      *                                  coverage field in each vertex, or -1 if
293      *                                  there aren't per-vertex coeverages.
294      *                                  (optional)
295      * @param edgeOffset                after return it is the offset of the
296      *                                  edge eq field in each vertex, or -1 if
297      *                                  there aren't per-vertex edge equations.
298      *                                  (optional)
299      * @return size of a single vertex
300      */
301     static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
302                    int texCoordOffsetsByStage[kNumStages],
303                    int* colorOffset,
304                    int* coverageOffset,
305                    int* edgeOffset);
306 
307     /**
308      * Determines whether src alpha is guaranteed to be one for all src pixels
309      */
310     bool srcAlphaWillBeOne(GrVertexLayout) const;
311 
312     /**
313      * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
314      */
315     bool hasSolidCoverage(GrVertexLayout) const;
316 
317     /**
318      * Accessing positions, texture coords, or colors, of a vertex within an
319      * array is a hassle involving casts and simple math. These helpers exist
320      * to keep GrDrawTarget clients' code a bit nicer looking.
321      */
322 
323     /**
324      * Gets a pointer to a GrPoint of a vertex's position or texture
325      * coordinate.
326      * @param vertices      the vetex array
327      * @param vertexIndex   the index of the vertex in the array
328      * @param vertexSize    the size of each vertex in the array
329      * @param offset        the offset in bytes of the vertex component.
330      *                      Defaults to zero (corresponding to vertex position)
331      * @return pointer to the vertex component as a GrPoint
332      */
333     static GrPoint* GetVertexPoint(void* vertices,
334                                    int vertexIndex,
335                                    int vertexSize,
336                                    int offset = 0) {
337         intptr_t start = GrTCast<intptr_t>(vertices);
338         return GrTCast<GrPoint*>(start + offset +
339                                  vertexIndex * vertexSize);
340     }
341     static const GrPoint* GetVertexPoint(const void* vertices,
342                                          int vertexIndex,
343                                          int vertexSize,
344                                          int offset = 0) {
345         intptr_t start = GrTCast<intptr_t>(vertices);
346         return GrTCast<const GrPoint*>(start + offset +
347                                        vertexIndex * vertexSize);
348     }
349 
350     /**
351      * Gets a pointer to a GrColor inside a vertex within a vertex array.
352      * @param vertices      the vetex array
353      * @param vertexIndex   the index of the vertex in the array
354      * @param vertexSize    the size of each vertex in the array
355      * @param offset        the offset in bytes of the vertex color
356      * @return pointer to the vertex component as a GrColor
357      */
GetVertexColor(void * vertices,int vertexIndex,int vertexSize,int offset)358     static GrColor* GetVertexColor(void* vertices,
359                                    int vertexIndex,
360                                    int vertexSize,
361                                    int offset) {
362         intptr_t start = GrTCast<intptr_t>(vertices);
363         return GrTCast<GrColor*>(start + offset +
364                                  vertexIndex * vertexSize);
365     }
GetVertexColor(const void * vertices,int vertexIndex,int vertexSize,int offset)366     static const GrColor* GetVertexColor(const void* vertices,
367                                          int vertexIndex,
368                                          int vertexSize,
369                                          int offset) {
370         const intptr_t start = GrTCast<intptr_t>(vertices);
371         return GrTCast<const GrColor*>(start + offset +
372                                        vertexIndex * vertexSize);
373     }
374 
375     static void VertexLayoutUnitTest();
376 
377     /// @}
378 
379     ///////////////////////////////////////////////////////////////////////////
380     /// @name Color
381     ////
382 
383     /**
384      *  Sets color for next draw to a premultiplied-alpha color.
385      *
386      *  @param color    the color to set.
387      */
setColor(GrColor color)388     void setColor(GrColor color) { fCommon.fColor = color; }
389 
getColor()390     GrColor getColor() const { return fCommon.fColor; }
391 
392     /**
393      *  Sets the color to be used for the next draw to be
394      *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
395      *
396      *  @param alpha The alpha value to set as the color.
397      */
setAlpha(uint8_t a)398     void setAlpha(uint8_t a) {
399         this->setColor((a << 24) | (a << 16) | (a << 8) | a);
400     }
401 
402     /**
403      * Add a color filter that can be represented by a color and a mode. Applied
404      * after color-computing texture stages.
405      */
setColorFilter(GrColor c,SkXfermode::Mode mode)406     void setColorFilter(GrColor c, SkXfermode::Mode mode) {
407         fCommon.fColorFilterColor = c;
408         fCommon.fColorFilterMode = mode;
409     }
410 
getColorFilterColor()411     GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
getColorFilterMode()412     SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
413 
414     /**
415      * Constructor sets the color to be 'color' which is undone by the destructor.
416      */
417     class AutoColorRestore : public ::GrNoncopyable {
418     public:
AutoColorRestore()419         AutoColorRestore() : fDrawState(NULL) {}
420 
AutoColorRestore(GrDrawState * drawState,GrColor color)421         AutoColorRestore(GrDrawState* drawState, GrColor color) {
422             fDrawState = NULL;
423             this->set(drawState, color);
424         }
425 
reset()426         void reset() {
427             if (NULL != fDrawState) {
428                 fDrawState->setColor(fOldColor);
429                 fDrawState = NULL;
430             }
431         }
432 
set(GrDrawState * drawState,GrColor color)433         void set(GrDrawState* drawState, GrColor color) {
434             this->reset();
435             fDrawState = drawState;
436             fOldColor = fDrawState->getColor();
437             fDrawState->setColor(color);
438         }
439 
~AutoColorRestore()440         ~AutoColorRestore() { this->reset(); }
441     private:
442         GrDrawState*    fDrawState;
443         GrColor         fOldColor;
444     };
445 
446     /// @}
447 
448     ///////////////////////////////////////////////////////////////////////////
449     /// @name Coverage
450     ////
451 
452     /**
453      * Sets a constant fractional coverage to be applied to the draw. The
454      * initial value (after construction or reset()) is 0xff. The constant
455      * coverage is ignored when per-vertex coverage is provided.
456      */
setCoverage(uint8_t coverage)457     void setCoverage(uint8_t coverage) {
458         fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
459     }
460 
461     /**
462      * Version of above that specifies 4 channel per-vertex color. The value
463      * should be premultiplied.
464      */
setCoverage4(GrColor coverage)465     void setCoverage4(GrColor coverage) {
466         fCommon.fCoverage = coverage;
467     }
468 
getCoverage()469     GrColor getCoverage() const {
470         return fCommon.fCoverage;
471     }
472 
473     /// @}
474 
475     ///////////////////////////////////////////////////////////////////////////
476     /// @name Effect Stages
477     ////
478 
setEffect(int stageIdx,const GrEffectRef * effect)479     const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
480         fStages[stageIdx].setEffect(effect);
481         return effect;
482     }
483 
484     /**
485      * Creates a GrSimpleTextureEffect.
486      */
createTextureEffect(int stageIdx,GrTexture * texture,const SkMatrix & matrix)487     void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
488         GrAssert(!this->getStage(stageIdx).getEffect());
489         GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
490         this->setEffect(stageIdx, effect)->unref();
491     }
createTextureEffect(int stageIdx,GrTexture * texture,const SkMatrix & matrix,const GrTextureParams & params)492     void createTextureEffect(int stageIdx,
493                              GrTexture* texture,
494                              const SkMatrix& matrix,
495                              const GrTextureParams& params) {
496         GrAssert(!this->getStage(stageIdx).getEffect());
497         GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
498         this->setEffect(stageIdx, effect)->unref();
499     }
500 
stagesDisabled()501     bool stagesDisabled() {
502         for (int i = 0; i < kNumStages; ++i) {
503             if (NULL != fStages[i].getEffect()) {
504                 return false;
505             }
506         }
507         return true;
508     }
509 
disableStage(int stageIdx)510     void disableStage(int stageIdx) { this->setEffect(stageIdx, NULL); }
511 
512     /**
513      * Release all the GrEffects referred to by this draw state.
514      */
disableStages()515     void disableStages() {
516         for (int i = 0; i < kNumStages; ++i) {
517             this->disableStage(i);
518         }
519     }
520 
521     class AutoStageDisable : public ::GrNoncopyable {
522     public:
AutoStageDisable(GrDrawState * ds)523         AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
~AutoStageDisable()524         ~AutoStageDisable() {
525             if (NULL != fDrawState) {
526                 fDrawState->disableStages();
527             }
528         }
529     private:
530         GrDrawState* fDrawState;
531     };
532 
533     /**
534      * Returns the current stage by index.
535      */
getStage(int stageIdx)536     const GrEffectStage& getStage(int stageIdx) const {
537         GrAssert((unsigned)stageIdx < kNumStages);
538         return fStages[stageIdx];
539     }
540 
541     /**
542      * Called when the source coord system is changing. preConcat gives the transformation from the
543      * old coord system to the new coord system.
544      */
preConcatStageMatrices(const SkMatrix & preConcat)545     void preConcatStageMatrices(const SkMatrix& preConcat) {
546         this->preConcatStageMatrices(~0U, preConcat);
547     }
548     /**
549      * Version of above that applies the update matrix selectively to stages via a mask.
550      */
preConcatStageMatrices(uint32_t stageMask,const SkMatrix & preConcat)551     void preConcatStageMatrices(uint32_t stageMask, const SkMatrix& preConcat) {
552         for (int i = 0; i < kNumStages; ++i) {
553             if (((1 << i) & stageMask) && this->isStageEnabled(i)) {
554                 fStages[i].preConcatCoordChange(preConcat);
555             }
556         }
557     }
558 
559     /**
560      * Called when the source coord system is changing. preConcatInverse is the inverse of the
561      * transformation from the old coord system to the new coord system. Returns false if the matrix
562      * cannot be inverted.
563      */
preConcatStageMatricesWithInverse(const SkMatrix & preConcatInverse)564     bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) {
565         SkMatrix inv;
566         bool computed = false;
567         for (int i = 0; i < kNumStages; ++i) {
568             if (this->isStageEnabled(i)) {
569                 if (!computed && !preConcatInverse.invert(&inv)) {
570                     return false;
571                 } else {
572                     computed = true;
573                 }
574                 fStages[i].preConcatCoordChange(preConcatInverse);
575             }
576         }
577         return true;
578     }
579 
580     /// @}
581 
582     ///////////////////////////////////////////////////////////////////////////
583     /// @name Coverage / Color Stages
584     ////
585 
586     /**
587      * A common pattern is to compute a color with the initial stages and then
588      * modulate that color by a coverage value in later stage(s) (AA, mask-
589      * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
590      * computed based on the pre-coverage-modulated color. The division of
591      * stages between color-computing and coverage-computing is specified by
592      * this method. Initially this is kNumStages (all stages
593      * are color-computing).
594      */
setFirstCoverageStage(int firstCoverageStage)595     void setFirstCoverageStage(int firstCoverageStage) {
596         GrAssert((unsigned)firstCoverageStage <= kNumStages);
597         fCommon.fFirstCoverageStage = firstCoverageStage;
598     }
599 
600     /**
601      * Gets the index of the first coverage-computing stage.
602      */
getFirstCoverageStage()603     int getFirstCoverageStage() const {
604         return fCommon.fFirstCoverageStage;
605     }
606 
607     ///@}
608 
609     ///////////////////////////////////////////////////////////////////////////
610     /// @name Blending
611     ////
612 
613     /**
614      * Sets the blending function coefficients.
615      *
616      * The blend function will be:
617      *    D' = sat(S*srcCoef + D*dstCoef)
618      *
619      *   where D is the existing destination color, S is the incoming source
620      *   color, and D' is the new destination color that will be written. sat()
621      *   is the saturation function.
622      *
623      * @param srcCoef coefficient applied to the src color.
624      * @param dstCoef coefficient applied to the dst color.
625      */
setBlendFunc(GrBlendCoeff srcCoeff,GrBlendCoeff dstCoeff)626     void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
627         fCommon.fSrcBlend = srcCoeff;
628         fCommon.fDstBlend = dstCoeff;
629     #if GR_DEBUG
630         switch (dstCoeff) {
631         case kDC_GrBlendCoeff:
632         case kIDC_GrBlendCoeff:
633         case kDA_GrBlendCoeff:
634         case kIDA_GrBlendCoeff:
635             GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
636                      "coverage stages.\n");
637             break;
638         default:
639             break;
640         }
641         switch (srcCoeff) {
642         case kSC_GrBlendCoeff:
643         case kISC_GrBlendCoeff:
644         case kSA_GrBlendCoeff:
645         case kISA_GrBlendCoeff:
646             GrPrintf("Unexpected src blend coeff. Won't work correctly with"
647                      "coverage stages.\n");
648             break;
649         default:
650             break;
651         }
652     #endif
653     }
654 
getSrcBlendCoeff()655     GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
getDstBlendCoeff()656     GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
657 
getDstBlendCoeff(GrBlendCoeff * srcBlendCoeff,GrBlendCoeff * dstBlendCoeff)658     void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
659                           GrBlendCoeff* dstBlendCoeff) const {
660         *srcBlendCoeff = fCommon.fSrcBlend;
661         *dstBlendCoeff = fCommon.fDstBlend;
662     }
663 
664     /**
665      * Sets the blending function constant referenced by the following blending
666      * coefficients:
667      *      kConstC_GrBlendCoeff
668      *      kIConstC_GrBlendCoeff
669      *      kConstA_GrBlendCoeff
670      *      kIConstA_GrBlendCoeff
671      *
672      * @param constant the constant to set
673      */
setBlendConstant(GrColor constant)674     void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
675 
676     /**
677      * Retrieves the last value set by setBlendConstant()
678      * @return the blending constant value
679      */
getBlendConstant()680     GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
681 
682     /// @}
683 
684     ///////////////////////////////////////////////////////////////////////////
685     /// @name View Matrix
686     ////
687 
688     /**
689      * Sets the matrix applied to vertex positions.
690      *
691      * In the post-view-matrix space the rectangle [0,w]x[0,h]
692      * fully covers the render target. (w and h are the width and height of the
693      * the render-target.)
694      */
setViewMatrix(const SkMatrix & m)695     void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
696 
697     /**
698      * Gets a writable pointer to the view matrix.
699      */
viewMatrix()700     SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
701 
702     /**
703      *  Multiplies the current view matrix by a matrix
704      *
705      *  After this call V' = V*m where V is the old view matrix,
706      *  m is the parameter to this function, and V' is the new view matrix.
707      *  (We consider positions to be column vectors so position vector p is
708      *  transformed by matrix X as p' = X*p.)
709      *
710      *  @param m the matrix used to modify the view matrix.
711      */
preConcatViewMatrix(const SkMatrix & m)712     void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
713 
714     /**
715      *  Multiplies the current view matrix by a matrix
716      *
717      *  After this call V' = m*V where V is the old view matrix,
718      *  m is the parameter to this function, and V' is the new view matrix.
719      *  (We consider positions to be column vectors so position vector p is
720      *  transformed by matrix X as p' = X*p.)
721      *
722      *  @param m the matrix used to modify the view matrix.
723      */
postConcatViewMatrix(const SkMatrix & m)724     void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
725 
726     /**
727      * Retrieves the current view matrix
728      * @return the current view matrix.
729      */
getViewMatrix()730     const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
731 
732     /**
733      *  Retrieves the inverse of the current view matrix.
734      *
735      *  If the current view matrix is invertible, return true, and if matrix
736      *  is non-null, copy the inverse into it. If the current view matrix is
737      *  non-invertible, return false and ignore the matrix parameter.
738      *
739      * @param matrix if not null, will receive a copy of the current inverse.
740      */
getViewInverse(SkMatrix * matrix)741     bool getViewInverse(SkMatrix* matrix) const {
742         // TODO: determine whether we really need to leave matrix unmodified
743         // at call sites when inversion fails.
744         SkMatrix inverse;
745         if (fCommon.fViewMatrix.invert(&inverse)) {
746             if (matrix) {
747                 *matrix = inverse;
748             }
749             return true;
750         }
751         return false;
752     }
753 
754     ////////////////////////////////////////////////////////////////////////////
755 
756     /**
757      * Preconcats the current view matrix and restores the previous view matrix in the destructor.
758      * Effect matrices are automatically adjusted to compensate.
759      */
760     class AutoViewMatrixRestore : public ::GrNoncopyable {
761     public:
AutoViewMatrixRestore()762         AutoViewMatrixRestore() : fDrawState(NULL) {}
763 
764         AutoViewMatrixRestore(GrDrawState* ds,
765                               const SkMatrix& preconcatMatrix,
766                               uint32_t explicitCoordStageMask = 0) {
767             fDrawState = NULL;
768             this->set(ds, preconcatMatrix, explicitCoordStageMask);
769         }
770 
~AutoViewMatrixRestore()771         ~AutoViewMatrixRestore() { this->restore(); }
772 
773         /**
774          * Can be called prior to destructor to restore the original matrix.
775          */
776         void restore();
777 
778         void set(GrDrawState* drawState,
779                  const SkMatrix& preconcatMatrix,
780                  uint32_t explicitCoordStageMask = 0);
781 
isSet()782         bool isSet() const { return NULL != fDrawState; }
783 
784     private:
785         GrDrawState*                        fDrawState;
786         SkMatrix                            fViewMatrix;
787         GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
788         uint32_t                            fRestoreMask;
789     };
790 
791     ////////////////////////////////////////////////////////////////////////////
792 
793     /**
794      * This sets the view matrix to identity and adjusts stage matrices to compensate. The
795      * destructor undoes the changes, restoring the view matrix that was set before the
796      * constructor. It is similar to passing the inverse of the current view matrix to
797      * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
798      */
799     class AutoDeviceCoordDraw : ::GrNoncopyable {
800     public:
AutoDeviceCoordDraw()801         AutoDeviceCoordDraw() : fDrawState(NULL) {}
802         /**
803          * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
804          * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
805          * to specify such stages.
806          */
807         AutoDeviceCoordDraw(GrDrawState* drawState,
808                             uint32_t explicitCoordStageMask = 0) {
809             fDrawState = NULL;
810             this->set(drawState, explicitCoordStageMask);
811         }
812 
~AutoDeviceCoordDraw()813         ~AutoDeviceCoordDraw() { this->restore(); }
814 
815         bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
816 
817         /**
818          * Returns true if this object was successfully initialized on to a GrDrawState. It may
819          * return false because a non-default constructor or set() were never called or because
820          * the view matrix was not invertible.
821          */
succeeded()822         bool succeeded() const { return NULL != fDrawState; }
823 
824         /**
825          * Returns the matrix that was set previously set on the drawState. This is only valid
826          * if succeeded returns true.
827          */
getOriginalMatrix()828         const SkMatrix& getOriginalMatrix() const {
829             GrAssert(this->succeeded());
830             return fViewMatrix;
831         }
832 
833         /**
834          * Can be called prior to destructor to restore the original matrix.
835          */
836         void restore();
837 
838     private:
839         GrDrawState*                        fDrawState;
840         SkMatrix                            fViewMatrix;
841         GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
842         uint32_t                            fRestoreMask;
843     };
844 
845     /// @}
846 
847     ///////////////////////////////////////////////////////////////////////////
848     /// @name Render Target
849     ////
850 
851     /**
852      * Sets the render-target used at the next drawing call
853      *
854      * @param target  The render target to set.
855      */
setRenderTarget(GrRenderTarget * target)856     void setRenderTarget(GrRenderTarget* target) {
857         fRenderTarget.reset(SkSafeRef(target));
858     }
859 
860     /**
861      * Retrieves the currently set render-target.
862      *
863      * @return    The currently set render target.
864      */
getRenderTarget()865     const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
getRenderTarget()866     GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
867 
868     class AutoRenderTargetRestore : public ::GrNoncopyable {
869     public:
AutoRenderTargetRestore()870         AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
AutoRenderTargetRestore(GrDrawState * ds,GrRenderTarget * newTarget)871         AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
872             fDrawState = NULL;
873             fSavedTarget = NULL;
874             this->set(ds, newTarget);
875         }
~AutoRenderTargetRestore()876         ~AutoRenderTargetRestore() { this->restore(); }
877 
restore()878         void restore() {
879             if (NULL != fDrawState) {
880                 fDrawState->setRenderTarget(fSavedTarget);
881                 fDrawState = NULL;
882             }
883             GrSafeSetNull(fSavedTarget);
884         }
885 
set(GrDrawState * ds,GrRenderTarget * newTarget)886         void set(GrDrawState* ds, GrRenderTarget* newTarget) {
887             this->restore();
888 
889             if (NULL != ds) {
890                 GrAssert(NULL == fSavedTarget);
891                 fSavedTarget = ds->getRenderTarget();
892                 SkSafeRef(fSavedTarget);
893                 ds->setRenderTarget(newTarget);
894                 fDrawState = ds;
895             }
896         }
897     private:
898         GrDrawState* fDrawState;
899         GrRenderTarget* fSavedTarget;
900     };
901 
902     /// @}
903 
904     ///////////////////////////////////////////////////////////////////////////
905     /// @name Stencil
906     ////
907 
908     /**
909      * Sets the stencil settings to use for the next draw.
910      * Changing the clip has the side-effect of possibly zeroing
911      * out the client settable stencil bits. So multipass algorithms
912      * using stencil should not change the clip between passes.
913      * @param settings  the stencil settings to use.
914      */
setStencil(const GrStencilSettings & settings)915     void setStencil(const GrStencilSettings& settings) {
916         fCommon.fStencilSettings = settings;
917     }
918 
919     /**
920      * Shortcut to disable stencil testing and ops.
921      */
disableStencil()922     void disableStencil() {
923         fCommon.fStencilSettings.setDisabled();
924     }
925 
getStencil()926     const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
927 
stencil()928     GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
929 
930     /// @}
931 
932     ///////////////////////////////////////////////////////////////////////////
933     // @name Edge AA
934     // Edge equations can be specified to perform anti-aliasing. Because the
935     // edges are specified as per-vertex data, vertices that are shared by
936     // multiple edges must be split.
937     //
938     ////
939 
940     /**
941      * When specifying edges as vertex data this enum specifies what type of
942      * edges are in use. The edges are always 4 SkScalars in memory, even when
943      * the edge type requires fewer than 4.
944      *
945      * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
946      *       (either adjust in VS or use origin_upper_left in GLSL)
947      */
948     enum VertexEdgeType {
949         /* 1-pixel wide line
950            2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
951         kHairLine_EdgeType,
952         /* Quadratic specified by u^2-v canonical coords (only 2
953            components used). Coverage based on signed distance with negative
954            being inside, positive outside. Edge specified in window space
955            (y-down) */
956         kQuad_EdgeType,
957         /* Same as above but for hairline quadratics. Uses unsigned distance.
958            Coverage is min(0, 1-distance). */
959         kHairQuad_EdgeType,
960         /* Circle specified as center_x, center_y, outer_radius, inner_radius
961            all in window space (y-down). */
962         kCircle_EdgeType,
963         /* Axis-aligned ellipse specified as center_x, center_y, x_radius, x_radius/y_radius
964            all in window space (y-down). */
965         kEllipse_EdgeType,
966 
967         kVertexEdgeTypeCnt
968     };
969 
970     /**
971      * Determines the interpretation per-vertex edge data when the
972      * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
973      * are not specified the value of this setting has no effect.
974      */
setVertexEdgeType(VertexEdgeType type)975     void setVertexEdgeType(VertexEdgeType type) {
976         GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
977         fCommon.fVertexEdgeType = type;
978     }
979 
getVertexEdgeType()980     VertexEdgeType getVertexEdgeType() const { return fCommon.fVertexEdgeType; }
981 
982     /// @}
983 
984     ///////////////////////////////////////////////////////////////////////////
985     /// @name State Flags
986     ////
987 
988     /**
989      *  Flags that affect rendering. Controlled using enable/disableState(). All
990      *  default to disabled.
991      */
992     enum StateBits {
993         /**
994          * Perform dithering. TODO: Re-evaluate whether we need this bit
995          */
996         kDither_StateBit        = 0x01,
997         /**
998          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
999          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
1000          * the 3D API.
1001          */
1002         kHWAntialias_StateBit   = 0x02,
1003         /**
1004          * Draws will respect the clip, otherwise the clip is ignored.
1005          */
1006         kClip_StateBit          = 0x04,
1007         /**
1008          * Disables writing to the color buffer. Useful when performing stencil
1009          * operations.
1010          */
1011         kNoColorWrites_StateBit = 0x08,
1012 
1013         /**
1014          * Usually coverage is applied after color blending. The color is blended using the coeffs
1015          * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
1016          * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
1017          * this case there is no distinction between coverage and color and the caller needs direct
1018          * control over the blend coeffs. When set, there will be a single blend step controlled by
1019          * setBlendFunc() which will use coverage*color as the src color.
1020          */
1021          kCoverageDrawing_StateBit = 0x10,
1022 
1023         // Users of the class may add additional bits to the vector
1024         kDummyStateBit,
1025         kLastPublicStateBit = kDummyStateBit-1,
1026     };
1027 
resetStateFlags()1028     void resetStateFlags() {
1029         fCommon.fFlagBits = 0;
1030     }
1031 
1032     /**
1033      * Enable render state settings.
1034      *
1035      * @param stateBits bitfield of StateBits specifying the states to enable
1036      */
enableState(uint32_t stateBits)1037     void enableState(uint32_t stateBits) {
1038         fCommon.fFlagBits |= stateBits;
1039     }
1040 
1041     /**
1042      * Disable render state settings.
1043      *
1044      * @param stateBits bitfield of StateBits specifying the states to disable
1045      */
disableState(uint32_t stateBits)1046     void disableState(uint32_t stateBits) {
1047         fCommon.fFlagBits &= ~(stateBits);
1048     }
1049 
1050     /**
1051      * Enable or disable stateBits based on a boolean.
1052      *
1053      * @param stateBits bitfield of StateBits to enable or disable
1054      * @param enable    if true enable stateBits, otherwise disable
1055      */
setState(uint32_t stateBits,bool enable)1056     void setState(uint32_t stateBits, bool enable) {
1057         if (enable) {
1058             this->enableState(stateBits);
1059         } else {
1060             this->disableState(stateBits);
1061         }
1062     }
1063 
isDitherState()1064     bool isDitherState() const {
1065         return 0 != (fCommon.fFlagBits & kDither_StateBit);
1066     }
1067 
isHWAntialiasState()1068     bool isHWAntialiasState() const {
1069         return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
1070     }
1071 
isClipState()1072     bool isClipState() const {
1073         return 0 != (fCommon.fFlagBits & kClip_StateBit);
1074     }
1075 
isColorWriteDisabled()1076     bool isColorWriteDisabled() const {
1077         return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
1078     }
1079 
isCoverageDrawing()1080     bool isCoverageDrawing() const {
1081         return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
1082     }
1083 
isStateFlagEnabled(uint32_t stateBit)1084     bool isStateFlagEnabled(uint32_t stateBit) const {
1085         return 0 != (stateBit & fCommon.fFlagBits);
1086     }
1087 
1088     /// @}
1089 
1090     ///////////////////////////////////////////////////////////////////////////
1091     /// @name Face Culling
1092     ////
1093 
1094     enum DrawFace {
1095         kInvalid_DrawFace = -1,
1096 
1097         kBoth_DrawFace,
1098         kCCW_DrawFace,
1099         kCW_DrawFace,
1100     };
1101 
1102     /**
1103      * Controls whether clockwise, counterclockwise, or both faces are drawn.
1104      * @param face  the face(s) to draw.
1105      */
setDrawFace(DrawFace face)1106     void setDrawFace(DrawFace face) {
1107         GrAssert(kInvalid_DrawFace != face);
1108         fCommon.fDrawFace = face;
1109     }
1110 
1111     /**
1112      * Gets whether the target is drawing clockwise, counterclockwise,
1113      * or both faces.
1114      * @return the current draw face(s).
1115      */
getDrawFace()1116     DrawFace getDrawFace() const { return fCommon.fDrawFace; }
1117 
1118     /// @}
1119 
1120     ///////////////////////////////////////////////////////////////////////////
1121 
isStageEnabled(int s)1122     bool isStageEnabled(int s) const {
1123         GrAssert((unsigned)s < kNumStages);
1124         return (NULL != fStages[s].getEffect());
1125     }
1126 
1127     // Most stages are usually not used, so conditionals here
1128     // reduce the expected number of bytes touched by 50%.
1129     bool operator ==(const GrDrawState& s) const {
1130         if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
1131             return false;
1132         }
1133 
1134         for (int i = 0; i < kNumStages; i++) {
1135             bool enabled = this->isStageEnabled(i);
1136             if (enabled != s.isStageEnabled(i)) {
1137                 return false;
1138             }
1139             if (enabled && this->fStages[i] != s.fStages[i]) {
1140                 return false;
1141             }
1142         }
1143         return true;
1144     }
1145     bool operator !=(const GrDrawState& s) const { return !(*this == s); }
1146 
1147     GrDrawState& operator= (const GrDrawState& s) {
1148         this->setRenderTarget(s.fRenderTarget.get());
1149         fCommon = s.fCommon;
1150         for (int i = 0; i < kNumStages; i++) {
1151             if (s.isStageEnabled(i)) {
1152                 this->fStages[i] = s.fStages[i];
1153             }
1154         }
1155         return *this;
1156     }
1157 
1158 private:
1159 
1160     /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1161     struct CommonState {
1162         // These fields are roughly sorted by decreasing likelihood of being different in op==
1163         GrColor                         fColor;
1164         SkMatrix                        fViewMatrix;
1165         GrBlendCoeff                    fSrcBlend;
1166         GrBlendCoeff                    fDstBlend;
1167         GrColor                         fBlendConstant;
1168         uint32_t                        fFlagBits;
1169         VertexEdgeType                  fVertexEdgeType;
1170         GrStencilSettings               fStencilSettings;
1171         int                             fFirstCoverageStage;
1172         GrColor                         fCoverage;
1173         SkXfermode::Mode                fColorFilterMode;
1174         GrColor                         fColorFilterColor;
1175         DrawFace                        fDrawFace;
1176         bool operator== (const CommonState& other) const {
1177             return fColor == other.fColor &&
1178                    fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1179                    fSrcBlend == other.fSrcBlend &&
1180                    fDstBlend == other.fDstBlend &&
1181                    fBlendConstant == other.fBlendConstant &&
1182                    fFlagBits == other.fFlagBits &&
1183                    fVertexEdgeType == other.fVertexEdgeType &&
1184                    fStencilSettings == other.fStencilSettings &&
1185                    fFirstCoverageStage == other.fFirstCoverageStage &&
1186                    fCoverage == other.fCoverage &&
1187                    fColorFilterMode == other.fColorFilterMode &&
1188                    fColorFilterColor == other.fColorFilterColor &&
1189                    fDrawFace == other.fDrawFace;
1190         }
1191         bool operator!= (const CommonState& other) const { return !(*this == other); }
1192     };
1193 
1194     /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1195         DeferredState must directly reference GrEffects, however. */
1196     struct SavedEffectStage {
SavedEffectStageSavedEffectStage1197         SavedEffectStage() : fEffect(NULL) {}
1198         const GrEffect*                    fEffect;
1199         GrEffectStage::SavedCoordChange    fCoordChange;
1200     };
1201 
1202 public:
1203     /**
1204      * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1205      * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1206      * dispose mechanism returns them to the cache. This allows recycling resources through the
1207      * the cache while they are in a deferred draw queue.
1208      */
1209     class DeferredState {
1210     public:
DeferredState()1211         DeferredState() : fRenderTarget(NULL) {
1212             GR_DEBUGCODE(fInitialized = false;)
1213         }
1214         // TODO: Remove this when DeferredState no longer holds a ref to the RT
~DeferredState()1215         ~DeferredState() { SkSafeUnref(fRenderTarget); }
1216 
saveFrom(const GrDrawState & drawState)1217         void saveFrom(const GrDrawState& drawState) {
1218             fCommon = drawState.fCommon;
1219             // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1220             fRenderTarget = drawState.fRenderTarget.get();
1221             SkSafeRef(fRenderTarget);
1222             // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1223             // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1224             // and recycle them to the cache (if no one else is holding a ref to the resources).
1225             for (int i = 0; i < kNumStages; ++i) {
1226                 fStages[i].saveFrom(drawState.fStages[i]);
1227             }
1228             GR_DEBUGCODE(fInitialized = true;)
1229         }
1230 
restoreTo(GrDrawState * drawState)1231         void restoreTo(GrDrawState* drawState) {
1232             GrAssert(fInitialized);
1233             drawState->fCommon = fCommon;
1234             drawState->setRenderTarget(fRenderTarget);
1235             for (int i = 0; i < kNumStages; ++i) {
1236                 fStages[i].restoreTo(&drawState->fStages[i]);
1237             }
1238         }
1239 
isEqual(const GrDrawState & state)1240         bool isEqual(const GrDrawState& state) const {
1241             if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1242                 return false;
1243             }
1244             for (int i = 0; i < kNumStages; ++i) {
1245                 if (!fStages[i].isEqual(state.fStages[i])) {
1246                     return false;
1247                 }
1248             }
1249             return true;
1250         }
1251 
1252     private:
1253         GrRenderTarget*                 fRenderTarget;
1254         CommonState                     fCommon;
1255         GrEffectStage::DeferredStage    fStages[kNumStages];
1256 
1257         GR_DEBUGCODE(bool fInitialized;)
1258     };
1259 
1260 private:
1261     SkAutoTUnref<GrRenderTarget>    fRenderTarget;
1262     CommonState                     fCommon;
1263     GrEffectStage                   fStages[kNumStages];
1264 
1265     typedef GrRefCnt INHERITED;
1266 };
1267 
1268 #endif
1269