/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrDrawState_DEFINED
#define GrDrawState_DEFINED

#include "GrColor.h"
#include "GrMatrix.h"
#include "GrNoncopyable.h"
#include "GrSamplerState.h"
#include "GrStencil.h"

#include "SkXfermode.h"

class GrRenderTarget;
class GrTexture;

struct GrDrawState {

    /**
     * Number of texture stages. Each stage takes as input a color and
     * 2D texture coordinates. The color input to the first enabled stage is the
     * per-vertex color or the constant color (setColor/setAlpha) if there are
     * no per-vertex colors. For subsequent stages the input color is the output
     * color from the previous enabled stage. The output color of each stage is
     * the input color modulated with the result of a texture lookup. Texture
     * lookups are specified by a texture a sampler (setSamplerState). Texture
     * coordinates for each stage come from the vertices based on a
     * GrVertexLayout bitfield. The output fragment color is the output color of
     * the last enabled stage. The presence or absence of texture coordinates
     * for each stage in the vertex layout indicates whether a stage is enabled
     * or not.
     */
    enum {
        kNumStages = 3,
        kMaxTexCoords = kNumStages
    };

    /**
     *  Bitfield used to indicate a set of stages.
     */
    typedef uint32_t StageMask;
    GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);

    GrDrawState() {
        this->reset();
    }

    GrDrawState(const GrDrawState& state) {
        *this = state;
    }

    /**
     * Resets to the default state. Sampler states will not be modified.
     */ 
    void reset() {
        // make sure any pad is zero for memcmp
        // all GrDrawState members should default to something valid by the
        // the memset except those initialized individually below. There should
        // be no padding between the individually initialized members.
        static const size_t kMemsetSize =
            reinterpret_cast<intptr_t>(&fColor) -
            reinterpret_cast<intptr_t>(this);
        memset(this, 0, kMemsetSize);
        // pedantic assertion that our ptrs will
        // be NULL (0 ptr is mem addr 0)
        GrAssert((intptr_t)(void*)NULL == 0LL);
        GR_STATIC_ASSERT(0 == kBoth_DrawFace);
        GrAssert(fStencilSettings.isDisabled());

        // memset exceptions
        fColor = 0xffffffff;
        fCoverage = 0xffffffff;
        fFirstCoverageStage = kNumStages;
        fColorFilterMode = SkXfermode::kDst_Mode;
        fSrcBlend = kOne_BlendCoeff;
        fDstBlend = kZero_BlendCoeff;
        fViewMatrix.reset();

        // ensure values that will be memcmp'ed in == but not memset in reset()
        // are tightly packed
        GrAssert(kMemsetSize +  sizeof(fColor) + sizeof(fCoverage) +
                 sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) +
                 sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(GrMatrix) ==
                 reinterpret_cast<intptr_t>(&fEdgeAANumEdges) -
                 reinterpret_cast<intptr_t>(this));

        fEdgeAANumEdges = 0;
    }

    ///////////////////////////////////////////////////////////////////////////
    /// @name Color
    ////

    /**
     *  Sets color for next draw to a premultiplied-alpha color.
     *
     *  @param color    the color to set.
     */
    void setColor(GrColor color) { fColor = color; }

    GrColor getColor() const { return fColor; }

    /**
     *  Sets the color to be used for the next draw to be
     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
     *
     *  @param alpha The alpha value to set as the color.
     */
    void setAlpha(uint8_t a) {
        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
    }

    /**
     * Add a color filter that can be represented by a color and a mode. Applied
     * after color-computing texture stages.
     */
    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
        fColorFilterColor = c;
        fColorFilterMode = mode;
    }

    GrColor getColorFilterColor() const { return fColorFilterColor; }
    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Coverage
    ////

    /**
     * Sets a constant fractional coverage to be applied to the draw. The 
     * initial value (after construction or reset()) is 0xff. The constant
     * coverage is ignored when per-vertex coverage is provided.
     */
    void setCoverage(uint8_t coverage) {
        fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
    }

    /**
     * Version of above that specifies 4 channel per-vertex color. The value
     * should be premultiplied.
     */
    void setCoverage4(GrColor coverage) {
        fCoverage = coverage;
    }

    GrColor getCoverage() const {
        return fCoverage;
    }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Textures
    ////

    /**
     * Sets the texture used at the next drawing call
     *
     * @param stage The texture stage for which the texture will be set
     *
     * @param texture The texture to set. Can be NULL though there is no
     * advantage to settings a NULL texture if doing non-textured drawing
     */
    void setTexture(int stage, GrTexture* texture) {
        GrAssert((unsigned)stage < kNumStages);
        fTextures[stage] = texture;
    }

    /**
     * Retrieves the currently set texture.
     *
     * @return    The currently set texture. The return value will be NULL if no
     *            texture has been set, NULL was most recently passed to
     *            setTexture, or the last setTexture was destroyed.
     */
    const GrTexture* getTexture(int stage) const {
        GrAssert((unsigned)stage < kNumStages);
        return fTextures[stage];
    }
    GrTexture* getTexture(int stage) {
        GrAssert((unsigned)stage < kNumStages);
        return fTextures[stage];
    }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Samplers
    ////

    /**
     * Returns the current sampler for a stage.
     */
    const GrSamplerState& getSampler(int stage) const {
        GrAssert((unsigned)stage < kNumStages);
        return fSamplerStates[stage];
    }

    /**
     * Writable pointer to a stage's sampler.
     */
    GrSamplerState* sampler(int stage) {
        GrAssert((unsigned)stage < kNumStages);
        return fSamplerStates + stage;
    }

    /**
     * Preconcats the matrix of all samplers in the mask with the same matrix.
     */
    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
        GrAssert(!(stageMask & kIllegalStageMaskBits));
        for (int i = 0; i < kNumStages; ++i) {
            if ((1 << i) & stageMask) {
                fSamplerStates[i].preConcatMatrix(matrix);
            }
        }
    }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Coverage / Color Stages
    ////

    /**
     * A common pattern is to compute a color with the initial stages and then
     * modulate that color by a coverage value in later stage(s) (AA, mask-
     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be 
     * computed based on the pre-coverage-modulated color. The division of 
     * stages between color-computing and coverage-computing is specified by 
     * this method. Initially this is kNumStages (all stages
     * are color-computing).
     */
    void setFirstCoverageStage(int firstCoverageStage) {
        GrAssert((unsigned)firstCoverageStage <= kNumStages);
        fFirstCoverageStage = firstCoverageStage; 
    }

    /**
     * Gets the index of the first coverage-computing stage.
     */
    int getFirstCoverageStage() const {
        return fFirstCoverageStage; 
    }

    ///@}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Blending
    ////

    /**
     * Sets the blending function coeffecients.
     *
     * The blend function will be:
     *    D' = sat(S*srcCoef + D*dstCoef)
     *
     *   where D is the existing destination color, S is the incoming source
     *   color, and D' is the new destination color that will be written. sat()
     *   is the saturation function.
     *
     * @param srcCoef coeffecient applied to the src color.
     * @param dstCoef coeffecient applied to the dst color.
     */
    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
        fSrcBlend = srcCoeff;
        fDstBlend = dstCoeff;
    #if GR_DEBUG
        switch (dstCoeff) {
        case kDC_BlendCoeff:
        case kIDC_BlendCoeff:
        case kDA_BlendCoeff:
        case kIDA_BlendCoeff:
            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
                     "coverage stages.\n");
            break;
        default:
            break;
        }
        switch (srcCoeff) {
        case kSC_BlendCoeff:
        case kISC_BlendCoeff:
        case kSA_BlendCoeff:
        case kISA_BlendCoeff:
            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
                     "coverage stages.\n");
            break;
        default:
            break;
        }
    #endif
    }

    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }

    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
                          GrBlendCoeff* dstBlendCoeff) const {
        *srcBlendCoeff = fSrcBlend;
        *dstBlendCoeff = fDstBlend;
    }

    /**
     * Sets the blending function constant referenced by the following blending
     * coeffecients:
     *      kConstC_BlendCoeff
     *      kIConstC_BlendCoeff
     *      kConstA_BlendCoeff
     *      kIConstA_BlendCoeff
     *
     * @param constant the constant to set
     */
    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }

    /**
     * Retrieves the last value set by setBlendConstant()
     * @return the blending constant value
     */
    GrColor getBlendConstant() const { return fBlendConstant; }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name View Matrix
    ////

    /**
     * Sets the matrix applied to veretx positions.
     *
     * In the post-view-matrix space the rectangle [0,w]x[0,h]
     * fully covers the render target. (w and h are the width and height of the
     * the rendertarget.)
     */
    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }

    /**
     * Gets a writable pointer to the view matrix.
     */
    GrMatrix* viewMatrix() { return &fViewMatrix; }

    /**
     *  Multiplies the current view matrix by a matrix
     *
     *  After this call V' = V*m where V is the old view matrix,
     *  m is the parameter to this function, and V' is the new view matrix.
     *  (We consider positions to be column vectors so position vector p is
     *  transformed by matrix X as p' = X*p.)
     *
     *  @param m the matrix used to modify the view matrix.
     */
    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }

    /**
     *  Multiplies the current view matrix by a matrix
     *
     *  After this call V' = m*V where V is the old view matrix,
     *  m is the parameter to this function, and V' is the new view matrix.
     *  (We consider positions to be column vectors so position vector p is
     *  transformed by matrix X as p' = X*p.)
     *
     *  @param m the matrix used to modify the view matrix.
     */
    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }

    /**
     * Retrieves the current view matrix
     * @return the current view matrix.
     */
    const GrMatrix& getViewMatrix() const { return fViewMatrix; }

    /**
     *  Retrieves the inverse of the current view matrix.
     *
     *  If the current view matrix is invertible, return true, and if matrix
     *  is non-null, copy the inverse into it. If the current view matrix is
     *  non-invertible, return false and ignore the matrix parameter.
     *
     * @param matrix if not null, will receive a copy of the current inverse.
     */
    bool getViewInverse(GrMatrix* matrix) const {
        // TODO: determine whether we really need to leave matrix unmodified
        // at call sites when inversion fails.
        GrMatrix inverse;
        if (fViewMatrix.invert(&inverse)) {
            if (matrix) {
                *matrix = inverse;
            }
            return true;
        }
        return false;
    }

    class AutoViewMatrixRestore : public ::GrNoncopyable {
    public:
        AutoViewMatrixRestore() : fDrawState(NULL) {}
        AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
            fDrawState = NULL;
            this->set(ds, newMatrix);
        }
        AutoViewMatrixRestore(GrDrawState* ds) {
            fDrawState = NULL;
            this->set(ds);
        }
        ~AutoViewMatrixRestore() {
            this->set(NULL, GrMatrix::I());
        }
        void set(GrDrawState* ds, const GrMatrix& newMatrix) {
            if (NULL != fDrawState) {
                fDrawState->setViewMatrix(fSavedMatrix);
            }
            if (NULL != ds) {
                fSavedMatrix = ds->getViewMatrix();
                ds->setViewMatrix(newMatrix);
            }
            fDrawState = ds;
        }
        void set(GrDrawState* ds) {
            if (NULL != fDrawState) {
                fDrawState->setViewMatrix(fSavedMatrix);
            }
            if (NULL != ds) {
                fSavedMatrix = ds->getViewMatrix();
            }
            fDrawState = ds;
        }
    private:
        GrDrawState* fDrawState;
        GrMatrix fSavedMatrix;
    };

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Render Target
    ////

    /**
     * Sets the rendertarget used at the next drawing call
     *
     * @param target  The render target to set.
     */
    void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }

    /**
     * Retrieves the currently set rendertarget.
     *
     * @return    The currently set render target.
     */
    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
    GrRenderTarget* getRenderTarget() { return fRenderTarget; }

    class AutoRenderTargetRestore : public ::GrNoncopyable {
    public:
        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
            fDrawState = NULL;
            this->set(ds, newTarget);
        }
        ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
            if (NULL != fDrawState) {
                fDrawState->setRenderTarget(fSavedTarget);
            }
            if (NULL != ds) {
                fSavedTarget = ds->getRenderTarget();
                ds->setRenderTarget(newTarget);
            }
            fDrawState = ds;
        }
    private:
        GrDrawState* fDrawState;
        GrRenderTarget* fSavedTarget;
    };

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Stencil
    ////

    /**
     * Sets the stencil settings to use for the next draw.
     * Changing the clip has the side-effect of possibly zeroing
     * out the client settable stencil bits. So multipass algorithms
     * using stencil should not change the clip between passes.
     * @param settings  the stencil settings to use.
     */
    void setStencil(const GrStencilSettings& settings) {
        fStencilSettings = settings;
    }

    /**
     * Shortcut to disable stencil testing and ops.
     */
    void disableStencil() {
        fStencilSettings.setDisabled();
    }

    const GrStencilSettings& getStencil() const { return fStencilSettings; }

    GrStencilSettings* stencil() { return &fStencilSettings; }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Color Matrix
    ////

    /**
     * Sets the color matrix to use for the next draw.
     * @param matrix  the 5x4 matrix to apply to the incoming color
     */
    void setColorMatrix(const float matrix[20]) {
        memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
    }

    const float* getColorMatrix() const { return fColorMatrix; }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    // @name Edge AA
    // There are two ways to perform antialiasing using edge equations. One
    // is to specify an (linear or quadratic) edge eq per-vertex. This requires
    // splitting vertices shared by primitives.
    //
    // The other is via setEdgeAAData which sets a set of edges and each
    // is tested against all the edges.
    ////

    /**
     * When specifying edges as vertex data this enum specifies what type of
     * edges are in use. The edges are always 4 GrScalars in memory, even when
     * the edge type requires fewer than 4.
     */
    enum VertexEdgeType {
        /* 1-pixel wide line
           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
        kHairLine_EdgeType,
        /* Quadratic specified by u^2-v canonical coords (only 2 
           components used). Coverage based on signed distance with negative
           being inside, positive outside.*/
        kQuad_EdgeType,
        /* Same as above but for hairline quadratics. Uses unsigned distance.
           Coverage is min(0, 1-distance). */
        kHairQuad_EdgeType,

        kVertexEdgeTypeCnt
    };

    /**
     * Determines the interpretation per-vertex edge data when the 
     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
     * are not specified the value of this setting has no effect.
     */
    void setVertexEdgeType(VertexEdgeType type) {
        GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
        fVertexEdgeType = type;
    }

    VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }

    /**
     * The absolute maximum number of edges that may be specified for
     * a single draw call when performing edge antialiasing.  This is used for
     * the size of several static buffers, so implementations of getMaxEdges()
     * (below) should clamp to this value.
     */
    enum {
        // TODO: this should be 32 when GrTesselatedPathRenderer is used
        // Visual Studio 2010 does not permit a member array of size 0.
        kMaxEdges = 1
    };

    class Edge {
      public:
        Edge() {}
        Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
        GrPoint intersect(const Edge& other) {
            return GrPoint::Make(
                SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
                                (fX * other.fY - other.fX * fY)),
                SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
                                (other.fX * fY - fX * other.fY)));
        }
        float fX, fY, fZ;
    };

    /**
     * Sets the edge data required for edge antialiasing.
     *
     * @param edges       3 * numEdges float values, representing the edge
     *                    equations in Ax + By + C form
     */
    void setEdgeAAData(const Edge* edges, int numEdges) {
        GrAssert(numEdges <= GrDrawState::kMaxEdges);
        memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
        fEdgeAANumEdges = numEdges;
    }

    int getNumAAEdges() const { return fEdgeAANumEdges; }

    const Edge* getAAEdges() const { return fEdgeAAEdges; }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name State Flags
    ////

    /**
     *  Flags that affect rendering. Controlled using enable/disableState(). All
     *  default to disabled.
     */
    enum StateBits {
        /**
         * Perform dithering. TODO: Re-evaluate whether we need this bit
         */
        kDither_StateBit        = 0x01,
        /**
         * Perform HW anti-aliasing. This means either HW FSAA, if supported
         * by the render target, or smooth-line rendering if a line primitive
         * is drawn and line smoothing is supported by the 3D API.
         */
        kHWAntialias_StateBit   = 0x02,
        /**
         * Draws will respect the clip, otherwise the clip is ignored.
         */
        kClip_StateBit          = 0x04,
        /**
         * Disables writing to the color buffer. Useful when performing stencil
         * operations.
         */
        kNoColorWrites_StateBit = 0x08,
        /**
         * Modifies the behavior of edge AA specified by setEdgeAA. If set, 
         * will test edge pairs for convexity when rasterizing. Set this if the 
         * source polygon is non-convex.
         */
        kEdgeAAConcave_StateBit = 0x10,
        /**
         * Draws will apply the color matrix, otherwise the color matrix is
         * ignored.
         */
        kColorMatrix_StateBit   = 0x20,

        // Users of the class may add additional bits to the vector
        kDummyStateBit,
        kLastPublicStateBit = kDummyStateBit-1,
    };

    void resetStateFlags() {
        fFlagBits = 0;
    }

    /**
     * Enable render state settings.
     *
     * @param flags   bitfield of StateBits specifing the states to enable
     */
    void enableState(uint32_t stateBits) {
        fFlagBits |= stateBits;
    }

    /**
     * Disable render state settings.
     *
     * @param flags   bitfield of StateBits specifing the states to disable
     */
    void disableState(uint32_t stateBits) {
        fFlagBits &= ~(stateBits);
    }

    bool isDitherState() const {
        return 0 != (fFlagBits & kDither_StateBit);
    }

    bool isHWAntialiasState() const {
        return 0 != (fFlagBits & kHWAntialias_StateBit);
    }

    bool isClipState() const {
        return 0 != (fFlagBits & kClip_StateBit);
    }

    bool isColorWriteDisabled() const {
        return 0 != (fFlagBits & kNoColorWrites_StateBit);
    }

    bool isConcaveEdgeAAState() const {
        return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
    }

    bool isStateFlagEnabled(uint32_t stateBit) const {
        return 0 != (stateBit & fFlagBits);
    }

    void copyStateFlags(const GrDrawState& ds) {
        fFlagBits = ds.fFlagBits;
    }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Face Culling
    ////

    enum DrawFace {
        kBoth_DrawFace,
        kCCW_DrawFace,
        kCW_DrawFace,
    };

    /**
     * Controls whether clockwise, counterclockwise, or both faces are drawn.
     * @param face  the face(s) to draw.
     */
    void setDrawFace(DrawFace face) {
        fDrawFace = face;
    }

    /**
     * Gets whether the target is drawing clockwise, counterclockwise,
     * or both faces.
     * @return the current draw face(s).
     */
    DrawFace getDrawFace() const { return fDrawFace; }
    
    /// @}

    ///////////////////////////////////////////////////////////////////////////

    // Most stages are usually not used, so conditionals here
    // reduce the expected number of bytes touched by 50%.
    bool operator ==(const GrDrawState& s) const {
        if (memcmp(this, &s, this->leadingBytes())) return false;

        for (int i = 0; i < kNumStages; i++) {
            if (fTextures[i] &&
                memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
                       sizeof(GrSamplerState))) {
                return false;
            }
        }

        return true;
    }
    bool operator !=(const GrDrawState& s) const { return !(*this == s); }

    // Most stages are usually not used, so conditionals here 
    // reduce the expected number of bytes touched by 50%.
    GrDrawState& operator =(const GrDrawState& s) {
        memcpy(this, &s, this->leadingBytes());

        for (int i = 0; i < kNumStages; i++) {
            if (s.fTextures[i]) {
                memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
                       sizeof(GrSamplerState));
            }
        }

        return *this;
    }

private:
    static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
    // @{ these fields can be initialized with memset to 0
    GrColor             fBlendConstant;
    GrTexture*          fTextures[kNumStages];
    GrColor             fColorFilterColor;
    uint32_t            fFlagBits;
    DrawFace            fDrawFace; 
    VertexEdgeType      fVertexEdgeType;
    GrStencilSettings   fStencilSettings;
    float               fColorMatrix[20];       // 5 x 4 matrix
    GrRenderTarget*     fRenderTarget;
    // @}

    // @{ Initialized to values other than zero
    GrColor             fColor;
    GrColor             fCoverage;
    int                 fFirstCoverageStage;
    SkXfermode::Mode    fColorFilterMode;
    GrBlendCoeff        fSrcBlend;
    GrBlendCoeff        fDstBlend;
    GrMatrix            fViewMatrix;
    // @}

    // @{ Data for GrTesselatedPathRenderer
    // TODO: currently ignored in copying & comparison for performance.
    // Must be considered if GrTesselatedPathRenderer is being used.
    int                 fEdgeAANumEdges;
    Edge                fEdgeAAEdges[kMaxEdges];
    // @}

    // This field must be last; it will not be copied or compared
    // if the corresponding fTexture[] is NULL.
    GrSamplerState      fSamplerStates[kNumStages];

    size_t leadingBytes() const {
        // Can't use offsetof() with non-POD types, so stuck with pointer math.
        // TODO: ignores GrTesselatedPathRenderer data structures. We don't
        // have a compile-time flag that lets us know if it's being used, and
        // checking at runtime seems to cost 5% performance.
        return (size_t) ((unsigned char*)&fEdgeAANumEdges -
                         (unsigned char*)&fBlendConstant);
    }

};

#endif
