Home | History | Annotate | Download | only in gpu
      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 
     19 class GrRenderTarget;
     20 class GrTexture;
     21 
     22 struct 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 
    772 private:
    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