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 "GrColor.h"
12#include "GrMatrix.h"
13#include "GrNoncopyable.h"
14#include "GrSamplerState.h"
15#include "GrStencil.h"
16
17#include "SkXfermode.h"
18
19class GrRenderTarget;
20class GrTexture;
21
22struct GrDrawState {
23
24    /**
25     * Number of texture stages. Each stage takes as input a color and
26     * 2D texture coordinates. The color input to the first enabled stage is the
27     * per-vertex color or the constant color (setColor/setAlpha) if there are
28     * no per-vertex colors. For subsequent stages the input color is the output
29     * color from the previous enabled stage. The output color of each stage is
30     * the input color modulated with the result of a texture lookup. Texture
31     * lookups are specified by a texture a sampler (setSamplerState). Texture
32     * coordinates for each stage come from the vertices based on a
33     * GrVertexLayout bitfield. The output fragment color is the output color of
34     * the last enabled stage. The presence or absence of texture coordinates
35     * for each stage in the vertex layout indicates whether a stage is enabled
36     * or not.
37     */
38    enum {
39        kNumStages = 3,
40        kMaxTexCoords = kNumStages
41    };
42
43    /**
44     *  Bitfield used to indicate a set of stages.
45     */
46    typedef uint32_t StageMask;
47    GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
48
49    GrDrawState() {
50        this->reset();
51    }
52
53    GrDrawState(const GrDrawState& state) {
54        *this = state;
55    }
56
57    /**
58     * Resets to the default state. Sampler states will not be modified.
59     */
60    void reset() {
61        // make sure any pad is zero for memcmp
62        // all GrDrawState members should default to something valid by the
63        // the memset except those initialized individually below. There should
64        // be no padding between the individually initialized members.
65        static const size_t kMemsetSize =
66            reinterpret_cast<intptr_t>(&fColor) -
67            reinterpret_cast<intptr_t>(this);
68        memset(this, 0, kMemsetSize);
69        // pedantic assertion that our ptrs will
70        // be NULL (0 ptr is mem addr 0)
71        GrAssert((intptr_t)(void*)NULL == 0LL);
72        GR_STATIC_ASSERT(0 == kBoth_DrawFace);
73        GrAssert(fStencilSettings.isDisabled());
74
75        // memset exceptions
76        fColor = 0xffffffff;
77        fCoverage = 0xffffffff;
78        fFirstCoverageStage = kNumStages;
79        fColorFilterMode = SkXfermode::kDst_Mode;
80        fSrcBlend = kOne_BlendCoeff;
81        fDstBlend = kZero_BlendCoeff;
82        fViewMatrix.reset();
83
84        // ensure values that will be memcmp'ed in == but not memset in reset()
85        // are tightly packed
86        GrAssert(kMemsetSize +  sizeof(fColor) + sizeof(fCoverage) +
87                 sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) +
88                 sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(GrMatrix) ==
89                 reinterpret_cast<intptr_t>(&fEdgeAANumEdges) -
90                 reinterpret_cast<intptr_t>(this));
91
92        fEdgeAANumEdges = 0;
93    }
94
95    ///////////////////////////////////////////////////////////////////////////
96    /// @name Color
97    ////
98
99    /**
100     *  Sets color for next draw to a premultiplied-alpha color.
101     *
102     *  @param color    the color to set.
103     */
104    void setColor(GrColor color) { fColor = color; }
105
106    GrColor getColor() const { return fColor; }
107
108    /**
109     *  Sets the color to be used for the next draw to be
110     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
111     *
112     *  @param alpha The alpha value to set as the color.
113     */
114    void setAlpha(uint8_t a) {
115        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
116    }
117
118    /**
119     * Add a color filter that can be represented by a color and a mode. Applied
120     * after color-computing texture stages.
121     */
122    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
123        fColorFilterColor = c;
124        fColorFilterMode = mode;
125    }
126
127    GrColor getColorFilterColor() const { return fColorFilterColor; }
128    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
129
130    /// @}
131
132    ///////////////////////////////////////////////////////////////////////////
133    /// @name Coverage
134    ////
135
136    /**
137     * Sets a constant fractional coverage to be applied to the draw. The
138     * initial value (after construction or reset()) is 0xff. The constant
139     * coverage is ignored when per-vertex coverage is provided.
140     */
141    void setCoverage(uint8_t coverage) {
142        fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
143    }
144
145    /**
146     * Version of above that specifies 4 channel per-vertex color. The value
147     * should be premultiplied.
148     */
149    void setCoverage4(GrColor coverage) {
150        fCoverage = coverage;
151    }
152
153    GrColor getCoverage() const {
154        return fCoverage;
155    }
156
157    /// @}
158
159    ///////////////////////////////////////////////////////////////////////////
160    /// @name Textures
161    ////
162
163    /**
164     * Sets the texture used at the next drawing call
165     *
166     * @param stage The texture stage for which the texture will be set
167     *
168     * @param texture The texture to set. Can be NULL though there is no
169     * advantage to settings a NULL texture if doing non-textured drawing
170     */
171    void setTexture(int stage, GrTexture* texture) {
172        GrAssert((unsigned)stage < kNumStages);
173        fTextures[stage] = texture;
174    }
175
176    /**
177     * Retrieves the currently set texture.
178     *
179     * @return    The currently set texture. The return value will be NULL if no
180     *            texture has been set, NULL was most recently passed to
181     *            setTexture, or the last setTexture was destroyed.
182     */
183    const GrTexture* getTexture(int stage) const {
184        GrAssert((unsigned)stage < kNumStages);
185        return fTextures[stage];
186    }
187    GrTexture* getTexture(int stage) {
188        GrAssert((unsigned)stage < kNumStages);
189        return fTextures[stage];
190    }
191
192    /// @}
193
194    ///////////////////////////////////////////////////////////////////////////
195    /// @name Samplers
196    ////
197
198    /**
199     * Returns the current sampler for a stage.
200     */
201    const GrSamplerState& getSampler(int stage) const {
202        GrAssert((unsigned)stage < kNumStages);
203        return fSamplerStates[stage];
204    }
205
206    /**
207     * Writable pointer to a stage's sampler.
208     */
209    GrSamplerState* sampler(int stage) {
210        GrAssert((unsigned)stage < kNumStages);
211        return fSamplerStates + stage;
212    }
213
214    /**
215     * Preconcats the matrix of all samplers in the mask with the same matrix.
216     */
217    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
218        GrAssert(!(stageMask & kIllegalStageMaskBits));
219        for (int i = 0; i < kNumStages; ++i) {
220            if ((1 << i) & stageMask) {
221                fSamplerStates[i].preConcatMatrix(matrix);
222            }
223        }
224    }
225
226    /// @}
227
228    ///////////////////////////////////////////////////////////////////////////
229    /// @name Coverage / Color Stages
230    ////
231
232    /**
233     * A common pattern is to compute a color with the initial stages and then
234     * modulate that color by a coverage value in later stage(s) (AA, mask-
235     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
236     * computed based on the pre-coverage-modulated color. The division of
237     * stages between color-computing and coverage-computing is specified by
238     * this method. Initially this is kNumStages (all stages
239     * are color-computing).
240     */
241    void setFirstCoverageStage(int firstCoverageStage) {
242        GrAssert((unsigned)firstCoverageStage <= kNumStages);
243        fFirstCoverageStage = firstCoverageStage;
244    }
245
246    /**
247     * Gets the index of the first coverage-computing stage.
248     */
249    int getFirstCoverageStage() const {
250        return fFirstCoverageStage;
251    }
252
253    ///@}
254
255    ///////////////////////////////////////////////////////////////////////////
256    /// @name Blending
257    ////
258
259    /**
260     * Sets the blending function coeffecients.
261     *
262     * The blend function will be:
263     *    D' = sat(S*srcCoef + D*dstCoef)
264     *
265     *   where D is the existing destination color, S is the incoming source
266     *   color, and D' is the new destination color that will be written. sat()
267     *   is the saturation function.
268     *
269     * @param srcCoef coeffecient applied to the src color.
270     * @param dstCoef coeffecient applied to the dst color.
271     */
272    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
273        fSrcBlend = srcCoeff;
274        fDstBlend = dstCoeff;
275    #if GR_DEBUG
276        switch (dstCoeff) {
277        case kDC_BlendCoeff:
278        case kIDC_BlendCoeff:
279        case kDA_BlendCoeff:
280        case kIDA_BlendCoeff:
281            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
282                     "coverage stages.\n");
283            break;
284        default:
285            break;
286        }
287        switch (srcCoeff) {
288        case kSC_BlendCoeff:
289        case kISC_BlendCoeff:
290        case kSA_BlendCoeff:
291        case kISA_BlendCoeff:
292            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
293                     "coverage stages.\n");
294            break;
295        default:
296            break;
297        }
298    #endif
299    }
300
301    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
302    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
303
304    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
305                          GrBlendCoeff* dstBlendCoeff) const {
306        *srcBlendCoeff = fSrcBlend;
307        *dstBlendCoeff = fDstBlend;
308    }
309
310    /**
311     * Sets the blending function constant referenced by the following blending
312     * coeffecients:
313     *      kConstC_BlendCoeff
314     *      kIConstC_BlendCoeff
315     *      kConstA_BlendCoeff
316     *      kIConstA_BlendCoeff
317     *
318     * @param constant the constant to set
319     */
320    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
321
322    /**
323     * Retrieves the last value set by setBlendConstant()
324     * @return the blending constant value
325     */
326    GrColor getBlendConstant() const { return fBlendConstant; }
327
328    /// @}
329
330    ///////////////////////////////////////////////////////////////////////////
331    /// @name View Matrix
332    ////
333
334    /**
335     * Sets the matrix applied to veretx positions.
336     *
337     * In the post-view-matrix space the rectangle [0,w]x[0,h]
338     * fully covers the render target. (w and h are the width and height of the
339     * the rendertarget.)
340     */
341    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
342
343    /**
344     * Gets a writable pointer to the view matrix.
345     */
346    GrMatrix* viewMatrix() { return &fViewMatrix; }
347
348    /**
349     *  Multiplies the current view matrix by a matrix
350     *
351     *  After this call V' = V*m where V is the old view matrix,
352     *  m is the parameter to this function, and V' is the new view matrix.
353     *  (We consider positions to be column vectors so position vector p is
354     *  transformed by matrix X as p' = X*p.)
355     *
356     *  @param m the matrix used to modify the view matrix.
357     */
358    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
359
360    /**
361     *  Multiplies the current view matrix by a matrix
362     *
363     *  After this call V' = m*V where V is the old view matrix,
364     *  m is the parameter to this function, and V' is the new view matrix.
365     *  (We consider positions to be column vectors so position vector p is
366     *  transformed by matrix X as p' = X*p.)
367     *
368     *  @param m the matrix used to modify the view matrix.
369     */
370    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
371
372    /**
373     * Retrieves the current view matrix
374     * @return the current view matrix.
375     */
376    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
377
378    /**
379     *  Retrieves the inverse of the current view matrix.
380     *
381     *  If the current view matrix is invertible, return true, and if matrix
382     *  is non-null, copy the inverse into it. If the current view matrix is
383     *  non-invertible, return false and ignore the matrix parameter.
384     *
385     * @param matrix if not null, will receive a copy of the current inverse.
386     */
387    bool getViewInverse(GrMatrix* matrix) const {
388        // TODO: determine whether we really need to leave matrix unmodified
389        // at call sites when inversion fails.
390        GrMatrix inverse;
391        if (fViewMatrix.invert(&inverse)) {
392            if (matrix) {
393                *matrix = inverse;
394            }
395            return true;
396        }
397        return false;
398    }
399
400    class AutoViewMatrixRestore : public ::GrNoncopyable {
401    public:
402        AutoViewMatrixRestore() : fDrawState(NULL) {}
403        AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
404            fDrawState = NULL;
405            this->set(ds, newMatrix);
406        }
407        AutoViewMatrixRestore(GrDrawState* ds) {
408            fDrawState = NULL;
409            this->set(ds);
410        }
411        ~AutoViewMatrixRestore() {
412            this->set(NULL, GrMatrix::I());
413        }
414        void set(GrDrawState* ds, const GrMatrix& newMatrix) {
415            if (NULL != fDrawState) {
416                fDrawState->setViewMatrix(fSavedMatrix);
417            }
418            if (NULL != ds) {
419                fSavedMatrix = ds->getViewMatrix();
420                ds->setViewMatrix(newMatrix);
421            }
422            fDrawState = ds;
423        }
424        void set(GrDrawState* ds) {
425            if (NULL != fDrawState) {
426                fDrawState->setViewMatrix(fSavedMatrix);
427            }
428            if (NULL != ds) {
429                fSavedMatrix = ds->getViewMatrix();
430            }
431            fDrawState = ds;
432        }
433    private:
434        GrDrawState* fDrawState;
435        GrMatrix fSavedMatrix;
436    };
437
438    /// @}
439
440    ///////////////////////////////////////////////////////////////////////////
441    /// @name Render Target
442    ////
443
444    /**
445     * Sets the rendertarget used at the next drawing call
446     *
447     * @param target  The render target to set.
448     */
449    void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
450
451    /**
452     * Retrieves the currently set rendertarget.
453     *
454     * @return    The currently set render target.
455     */
456    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
457    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
458
459    class AutoRenderTargetRestore : public ::GrNoncopyable {
460    public:
461        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
462        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
463            fDrawState = NULL;
464            this->set(ds, newTarget);
465        }
466        ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
467        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
468            if (NULL != fDrawState) {
469                fDrawState->setRenderTarget(fSavedTarget);
470            }
471            if (NULL != ds) {
472                fSavedTarget = ds->getRenderTarget();
473                ds->setRenderTarget(newTarget);
474            }
475            fDrawState = ds;
476        }
477    private:
478        GrDrawState* fDrawState;
479        GrRenderTarget* fSavedTarget;
480    };
481
482    /// @}
483
484    ///////////////////////////////////////////////////////////////////////////
485    /// @name Stencil
486    ////
487
488    /**
489     * Sets the stencil settings to use for the next draw.
490     * Changing the clip has the side-effect of possibly zeroing
491     * out the client settable stencil bits. So multipass algorithms
492     * using stencil should not change the clip between passes.
493     * @param settings  the stencil settings to use.
494     */
495    void setStencil(const GrStencilSettings& settings) {
496        fStencilSettings = settings;
497    }
498
499    /**
500     * Shortcut to disable stencil testing and ops.
501     */
502    void disableStencil() {
503        fStencilSettings.setDisabled();
504    }
505
506    const GrStencilSettings& getStencil() const { return fStencilSettings; }
507
508    GrStencilSettings* stencil() { return &fStencilSettings; }
509
510    /// @}
511
512    ///////////////////////////////////////////////////////////////////////////
513    /// @name Color Matrix
514    ////
515
516    /**
517     * Sets the color matrix to use for the next draw.
518     * @param matrix  the 5x4 matrix to apply to the incoming color
519     */
520    void setColorMatrix(const float matrix[20]) {
521        memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
522    }
523
524    const float* getColorMatrix() const { return fColorMatrix; }
525
526    /// @}
527
528    ///////////////////////////////////////////////////////////////////////////
529    // @name Edge AA
530    // There are two ways to perform antialiasing using edge equations. One
531    // is to specify an (linear or quadratic) edge eq per-vertex. This requires
532    // splitting vertices shared by primitives.
533    //
534    // The other is via setEdgeAAData which sets a set of edges and each
535    // is tested against all the edges.
536    ////
537
538    /**
539     * When specifying edges as vertex data this enum specifies what type of
540     * edges are in use. The edges are always 4 GrScalars in memory, even when
541     * the edge type requires fewer than 4.
542     */
543    enum VertexEdgeType {
544        /* 1-pixel wide line
545           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
546        kHairLine_EdgeType,
547        /* Quadratic specified by u^2-v canonical coords (only 2
548           components used). Coverage based on signed distance with negative
549           being inside, positive outside.*/
550        kQuad_EdgeType,
551        /* Same as above but for hairline quadratics. Uses unsigned distance.
552           Coverage is min(0, 1-distance). */
553        kHairQuad_EdgeType,
554
555        kVertexEdgeTypeCnt
556    };
557
558    /**
559     * Determines the interpretation per-vertex edge data when the
560     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
561     * are not specified the value of this setting has no effect.
562     */
563    void setVertexEdgeType(VertexEdgeType type) {
564        GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
565        fVertexEdgeType = type;
566    }
567
568    VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
569
570    /**
571     * The absolute maximum number of edges that may be specified for
572     * a single draw call when performing edge antialiasing.  This is used for
573     * the size of several static buffers, so implementations of getMaxEdges()
574     * (below) should clamp to this value.
575     */
576    enum {
577        // TODO: this should be 32 when GrTesselatedPathRenderer is used
578        // Visual Studio 2010 does not permit a member array of size 0.
579        kMaxEdges = 1
580    };
581
582    class Edge {
583      public:
584        Edge() {}
585        Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
586        GrPoint intersect(const Edge& other) {
587            return GrPoint::Make(
588                SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
589                                (fX * other.fY - other.fX * fY)),
590                SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
591                                (other.fX * fY - fX * other.fY)));
592        }
593        float fX, fY, fZ;
594    };
595
596    /**
597     * Sets the edge data required for edge antialiasing.
598     *
599     * @param edges       3 * numEdges float values, representing the edge
600     *                    equations in Ax + By + C form
601     */
602    void setEdgeAAData(const Edge* edges, int numEdges) {
603        GrAssert(numEdges <= GrDrawState::kMaxEdges);
604        memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
605        fEdgeAANumEdges = numEdges;
606    }
607
608    int getNumAAEdges() const { return fEdgeAANumEdges; }
609
610    const Edge* getAAEdges() const { return fEdgeAAEdges; }
611
612    /// @}
613
614    ///////////////////////////////////////////////////////////////////////////
615    /// @name State Flags
616    ////
617
618    /**
619     *  Flags that affect rendering. Controlled using enable/disableState(). All
620     *  default to disabled.
621     */
622    enum StateBits {
623        /**
624         * Perform dithering. TODO: Re-evaluate whether we need this bit
625         */
626        kDither_StateBit        = 0x01,
627        /**
628         * Perform HW anti-aliasing. This means either HW FSAA, if supported
629         * by the render target, or smooth-line rendering if a line primitive
630         * is drawn and line smoothing is supported by the 3D API.
631         */
632        kHWAntialias_StateBit   = 0x02,
633        /**
634         * Draws will respect the clip, otherwise the clip is ignored.
635         */
636        kClip_StateBit          = 0x04,
637        /**
638         * Disables writing to the color buffer. Useful when performing stencil
639         * operations.
640         */
641        kNoColorWrites_StateBit = 0x08,
642        /**
643         * Modifies the behavior of edge AA specified by setEdgeAA. If set,
644         * will test edge pairs for convexity when rasterizing. Set this if the
645         * source polygon is non-convex.
646         */
647        kEdgeAAConcave_StateBit = 0x10,
648        /**
649         * Draws will apply the color matrix, otherwise the color matrix is
650         * ignored.
651         */
652        kColorMatrix_StateBit   = 0x20,
653
654        // Users of the class may add additional bits to the vector
655        kDummyStateBit,
656        kLastPublicStateBit = kDummyStateBit-1,
657    };
658
659    void resetStateFlags() {
660        fFlagBits = 0;
661    }
662
663    /**
664     * Enable render state settings.
665     *
666     * @param flags   bitfield of StateBits specifing the states to enable
667     */
668    void enableState(uint32_t stateBits) {
669        fFlagBits |= stateBits;
670    }
671
672    /**
673     * Disable render state settings.
674     *
675     * @param flags   bitfield of StateBits specifing the states to disable
676     */
677    void disableState(uint32_t stateBits) {
678        fFlagBits &= ~(stateBits);
679    }
680
681    bool isDitherState() const {
682        return 0 != (fFlagBits & kDither_StateBit);
683    }
684
685    bool isHWAntialiasState() const {
686        return 0 != (fFlagBits & kHWAntialias_StateBit);
687    }
688
689    bool isClipState() const {
690        return 0 != (fFlagBits & kClip_StateBit);
691    }
692
693    bool isColorWriteDisabled() const {
694        return 0 != (fFlagBits & kNoColorWrites_StateBit);
695    }
696
697    bool isConcaveEdgeAAState() const {
698        return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
699    }
700
701    bool isStateFlagEnabled(uint32_t stateBit) const {
702        return 0 != (stateBit & fFlagBits);
703    }
704
705    void copyStateFlags(const GrDrawState& ds) {
706        fFlagBits = ds.fFlagBits;
707    }
708
709    /// @}
710
711    ///////////////////////////////////////////////////////////////////////////
712    /// @name Face Culling
713    ////
714
715    enum DrawFace {
716        kBoth_DrawFace,
717        kCCW_DrawFace,
718        kCW_DrawFace,
719    };
720
721    /**
722     * Controls whether clockwise, counterclockwise, or both faces are drawn.
723     * @param face  the face(s) to draw.
724     */
725    void setDrawFace(DrawFace face) {
726        fDrawFace = face;
727    }
728
729    /**
730     * Gets whether the target is drawing clockwise, counterclockwise,
731     * or both faces.
732     * @return the current draw face(s).
733     */
734    DrawFace getDrawFace() const { return fDrawFace; }
735
736    /// @}
737
738    ///////////////////////////////////////////////////////////////////////////
739
740    // Most stages are usually not used, so conditionals here
741    // reduce the expected number of bytes touched by 50%.
742    bool operator ==(const GrDrawState& s) const {
743        if (memcmp(this, &s, this->leadingBytes())) return false;
744
745        for (int i = 0; i < kNumStages; i++) {
746            if (fTextures[i] &&
747                memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
748                       sizeof(GrSamplerState))) {
749                return false;
750            }
751        }
752
753        return true;
754    }
755    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
756
757    // Most stages are usually not used, so conditionals here
758    // reduce the expected number of bytes touched by 50%.
759    GrDrawState& operator =(const GrDrawState& s) {
760        memcpy(this, &s, this->leadingBytes());
761
762        for (int i = 0; i < kNumStages; i++) {
763            if (s.fTextures[i]) {
764                memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
765                       sizeof(GrSamplerState));
766            }
767        }
768
769        return *this;
770    }
771
772private:
773    static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
774    // @{ these fields can be initialized with memset to 0
775    GrColor             fBlendConstant;
776    GrTexture*          fTextures[kNumStages];
777    GrColor             fColorFilterColor;
778    uint32_t            fFlagBits;
779    DrawFace            fDrawFace;
780    VertexEdgeType      fVertexEdgeType;
781    GrStencilSettings   fStencilSettings;
782    float               fColorMatrix[20];       // 5 x 4 matrix
783    GrRenderTarget*     fRenderTarget;
784    // @}
785
786    // @{ Initialized to values other than zero
787    GrColor             fColor;
788    GrColor             fCoverage;
789    int                 fFirstCoverageStage;
790    SkXfermode::Mode    fColorFilterMode;
791    GrBlendCoeff        fSrcBlend;
792    GrBlendCoeff        fDstBlend;
793    GrMatrix            fViewMatrix;
794    // @}
795
796    // @{ Data for GrTesselatedPathRenderer
797    // TODO: currently ignored in copying & comparison for performance.
798    // Must be considered if GrTesselatedPathRenderer is being used.
799    int                 fEdgeAANumEdges;
800    Edge                fEdgeAAEdges[kMaxEdges];
801    // @}
802
803    // This field must be last; it will not be copied or compared
804    // if the corresponding fTexture[] is NULL.
805    GrSamplerState      fSamplerStates[kNumStages];
806
807    size_t leadingBytes() const {
808        // Can't use offsetof() with non-POD types, so stuck with pointer math.
809        // TODO: ignores GrTesselatedPathRenderer data structures. We don't
810        // have a compile-time flag that lets us know if it's being used, and
811        // checking at runtime seems to cost 5% performance.
812        return (size_t) ((unsigned char*)&fEdgeAANumEdges -
813                         (unsigned char*)&fBlendConstant);
814    }
815
816};
817
818#endif
819