Cleanup of r2830.



git-svn-id: http://skia.googlecode.com/svn/trunk@2841 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 90de1a3..7526b9f 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -10,6 +10,7 @@
 
 #include "GrColor.h"
 #include "GrMatrix.h"
+#include "GrNoncopyable.h"
 #include "GrSamplerState.h"
 #include "GrStencil.h"
 
@@ -45,13 +46,433 @@
     typedef uint32_t StageMask;
     GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
 
-    enum DrawFace {
-        kBoth_DrawFace,
-        kCCW_DrawFace,
-        kCW_DrawFace,
+    GrDrawState() {
+        // make sure any pad is zero for memcmp
+        // all GrDrawState members should default to something
+        // valid by the memset
+        memset(this, 0, sizeof(GrDrawState));
+            
+        // memset exceptions
+        fColorFilterMode = SkXfermode::kDstIn_Mode;
+        fFirstCoverageStage = kNumStages;
+
+        // pedantic assertion that our ptrs will
+        // be NULL (0 ptr is mem addr 0)
+        GrAssert((intptr_t)(void*)NULL == 0LL);
+
+        GrAssert(fStencilSettings.isDisabled());
+        fFirstCoverageStage = kNumStages;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @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 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];
+    }
+
+    /**
+     * Sets the sampler. This will be removed soon in favor of direct access.
+     */
+    void setSampler(int stage, const GrSamplerState& sampler) {
+        GrAssert((unsigned)stage < kNumStages);
+        fSamplerStates[stage] = sampler;
+    }
+
+    /**
+     * 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) {}
+        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 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.
@@ -66,6 +487,19 @@
     };
 
     /**
+     * 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) {
+        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()
@@ -91,53 +525,146 @@
         float fX, fY, fZ;
     };
 
-    GrDrawState() {
-        // make sure any pad is zero for memcmp
-        // all GrDrawState members should default to something
-        // valid by the memset
-        memset(this, 0, sizeof(GrDrawState));
-            
-        // memset exceptions
-        fColorFilterXfermode = SkXfermode::kDstIn_Mode;
-        fFirstCoverageStage = kNumStages;
-
-        // pedantic assertion that our ptrs will
-        // be NULL (0 ptr is mem addr 0)
-        GrAssert((intptr_t)(void*)NULL == 0LL);
-
-        // default stencil setting should be disabled
-        GrAssert(fStencilSettings.isDisabled());
-        fFirstCoverageStage = kNumStages;
+    /**
+     * 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;
     }
 
-    uint8_t                 fFlagBits;
-    GrBlendCoeff            fSrcBlend : 8;
-    GrBlendCoeff            fDstBlend : 8;
-    DrawFace                fDrawFace : 8;
-    uint8_t                 fFirstCoverageStage;
-    SkXfermode::Mode        fColorFilterXfermode : 8;
-    GrColor                 fBlendConstant;
-    GrTexture*              fTextures[kNumStages];
-    GrRenderTarget*         fRenderTarget;
-    GrColor                 fColor;
-    GrColor                 fColorFilterColor;
+    int getNumAAEdges() const { return fEdgeAANumEdges; }
 
-    GrStencilSettings       fStencilSettings;
-    GrMatrix                fViewMatrix;
+    const Edge* getAAEdges() const { return fEdgeAAEdges; }
 
-    // @{ Data for GrTesselatedPathRenderer
-    // TODO: currently ignored in copying & comparison for performance.
-    // Must be considered if GrTesselatedPathRenderer is being used.
+    /// @}
 
-    int                     fEdgeAANumEdges;
-    VertexEdgeType          fVertexEdgeType;
-    Edge                    fEdgeAAEdges[kMaxEdges];
+    ///////////////////////////////////////////////////////////////////////////
+    /// @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,
 
-    // This field must be last; it will not be copied or compared
-    // if the corresponding fTexture[] is NULL.
-    GrSamplerState          fSamplerStates[kNumStages];
+        // 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%.
@@ -172,6 +699,33 @@
     }
 
 private:
+    static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
+    uint8_t                 fFlagBits;
+    GrBlendCoeff            fSrcBlend : 8;
+    GrBlendCoeff            fDstBlend : 8;
+    DrawFace                fDrawFace : 8;
+    uint8_t                 fFirstCoverageStage;
+    SkXfermode::Mode        fColorFilterMode : 8;
+    GrColor                 fBlendConstant;
+    GrTexture*              fTextures[kNumStages];
+    GrRenderTarget*         fRenderTarget;
+    GrColor                 fColor;
+    GrColor                 fColorFilterColor;
+    GrStencilSettings       fStencilSettings;
+    GrMatrix                fViewMatrix;
+    // @{ Data for GrTesselatedPathRenderer
+    // TODO: currently ignored in copying & comparison for performance.
+    // Must be considered if GrTesselatedPathRenderer is being used.
+
+    VertexEdgeType          fVertexEdgeType;
+    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
@@ -184,4 +738,3 @@
 };
 
 #endif
-