Make GrDrawState a real class with getters and setters
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 8 Dec 2011 15:53:53 +0000 (15:53 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 8 Dec 2011 15:53:53 +0000 (15:53 +0000)
Review URL: http://codereview.appspot.com/5448119/

git-svn-id: http://skia.googlecode.com/svn/trunk@2830 2bbb7eff-a529-9590-31e7-b0007b416f81

13 files changed:
src/gpu/GrAAHairLinePathRenderer.cpp
src/gpu/GrContext.cpp
src/gpu/GrDefaultPathRenderer.cpp
src/gpu/GrDrawState.h
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrGpu.cpp
src/gpu/GrGpu.h
src/gpu/GrGpuGL.cpp
src/gpu/GrGpuGLShaders.cpp
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrTesselatedPathRenderer.cpp
src/gpu/GrTextContext.cpp

index e306b67..1806797 100644 (file)
@@ -702,7 +702,8 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) {
     int nBufLines = fLinesIndexBuffer->maxQuads();
     while (lines < fLineSegmentCnt) {
         int n = GrMin(fLineSegmentCnt-lines, nBufLines);
-        fTarget->setVertexEdgeType(GrDrawState::kHairLine_EdgeType);
+        fTarget->drawState()->setVertexEdgeType(
+            GrDrawState::kHairLine_EdgeType);
         fTarget->drawIndexed(kTriangles_PrimitiveType,
                              kVertsPerLineSeg*lines,    // startV
                              0,                         // startI
@@ -715,7 +716,8 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) {
     int quads = 0;
     while (quads < fQuadCnt) {
         int n = GrMin(fQuadCnt-quads, kNumQuadsInIdxBuffer);
-        fTarget->setVertexEdgeType(GrDrawState::kHairQuad_EdgeType);
+        fTarget->drawState()->setVertexEdgeType(
+            GrDrawState::kHairQuad_EdgeType);
         fTarget->drawIndexed(kTriangles_PrimitiveType,
                              4*fLineSegmentCnt + kVertsPerQuad*quads, // startV
                              0,                                       // startI
index de80f65..a792bd1 100644 (file)
@@ -217,21 +217,17 @@ void gen_stencil_key_values(const GrStencilBuffer* sb,
 // It does not reset stage textures/samplers or per-vertex-edge-aa state since
 // they aren't used unless the vertex layout references them.
 // It also doesn't set the render target.
-void reset_target_state(GrDrawTarget* target){
-        target->setViewMatrix(GrMatrix::I());
-        target->setColorFilter(0, SkXfermode::kDst_Mode);
-        target->disableState(GrDrawTarget::kDither_StateBit |
-                             GrDrawTarget::kHWAntialias_StateBit |
-                             GrDrawTarget::kClip_StateBit |
-                             GrDrawTarget::kNoColorWrites_StateBit |
-                             GrDrawTarget::kEdgeAAConcave_StateBit);
-        target->setEdgeAAData(NULL, 0);
-        target->disableStencil();
-        target->setAlpha(0xFF);
-        target->setBlendFunc(kOne_BlendCoeff,
-                           kZero_BlendCoeff);
-        target->setFirstCoverageStage(GrDrawState::kNumStages);
-        target->setDrawFace(GrDrawState::kBoth_DrawFace);
+void reset_target_state(GrDrawState* drawState) {
+        drawState->setViewMatrix(GrMatrix::I());
+        drawState->setColorFilter(0, SkXfermode::kDst_Mode);
+        drawState->resetStateFlags();
+        drawState->setEdgeAAData(NULL, 0);
+        drawState->disableStencil();
+        drawState->setAlpha(0xFF);
+        drawState->setBlendFunc(kOne_BlendCoeff,
+                                kZero_BlendCoeff);
+        drawState->setFirstCoverageStage(GrDrawState::kNumStages);
+        drawState->setDrawFace(GrDrawState::kBoth_DrawFace);
 }
 }
 
@@ -352,7 +348,7 @@ GrContext::TextureCacheEntry GrContext::createAndLockTexture(TextureKey key,
 
         if (NULL != texture) {
             GrDrawTarget::AutoStateRestore asr(fGpu);
-            reset_target_state(fGpu);
+            reset_target_state(fGpu->drawState());
 
             fGpu->setRenderTarget(texture->asRenderTarget());
             fGpu->setTexture(0, clampEntry.texture());
@@ -601,7 +597,7 @@ const GrClip& GrContext::getClip() const { return fGpu->getClip(); }
 
 void GrContext::setClip(const GrClip& clip) {
     fGpu->setClip(clip);
-    fGpu->enableState(GrDrawTarget::kClip_StateBit);
+    fGpu->drawState()->enableState(GrDrawState::kClip_StateBit);
 }
 
 void GrContext::setClip(const GrIRect& rect) {
@@ -806,14 +802,13 @@ void GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
     target->enableState(GrDrawTarget::kHWAntialias_StateBit);
 #endif
 
-    GrMatrix transM;
     int left = boundRect.fLeft + tileX * record->fTileSizeX;
     int top =  boundRect.fTop  + tileY * record->fTileSizeY;
-    transM.setTranslate(-left * GR_Scalar1, -top * GR_Scalar1);
-    target->postConcatViewMatrix(transM);
-    GrMatrix scaleM;
-    scaleM.setScale(record->fScale * GR_Scalar1, record->fScale * GR_Scalar1);
-    target->postConcatViewMatrix(scaleM);
+    GrDrawState* drawState = target->drawState();
+    drawState->viewMatrix()->postTranslate(-left * GR_Scalar1,
+                                           -top * GR_Scalar1);
+    drawState->viewMatrix()->postScale(record->fScale * GR_Scalar1,
+                                       record->fScale * GR_Scalar1);
 
     int w = (tileX == record->fTileCountX-1) ? boundRect.fRight - left :
                                                record->fTileSizeX;
@@ -1327,7 +1322,7 @@ void GrContext::drawRect(const GrPaint& paint,
         GrDrawTarget::AutoViewMatrixRestore avmr;
         if (NULL != matrix) {
             avmr.set(target);
-            target->preConcatViewMatrix(*matrix);
+            target->viewMatrix()->preConcat(*matrix);
             target->preConcatSamplerMatrices(stageMask, *matrix);
         }
 
@@ -1351,7 +1346,7 @@ void GrContext::drawRect(const GrPaint& paint,
                 m.postConcat(*matrix);
             }
 
-            target->preConcatViewMatrix(m);
+            target->viewMatrix()->preConcat(m);
             target->preConcatSamplerMatrices(stageMask, m);
  
             target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
@@ -1378,7 +1373,8 @@ void GrContext::drawRectToRect(const GrPaint& paint,
 
 #if GR_STATIC_RECT_VB
     GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-    
+    GrDrawState* drawState = target->drawState();
+
     GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
     GrDrawTarget::AutoViewMatrixRestore avmr(target);
 
@@ -1390,13 +1386,13 @@ void GrContext::drawRectToRect(const GrPaint& paint,
     if (NULL != dstMatrix) {
         m.postConcat(*dstMatrix);
     }
-    target->preConcatViewMatrix(m);
+    drawState->viewMatrix()->preConcat(m);
 
     // srcRect refers to first stage
     int otherStageMask = paint.getActiveStageMask() & 
                          (~(1 << GrPaint::kFirstTextureStage));
     if (otherStageMask) {
-        target->preConcatSamplerMatrices(otherStageMask, m);
+        drawState->preConcatSamplerMatrices(otherStageMask, m);
     }
 
     m.setAll(srcRect.width(), 0,                srcRect.fLeft,
@@ -1405,7 +1401,7 @@ void GrContext::drawRectToRect(const GrPaint& paint,
     if (NULL != srcMatrix) {
         m.postConcat(*srcMatrix);
     }
-    target->preConcatSamplerMatrix(GrPaint::kFirstTextureStage, m);
+    drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m);
 
     const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
     if (NULL == sqVB) {
@@ -1781,7 +1777,7 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
         GrAssert(NULL != target);
 
         GrDrawTarget::AutoStateRestore asr(fGpu);
-        reset_target_state(fGpu);
+        reset_target_state(fGpu->drawState());
 
         fGpu->setRenderTarget(target);
 
@@ -1819,7 +1815,7 @@ void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
     ASSERT_OWNED_RESOURCE(src);
 
     GrDrawTarget::AutoStateRestore asr(fGpu);
-    reset_target_state(fGpu);
+    reset_target_state(fGpu->drawState());
     fGpu->setRenderTarget(dst);
     GrSamplerState sampler(GrSamplerState::kClamp_WrapMode,
                            GrSamplerState::kNearest_Filter);
@@ -1889,7 +1885,7 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
                                      config, buffer, rowBytes, flags);
 
     GrDrawTarget::AutoStateRestore  asr(fGpu);
-    reset_target_state(fGpu);
+    reset_target_state(fGpu->drawState());
 
     GrMatrix matrix;
     matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
@@ -1920,6 +1916,8 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
 
 void GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) {
 
+    GrDrawState* drawState = target->drawState();
+
     for (int i = 0; i < GrPaint::kMaxTextures; ++i) {
         int s = i + GrPaint::kFirstTextureStage;
         target->setTexture(s, paint.getTexture(i));
@@ -1936,20 +1934,20 @@ void GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) {
         target->setSamplerState(s, paint.getMaskSampler(i));
     }
 
-    target->setColor(paint.fColor);
+    drawState->setColor(paint.fColor);
 
     if (paint.fDither) {
-        target->enableState(GrDrawTarget::kDither_StateBit);
+        drawState->enableState(GrDrawState::kDither_StateBit);
     } else {
-        target->disableState(GrDrawTarget::kDither_StateBit);
+        drawState->disableState(GrDrawState::kDither_StateBit);
     }
     if (paint.fAntiAlias) {
-        target->enableState(GrDrawTarget::kHWAntialias_StateBit);
+        drawState->enableState(GrDrawState::kHWAntialias_StateBit);
     } else {
-        target->disableState(GrDrawTarget::kHWAntialias_StateBit);
+        drawState->disableState(GrDrawState::kHWAntialias_StateBit);
     }
-    target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
-    target->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
+    drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
+    drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
 
     if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) {
         GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
@@ -2020,7 +2018,7 @@ void GrContext::setMatrix(const GrMatrix& m) {
 }
 
 void GrContext::concatMatrix(const GrMatrix& m) const {
-    fGpu->preConcatViewMatrix(m);
+    fGpu->viewMatrix()->preConcat(m);
 }
 
 static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
index 197ee06..cd4e429 100644 (file)
@@ -190,7 +190,8 @@ static inline bool single_pass_path(const GrDrawTarget& target,
         return hint == kConvex_ConvexHint ||
                hint == kNonOverlappingConvexPieces_ConvexHint ||
                (hint == kSameWindingConvexPieces_ConvexHint &&
-                !target.drawWillReadDst() && !target.isDitherState());
+                !target.drawWillReadDst() &&
+                !target.getDrawState().isDitherState());
 
     }
     return false;
@@ -388,6 +389,8 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
     GrScalar tol = GR_Scalar1;
     tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds());
 
+    GrDrawState* drawState = fTarget->drawState();
+
     // FIXME: It's really dumb that we recreate the verts for a new vertex
     // layout. We only do that because the GrDrawTarget API doesn't allow
     // us to change the vertex layout after reserveVertexSpace(). We won't
@@ -405,9 +408,9 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
 
     GrAssert(NULL != fTarget);
     GrDrawTarget::AutoStateRestore asr(fTarget);
-    bool colorWritesWereDisabled = fTarget->isColorWriteDisabled();
+    bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
     // face culling doesn't make sense here
-    GrAssert(GrDrawState::kBoth_DrawFace == fTarget->getDrawFace());
+    GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
 
     int                         passCount = 0;
     const GrStencilSettings*    passes[3];
@@ -503,36 +506,37 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
 
     {
     for (int p = 0; p < passCount; ++p) {
-        fTarget->setDrawFace(drawFace[p]);
+        drawState->setDrawFace(drawFace[p]);
         if (NULL != passes[p]) {
-            fTarget->setStencil(*passes[p]);
+            drawState->setStencil(*passes[p]);
         }
 
         if (lastPassIsBounds && (p == passCount-1)) {
             if (!colorWritesWereDisabled) {
-                fTarget->disableState(GrDrawTarget::kNoColorWrites_StateBit);
+                drawState->disableState(
+                    GrDrawState::kNoColorWrites_StateBit);
             }
             GrRect bounds;
             if (reverse) {
-                GrAssert(NULL != fTarget->getRenderTarget());
+                GrAssert(NULL != drawState->getRenderTarget());
                 // draw over the whole world.
                 bounds.setLTRB(0, 0,
-                               GrIntToScalar(fTarget->getRenderTarget()->width()),
-                               GrIntToScalar(fTarget->getRenderTarget()->height()));
+                               GrIntToScalar(drawState->getRenderTarget()->width()),
+                               GrIntToScalar(drawState->getRenderTarget()->height()));
                 GrMatrix vmi;
                 // mapRect through persp matrix may not be correct
-                if (!fTarget->getViewMatrix().hasPerspective() &&
-                    fTarget->getViewInverse(&vmi)) {
+                if (!drawState->getViewMatrix().hasPerspective() &&
+                    drawState->getViewInverse(&vmi)) {
                     vmi.mapRect(&bounds);
                 } else {
                     if (stageMask) {
-                        if (!fTarget->getViewInverse(&vmi)) {
+                        if (!drawState->getViewInverse(&vmi)) {
                             GrPrintf("Could not invert matrix.");
                             return;
                         }
-                        fTarget->preConcatSamplerMatrices(stageMask, vmi);
+                        drawState->preConcatSamplerMatrices(stageMask, vmi);
                     }
-                    fTarget->setViewMatrix(GrMatrix::I());
+                    drawState->setViewMatrix(GrMatrix::I());
                 }
             } else {
                 bounds = fPath->getBounds();
@@ -542,7 +546,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
             fTarget->drawSimpleRect(bounds, NULL, stageMask);
         } else {
             if (passCount > 1) {
-                fTarget->enableState(GrDrawTarget::kNoColorWrites_StateBit);
+                drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
             }
             if (fUseIndexedDraw) {
                 fTarget->drawIndexed(fPrimitiveType, 0, 0, 
index 90de1a3..8be4f3f 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "GrColor.h"
 #include "GrMatrix.h"
+#include "GrNoncopyable.h"
 #include "GrSamplerState.h"
 #include "GrStencil.h"
 
@@ -45,13 +46,386 @@ struct GrDrawState {
     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 fSamplers[stage];
+    }
+
+    /**
+     * Writable pointer to a stage's sampler.
+     */
+    GrSamplerState* sampler(int stage) {
+        GrAssert((unsigned)stage < kNumStages);
+        return fSamplers + 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) {
+                fSamplers[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;
+    }
+
+    /// @}
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @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) {
+            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 +440,19 @@ struct GrDrawState {
     };
 
     /**
+     * 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 +478,146 @@ struct GrDrawState {
         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;
+    /**
+     * 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;
+    }
 
-        // pedantic assertion that our ptrs will
-        // be NULL (0 ptr is mem addr 0)
-        GrAssert((intptr_t)(void*)NULL == 0LL);
+    int getNumAAEdges() const { return fEdgeAANumEdges; }
 
-        // default stencil setting should be disabled
-        GrAssert(fStencilSettings.isDisabled());
-        fFirstCoverageStage = kNumStages;
+    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,
+
+        // Users of the class may add additional bits to the vector
+        kDummyStateBit,
+        kLastPublicStateBit = kDummyStateBit-1,
+    };
+
+    void resetStateFlags() {
+        fFlagBits = 0;
     }
 
-    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;
+    /**
+     * Enable render state settings.
+     *
+     * @param flags   bitfield of StateBits specifing the states to enable
+     */
+    void enableState(uint32_t stateBits) {
+        fFlagBits |= stateBits;
+    }
 
-    GrStencilSettings       fStencilSettings;
-    GrMatrix                fViewMatrix;
+    /**
+     * Disable render state settings.
+     *
+     * @param flags   bitfield of StateBits specifing the states to disable
+     */
+    void disableState(uint32_t stateBits) {
+        fFlagBits &= ~(stateBits);
+    }
 
-    // @{ Data for GrTesselatedPathRenderer
-    // TODO: currently ignored in copying & comparison for performance.
-    // Must be considered if GrTesselatedPathRenderer is being used.
+    bool isDitherState() const {
+        return 0 != (fFlagBits & kDither_StateBit);
+    }
 
-    int                     fEdgeAANumEdges;
-    VertexEdgeType          fVertexEdgeType;
-    Edge                    fEdgeAAEdges[kMaxEdges];
+    bool isHWAntialiasState() const {
+        return 0 != (fFlagBits & kHWAntialias_StateBit);
+    }
 
-    // @}
+    bool isClipState() const {
+        return 0 != (fFlagBits & kClip_StateBit);
+    }
 
-    // This field must be last; it will not be copied or compared
-    // if the corresponding fTexture[] is NULL.
-    GrSamplerState          fSamplerStates[kNumStages];
+    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%.
@@ -146,7 +626,7 @@ struct GrDrawState {
 
         for (int i = 0; i < kNumStages; i++) {
             if (fTextures[i] &&
-                memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
+                memcmp(&this->fSamplers[i], &s.fSamplers[i],
                        sizeof(GrSamplerState))) {
                 return false;
             }
@@ -163,7 +643,7 @@ struct GrDrawState {
 
         for (int i = 0; i < kNumStages; i++) {
             if (s.fTextures[i]) {
-                memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
+                memcpy(&this->fSamplers[i], &s.fSamplers[i],
                        sizeof(GrSamplerState));
             }
         }
@@ -172,6 +652,36 @@ struct GrDrawState {
     }
 
 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.
+
+    int                     fEdgeAANumEdges;
+    VertexEdgeType          fVertexEdgeType;
+    Edge                    fEdgeAAEdges[kMaxEdges];
+
+    // @}
+
+    // This field must be last; it will not be copied or compared
+    // if the corresponding fTexture[] is NULL.
+    GrSamplerState          fSamplers[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 +694,3 @@ private:
 };
 
 #endif
-
index 7a84262..2d1563d 100644 (file)
@@ -455,119 +455,6 @@ const GrClip& GrDrawTarget::getClip() const {
     return fClip;
 }
 
-void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
-    GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
-    fCurrDrawState.fTextures[stage] = tex;
-}
-
-const GrTexture* GrDrawTarget::getTexture(int stage) const {
-    GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
-    return fCurrDrawState.fTextures[stage];
-}
-
-GrTexture* GrDrawTarget::getTexture(int stage) {
-    GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
-    return fCurrDrawState.fTextures[stage];
-}
-
-void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
-    fCurrDrawState.fRenderTarget = target;
-}
-
-const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
-    return fCurrDrawState.fRenderTarget;
-}
-
-GrRenderTarget* GrDrawTarget::getRenderTarget() {
-    return fCurrDrawState.fRenderTarget;
-}
-
-void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
-    fCurrDrawState.fViewMatrix = m;
-}
-
-void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
-    fCurrDrawState.fViewMatrix.preConcat(matrix);
-}
-
-void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
-    fCurrDrawState.fViewMatrix.postConcat(matrix);
-}
-
-const GrMatrix& GrDrawTarget::getViewMatrix() const {
-    return fCurrDrawState.fViewMatrix;
-}
-
-bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
-    // Mike:  Can we cache this somewhere?
-    // Brian: Sure, do we use it often?
-
-    GrMatrix inverse;
-    if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
-        if (matrix) {
-            *matrix = inverse;
-        }
-        return true;
-    }
-    return false;
-}
-
-void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
-    GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
-    fCurrDrawState.fSamplerStates[stage] = state;
-}
-
-void GrDrawTarget::enableState(uint32_t bits) {
-    fCurrDrawState.fFlagBits |= bits;
-}
-
-void GrDrawTarget::disableState(uint32_t bits) {
-    fCurrDrawState.fFlagBits &= ~(bits);
-}
-
-void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
-                                GrBlendCoeff dstCoeff) {
-    fCurrDrawState.fSrcBlend = srcCoeff;
-    fCurrDrawState.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
-}
-
-void GrDrawTarget::setColor(GrColor c) {
-    fCurrDrawState.fColor = c;
-}
-
-void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
-    fCurrDrawState.fColorFilterColor = c;
-    fCurrDrawState.fColorFilterXfermode = mode;
-}
-
-void GrDrawTarget::setAlpha(uint8_t a) {
-    this->setColor((a << 24) | (a << 16) | (a << 8) | a);
-}
-
 void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
     state->fState = fCurrDrawState;
 }
@@ -804,8 +691,8 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
         return false;
     }
     if (GrPixelConfigIsUnpremultiplied(this->getRenderTarget()->config())) {
-        if (kOne_BlendCoeff != fCurrDrawState.fSrcBlend ||
-            kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
+        if (kOne_BlendCoeff != getDrawState().getSrcBlendCoeff() ||
+            kZero_BlendCoeff != getDrawState().getDstBlendCoeff()) {
             return false;
         }
     }
@@ -817,8 +704,8 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
         // a custom bilerp in the shader. Until Skia itself supports unpremul
         // configs there is no pressure to implement this.
         if (this->isStageEnabled(s) &&
-            GrPixelConfigIsUnpremultiplied(fCurrDrawState.fTextures[s]->config()) &&
-            GrSamplerState::kNearest_Filter != fCurrDrawState.fSamplerStates[s].getFilter()) {
+            GrPixelConfigIsUnpremultiplied(this->getTexture(s)->config()) &&
+            GrSamplerState::kNearest_Filter != this->getSampler(s).getFilter()) {
             return false;
         }
     }
@@ -861,9 +748,10 @@ bool GrDrawTarget::canTweakAlphaForCoverage() const {
      * for Cd we find that only 1, ISA, and ISC produce the correct depth
      * coeffecient in terms of S' and D.
      */
-    return kOne_BlendCoeff == fCurrDrawState.fDstBlend||
-           kISA_BlendCoeff == fCurrDrawState.fDstBlend ||
-           kISC_BlendCoeff == fCurrDrawState.fDstBlend;
+    GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff();
+    return kOne_BlendCoeff == dstCoeff ||
+           kISA_BlendCoeff == dstCoeff ||
+           kISC_BlendCoeff == dstCoeff;
 }
 
 
@@ -872,20 +760,21 @@ bool GrDrawTarget::srcAlphaWillBeOne() const {
 
     // Check if per-vertex or constant color may have partial alpha
     if ((layout & kColor_VertexLayoutBit) ||
-        0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
+        0xff != GrColorUnpackA(this->getColor())) {
         return false;
     }
     // Check if color filter could introduce an alpha
     // (TODO: Consider being more aggressive with regards to detecting 0xff
     // final alpha from color filter).
-    if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) {
+    if (SkXfermode::kDst_Mode != this->getDrawState().getColorFilterMode()) {
         return false;
     }
     // Check if a color stage could create a partial alpha
-    for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) {
+    int firstCoverageStage = this->getFirstCoverageStage();
+    for (int s = 0; s < firstCoverageStage; ++s) {
         if (StageWillBeUsed(s, layout, fCurrDrawState)) {
-            GrAssert(NULL != fCurrDrawState.fTextures[s]);
-            GrPixelConfig config = fCurrDrawState.fTextures[s]->config();
+            GrAssert(NULL != this->getTexture(s));
+            GrPixelConfig config = this->getTexture(s)->config();
             if (!GrPixelConfigIsOpaque(config)) {
                 return false;
             }
@@ -905,12 +794,12 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
     if (NULL == srcCoeff) {
         srcCoeff = &bogusSrcCoeff;
     }
-    *srcCoeff = fCurrDrawState.fSrcBlend;
+    *srcCoeff = this->getDrawState().getSrcBlendCoeff();
 
     if (NULL == dstCoeff) {
         dstCoeff = &bogusDstCoeff;
     }
-    *dstCoeff = fCurrDrawState.fDstBlend;
+    *dstCoeff = this->getDrawState().getDstBlendCoeff();
 
     // We don't ever expect source coeffecients to reference the source
     GrAssert(kSA_BlendCoeff != *srcCoeff &&
@@ -923,7 +812,7 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
              kDC_BlendCoeff != *dstCoeff &&
              kIDC_BlendCoeff != *dstCoeff);
 
-    if (SkToBool(kNoColorWrites_StateBit & fCurrDrawState.fFlagBits)) {
+    if (this->getDrawState().isColorWriteDisabled()) {
         *srcCoeff = kZero_BlendCoeff;
         *dstCoeff = kOne_BlendCoeff;
     }
@@ -939,7 +828,7 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
     // stenciling is enabled. Having color writes disabled is effectively
     // (0,1).
     if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne)) {
-        if (fCurrDrawState.fStencilSettings.doesWrite()) {
+        if (this->getDrawState().getStencil().doesWrite()) {
             if (fCaps.fShaderSupport) {
                 return kDisableBlend_BlendOptFlag |
                        kEmitTransBlack_BlendOptFlag;
@@ -953,10 +842,10 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
 
     // check for coverage due to edge aa or coverage texture stage
     bool hasCoverage = forceCoverage ||
-                       fCurrDrawState.fEdgeAANumEdges > 0 ||
+                       this->getDrawState().getNumAAEdges() > 0 ||
                        (layout & kCoverage_VertexLayoutBit) ||
                        (layout & kEdge_VertexLayoutBit);
-    for (int s = fCurrDrawState.fFirstCoverageStage;
+    for (int s = this->getFirstCoverageStage();
          !hasCoverage && s < GrDrawState::kNumStages;
          ++s) {
         if (StageWillBeUsed(s, layout, fCurrDrawState)) {
@@ -1023,7 +912,7 @@ bool GrDrawTarget::willUseHWAALines() const {
     // but not in a premul-alpha way. So we only use them when our alpha
     // is 0xff and tweaking the color for partial coverage is OK
     if (!fCaps.fHWAALineSupport ||
-        !(kHWAntialias_StateBit & fCurrDrawState.fFlagBits)) {
+        !(this->getDrawState().isHWAntialiasState())) {
         return false;
     }
     BlendOptFlags opts = this->getBlendOpts();
@@ -1043,16 +932,6 @@ bool GrDrawTarget::drawWillReadDst() const {
                     this->getBlendOpts());
 }
 
-///////////////////////////////////////////////////////////////////////////////
-
-void GrDrawTarget::setEdgeAAData(const GrDrawState::Edge* edges, int numEdges) {
-    GrAssert(numEdges <= GrDrawState::kMaxEdges);
-    memcpy(fCurrDrawState.fEdgeAAEdges, edges,
-           numEdges * sizeof(GrDrawState::Edge));
-    fCurrDrawState.fEdgeAANumEdges = numEdges;
-}
-
-
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrDrawTarget::drawRect(const GrRect& rect, 
@@ -1068,13 +947,13 @@ void GrDrawTarget::drawRect(const GrRect& rect,
         return;
     }
 
-    SetRectVertices(rect, matrix, srcRects, 
+    SetRectVertices(rect, matrix, srcRects,
                     srcMatrices, layout, geo.vertices());
 
     drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
 }
 
-GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask, 
+GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask,
                                                  const GrRect* srcRects[]) {
     GrVertexLayout layout = 0;
 
@@ -1183,7 +1062,7 @@ GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(
         if (fViewMatrix.invert(&invVM)) {
             for (int s = 0; s < GrDrawState::kNumStages; ++s) {
                 if (fStageMask & (1 << s)) {
-                    fSamplerMatrices[s] = target->getSamplerMatrix(s);
+                    fSamplerMatrices[s] = target->getSampler(s).getMatrix();
                 }
             }
             target->preConcatSamplerMatrices(fStageMask, invVM);
@@ -1199,7 +1078,8 @@ GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
     fDrawTarget->setViewMatrix(fViewMatrix);
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         if (fStageMask & (1 << s)) {
-            fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]);
+            GrSamplerState* sampler = fDrawTarget->drawState()->sampler(s);
+            sampler->setMatrix(fSamplerMatrices[s]);
         }
     }
 }
index 4bd9eee..b72fb3a 100644 (file)
@@ -57,62 +57,9 @@ public:
         int fMaxTextureSize;
     };
 
+    // for convenience
     typedef GrDrawState::StageMask StageMask;
 
-    /**
-     *  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,
-        // subclass may use additional bits internally
-        kDummyStateBit,
-        kLastPublicStateBit = kDummyStateBit-1
-    };
-
-    /**
-     * 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) {
-        fCurrDrawState.fStencilSettings = settings;
-    }
-
-    /**
-     * Shortcut to disable stencil testing and ops.
-     */
-    void disableStencil() {
-        fCurrDrawState.fStencilSettings.setDisabled();
-    }
-
-public:
     ///////////////////////////////////////////////////////////////////////////
 
     GrDrawTarget();
@@ -141,285 +88,6 @@ public:
     const GrClip& getClip() const;
 
     /**
-     * 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);
-
-    /**
-     * 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;
-    GrTexture* getTexture(int stage);
-
-    /**
-     * Sets the rendertarget used at the next drawing call
-     *
-     * @param target  The render target to set.
-     */
-    void setRenderTarget(GrRenderTarget* target);
-
-    /**
-     * Retrieves the currently set rendertarget.
-     *
-     * @return    The currently set render target.
-     */
-    const GrRenderTarget* getRenderTarget() const;
-    GrRenderTarget* getRenderTarget();
-
-    /**
-     * Sets the sampler state for a stage used in subsequent draws.
-     *
-     * The sampler state determines how texture coordinates are
-     * intepretted and used to sample the texture.
-     *
-     * @param stage           the stage of the sampler to set
-     * @param samplerState    Specifies the sampler state.
-     */
-    void setSamplerState(int stage, const GrSamplerState& samplerState);
-
-    /**
-     * Concats the matrix of a stage's sampler.
-     *
-     * @param stage   the stage of the sampler to set
-     * @param matrix  the matrix to concat
-     */
-    void preConcatSamplerMatrix(int stage, const GrMatrix& matrix)  {
-        GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
-        fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
-    }
-
-    /**
-     * Shortcut for preConcatSamplerMatrix on all stages in mask with same
-     * matrix
-     */
-    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
-        for (int i = 0; i < GrDrawState::kNumStages; ++i) {
-            if ((1 << i) & stageMask) {
-                this->preConcatSamplerMatrix(i, matrix);
-            }
-        }
-    }
-
-    /**
-     * Shortcut for preConcatSamplerMatrix on all enabled stages in mask with
-     * same matrix
-     *
-     * @param stage   the stage of the sampler to set
-     * @param matrix  the matrix to concat
-     */
-    void preConcatEnabledSamplerMatrices(const GrMatrix& matrix) {
-        StageMask stageMask = this->enabledStages();
-        this->preConcatSamplerMatrices(stageMask, matrix);
-    }
-
-    /**
-     * Gets the matrix of a stage's sampler
-     *
-     * @param stage     the stage to of sampler to get
-     * @return the sampler state's matrix
-     */
-    const GrMatrix& getSamplerMatrix(int stage) const {
-        return fCurrDrawState.fSamplerStates[stage].getMatrix();
-    }
-
-    /**
-     * Sets the matrix of a stage's sampler
-     *
-     * @param stage     the stage of sampler set
-     * @param matrix    the matrix to set
-     */
-    void setSamplerMatrix(int stage, const GrMatrix& matrix) {
-        fCurrDrawState.fSamplerStates[stage].setMatrix(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.)
-     *
-     * @param m the matrix used to transform the vertex positions.
-     */
-    void setViewMatrix(const GrMatrix& m);
-
-    /**
-     *  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);
-
-    /**
-     *  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);
-
-    /**
-     * Retrieves the current view matrix
-     * @return the current view matrix.
-     */
-    const GrMatrix& getViewMatrix() const;
-
-    /**
-     *  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;
-
-    /**
-     *  Sets color for next draw to a premultiplied-alpha color.
-     *
-     *  @param the color to set.
-     */
-    void setColor(GrColor);
-
-    /**
-     * Gets the currently set color.
-     * @return the current color.
-     */
-    GrColor getColor() const { return fCurrDrawState.fColor; }
-
-    /**
-     * Add a color filter that can be represented by a color and a mode.
-     */
-    void setColorFilter(GrColor, SkXfermode::Mode);
-
-    /**
-     *  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 alpha);
-
-    /**
-     * Controls whether clockwise, counterclockwise, or both faces are drawn.
-     * @param face  the face(s) to draw.
-     */
-    void setDrawFace(GrDrawState::DrawFace face) {
-        fCurrDrawState.fDrawFace = face;
-    }
-
-    /**
-     * 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 GrDrawState::kNumStages (all stages
-     * are color-computing).
-     */
-    void setFirstCoverageStage(int firstCoverageStage) { 
-        fCurrDrawState.fFirstCoverageStage = firstCoverageStage; 
-    }
-
-    /**
-     * Gets the index of the first coverage-computing stage.
-     */
-    int getFirstCoverageStage() const { 
-        return fCurrDrawState.fFirstCoverageStage; 
-    }
-
-    /**
-     * Gets whether the target is drawing clockwise, counterclockwise,
-     * or both faces.
-     * @return the current draw face(s).
-     */
-    GrDrawState::DrawFace getDrawFace() const {
-        return fCurrDrawState.fDrawFace;
-    }
-
-    /**
-     * Enable render state settings.
-     *
-     * @param flags   bitfield of StateBits specifing the states to enable
-     */
-    void enableState(uint32_t stateBits);
-
-    /**
-     * Disable render state settings.
-     *
-     * @param flags   bitfield of StateBits specifing the states to disable
-     */
-    void disableState(uint32_t stateBits);
-
-    bool isDitherState() const {
-        return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
-    }
-
-    bool isHWAntialiasState() const {
-        return 0 != (fCurrDrawState.fFlagBits & kHWAntialias_StateBit);
-    }
-
-    bool isClipState() const {
-        return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
-    }
-
-    bool isColorWriteDisabled() const {
-        return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
-    }
-
-    /**
-     * 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);
-
-    /**
-     * 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) { fCurrDrawState.fBlendConstant = constant; }
-
-    /**
-     * Retrieves the last value set by setBlendConstant()
-     * @return the blending constant value
-     */
-    GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
-
-    /**
      * Determines if blending will require a read of a dst given the current
      * state set on the draw target
      *
@@ -448,15 +116,6 @@ public:
      */
     bool canTweakAlphaForCoverage() const;
 
-     /**
-      * Determines the interpretation per-vertex edge data when the
-      * kEdge_VertexLayoutBit is set (see below). When per-vertex edges are not
-      * specified the value of this setting has no effect.
-      */
-    void setVertexEdgeType(GrDrawState::VertexEdgeType type) {
-        fCurrDrawState.fVertexEdgeType = type;
-    }
-
     /**
      * Given the current draw state, vertex layout, and hw support, will HW AA
      * lines be used (if line primitive type is drawn)? (Note that lines are
@@ -464,13 +123,70 @@ public:
      */
     bool willUseHWAALines() const;
 
-    /**
-     * Sets the edge data required for edge antialiasing.
-     *
-     * @param edges       3 * 6 float values, representing the edge
-     *                    equations in Ax + By + C form
-     */
-    void setEdgeAAData(const GrDrawState::Edge* edges, int numEdges);
+    const GrDrawState& getDrawState() const { return fCurrDrawState; }
+    GrDrawState* drawState() { return &fCurrDrawState; }
+
+    // Convenience Pass-thrus to GrDrawState. These are likely candidates for
+    // removal.
+    void setViewMatrix(const GrMatrix& m) {
+        this->drawState()->setViewMatrix(m);
+    }
+    GrMatrix* viewMatrix() {
+        return this->drawState()->viewMatrix();
+    }
+    const GrMatrix& getViewMatrix() const {
+        return this->getDrawState().getViewMatrix();
+    }
+    bool getViewInverse(GrMatrix* inv) const {
+        return this->getDrawState().getViewInverse(inv);
+    }
+    void setRenderTarget(GrRenderTarget* renderTarget) {
+        this->drawState()->setRenderTarget(renderTarget);
+    }
+    const GrRenderTarget* getRenderTarget() const {
+        return this->getDrawState().getRenderTarget();
+    }
+    GrRenderTarget* getRenderTarget() {
+        return this->drawState()->getRenderTarget();
+    }
+    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+        this->drawState()->setBlendFunc(srcCoeff, dstCoeff);
+    }
+    void setTexture(int stage, GrTexture* texture) {
+        this->drawState()->setTexture(stage, texture);
+    }
+    const GrTexture* getTexture(int stage) const {
+        return this->getDrawState().getTexture(stage);
+    }
+    GrTexture* getTexture(int stage) {
+        return this->drawState()->getTexture(stage);
+    }
+    // THIS WILL BE REMOVED AND REPLACED WITH DIRECT ACCESS TO SAMPLER
+    // IN A COMING REVISION.
+    void setSamplerState(int stage, const GrSamplerState& sampler) {
+        *(this->drawState()->sampler(stage)) = sampler;
+    }
+    const GrSamplerState& getSampler(int stage) const {
+        return this->getDrawState().getSampler(stage);
+    }
+    void preConcatSamplerMatrices(StageMask stageMask,
+                                  const GrMatrix& m) {
+        this->drawState()->preConcatSamplerMatrices(stageMask, m);
+    }
+    GrColor getColor() const { return this->getDrawState().getColor(); }
+    void setColor(GrColor color) { this->drawState()->setColor(color); }
+    void setFirstCoverageStage(int firstCoverageStage) {
+        this->drawState()->setFirstCoverageStage(firstCoverageStage);
+    }
+    int getFirstCoverageStage() const {
+        return this->getDrawState().getFirstCoverageStage();
+    }
+    void setDrawFace(const GrDrawState::DrawFace face) {
+        this->drawState()->setDrawFace(face);
+    }
+    GrDrawState::DrawFace getDrawFace() const {
+        return this->getDrawState().getDrawFace();
+    }
 
     /**
      * Used to save and restore the GrGpu's drawing state
@@ -895,7 +611,7 @@ public:
         }
 
         AutoViewMatrixRestore(GrDrawTarget* target)
-            : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
+            : fDrawTarget(target), fMatrix(target->getViewMatrix()) {
             GrAssert(NULL != target);
         }
 
@@ -927,13 +643,14 @@ public:
      */
     class AutoDeviceCoordDraw : ::GrNoncopyable {
     public:
-        AutoDeviceCoordDraw(GrDrawTarget* target, StageMask stageMask);
+        AutoDeviceCoordDraw(GrDrawTarget* target,
+                            GrDrawState::StageMask stageMask);
         ~AutoDeviceCoordDraw();
     private:
-        GrDrawTarget*       fDrawTarget;
-        GrMatrix            fViewMatrix;
-        GrMatrix            fSamplerMatrices[GrDrawState::kNumStages];
-        int                 fStageMask;
+        GrDrawTarget*           fDrawTarget;
+        GrMatrix                fViewMatrix;
+        GrMatrix                fSamplerMatrices[GrDrawState::kNumStages];
+        GrDrawState::StageMask  fStageMask;
     };
 
     ////////////////////////////////////////////////////////////////////////////
@@ -1279,7 +996,8 @@ protected:
     // given a vertex layout and a draw state, will a stage be used?
     static bool StageWillBeUsed(int stage, GrVertexLayout layout, 
                                 const GrDrawState& state) {
-        return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
+        return NULL != state.getTexture(stage) &&
+               VertexUsesStage(stage, layout);
     }
 
     bool isStageEnabled(int stage) const {
@@ -1337,7 +1055,7 @@ protected:
 
     // Helpers for drawRect, protected so subclasses that override drawRect
     // can use them.
-    static GrVertexLayout GetRectVertexLayout(StageMask stageEnableBitfield,
+    static GrVertexLayout GetRectVertexLayout(StageMask stageMask,
                                               const GrRect* srcRects[]);
 
     static void SetRectVertices(const GrRect& rect,
index 1583630..4c0594b 100644 (file)
@@ -185,10 +185,10 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
         // We used to clear down in the GL subclass using a special purpose
         // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
         // FBO status.
-        GrRenderTarget* oldRT = fCurrDrawState.fRenderTarget;
-        fCurrDrawState.fRenderTarget = rt;
+        GrRenderTarget* oldRT = this->getRenderTarget();
+        this->setRenderTarget(rt);
         this->clearStencil();
-        fCurrDrawState.fRenderTarget = oldRT;
+        this->setRenderTarget(oldRT);
         return true;
     } else {
         return false;
@@ -530,16 +530,17 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
     const GrIRect* r = NULL;
     GrIRect clipRect;
 
+    GrRenderTarget* rt = this->getRenderTarget();
+
     // GrDrawTarget should have filtered this for us
-    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrAssert(NULL != rt);
 
-    if (fCurrDrawState.fFlagBits & kClip_StateBit) {
-        GrRenderTarget& rt = *fCurrDrawState.fRenderTarget;
+    if (this->getDrawState().isClipState()) {
 
         GrRect bounds;
         GrRect rtRect;
         rtRect.setLTRB(0, 0,
-                       GrIntToScalar(rt.width()), GrIntToScalar(rt.height()));
+                       GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
         if (fClip.hasConservativeBounds()) {
             bounds = fClip.getConservativeBounds();
             if (!bounds.intersect(rtRect)) {
@@ -560,15 +561,17 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
                          !bounds.isEmpty();
 
         // TODO: dynamically attach a SB when needed.
-        GrStencilBuffer* stencilBuffer = rt.getStencilBuffer();
+        GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
         if (fClipInStencil && NULL == stencilBuffer) {
             return false;
         }
 
+        GrDrawState* drawState = this->drawState();
+
         if (fClipInStencil &&
-            stencilBuffer->mustRenderClip(fClip, rt.width(), rt.height())) {
+            stencilBuffer->mustRenderClip(fClip, rt->width(), rt->height())) {
 
-            stencilBuffer->setLastClip(fClip, rt.width(), rt.height());
+            stencilBuffer->setLastClip(fClip, rt->width(), rt->height());
 
             // we set the current clip to the bounds so that our recursive
             // draws are scissored to them. We use the copy of the complex clip
@@ -583,9 +586,9 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
             this->setViewMatrix(GrMatrix::I());
             this->flushScissor(NULL);
 #if !VISUALIZE_COMPLEX_CLIP
-            this->enableState(kNoColorWrites_StateBit);
+            drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
 #else
-            this->disableState(kNoColorWrites_StateBit);
+            drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
 #endif
             int count = clip.getElementCount();
             int clipBit = stencilBuffer->bits();
@@ -606,7 +609,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
                 GrPathFill fill;
                 bool fillInverted;
                 // enabled at bottom of loop
-                this->disableState(kModifyStencilClip_StateBit);
+                drawState->disableState(kModifyStencilClip_StateBit);
 
                 bool canRenderDirectToStencil; // can the clip element be drawn
                                                // directly to the stencil buffer
@@ -664,11 +667,11 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
                     };
                     SET_RANDOM_COLOR
                     if (kRect_ClipType == clip.getElementType(c)) {
-                        this->setStencil(gDrawToStencil);
+                        drawState->setStencil(gDrawToStencil);
                         this->drawSimpleRect(clip.getRect(c), NULL, 0);
                     } else {
                         if (canRenderDirectToStencil) {
-                            this->setStencil(gDrawToStencil);
+                            drawState->setStencil(gDrawToStencil);
                             pr->drawPath(0);
                         } else {
                             pr->drawPathToStencil();
@@ -678,9 +681,9 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
 
                 // now we modify the clip bit by rendering either the clip
                 // element directly or a bounding rect of the entire clip.
-                this->enableState(kModifyStencilClip_StateBit);
+                drawState->enableState(kModifyStencilClip_StateBit);
                 for (int p = 0; p < passes; ++p) {
-                    this->setStencil(stencilSettings[p]);
+                    drawState->setStencil(stencilSettings[p]);
                     if (canDrawDirectToClip) {
                         if (kRect_ClipType == clip.getElementType(c)) {
                             SET_RANDOM_COLOR
index 11bf153..7b705e4 100644 (file)
@@ -327,8 +327,8 @@ public:
     }
 
 protected:
-    enum PrivateStateBits {
-        kFirstBit = (kLastPublicStateBit << 1),
+    enum PrivateDrawStateBits {
+        kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
 
         kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
                                                  // stencil bits used for
index 9f7e4ec..5df1ed1 100644 (file)
@@ -480,7 +480,7 @@ void GrGpuGL::onResetContext() {
 
     GL_CALL(Disable(GR_GL_CULL_FACE));
     GL_CALL(FrontFace(GR_GL_CCW));
-    fHWDrawState.fDrawFace = GrDrawState::kBoth_DrawFace;
+    fHWDrawState.setDrawFace(GrDrawState::kBoth_DrawFace);
 
     GL_CALL(Disable(GR_GL_DITHER));
     if (kDesktop_GrGLBinding == this->glBinding()) {
@@ -492,7 +492,7 @@ void GrGpuGL::onResetContext() {
     }
 
     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
-    fHWDrawState.fFlagBits = 0;
+    fHWDrawState.resetStateFlags();
 
     // we only ever use lines in hairline mode
     GL_CALL(LineWidth(1));
@@ -502,23 +502,22 @@ void GrGpuGL::onResetContext() {
 
     // illegal values
     //fHWDrawState.fSrcBlend = (GrBlendCoeff)(uint8_t)-1;
-    fHWDrawState.fSrcBlend = (GrBlendCoeff)0xFF;
-    fHWDrawState.fDstBlend = (GrBlendCoeff)(uint8_t)-1;
-
-    fHWDrawState.fBlendConstant = 0x00000000;
+    fHWDrawState.setBlendFunc((GrBlendCoeff)-1, (GrBlendCoeff)-1);
+    fHWDrawState.setBlendConstant(0x00000000);
     GL_CALL(BlendColor(0,0,0,0));
 
-    fHWDrawState.fColor = GrColor_ILLEGAL;
+    fHWDrawState.setColor(GrColor_ILLEGAL);
 
-    fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
+    fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
 
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        fHWDrawState.fTextures[s] = NULL;
-        fHWDrawState.fSamplerStates[s].setRadial2Params(-GR_ScalarMax,
-                                                        -GR_ScalarMax,
-                                                        true);
-        fHWDrawState.fSamplerStates[s].setMatrix(GrMatrix::InvalidMatrix());
-        fHWDrawState.fSamplerStates[s].setConvolutionParams(0, NULL, NULL);
+        fHWDrawState.setTexture(s, NULL);
+        GrSamplerState* sampler = fHWDrawState.sampler(s);
+        sampler->setRadial2Params(-GR_ScalarMax,
+                                  -GR_ScalarMax,
+                                  true);
+        sampler->setMatrix(GrMatrix::InvalidMatrix());
+        sampler->setConvolutionParams(0, NULL, NULL);
     }
 
     fHWBounds.fScissorRect.invalidate();
@@ -526,7 +525,7 @@ void GrGpuGL::onResetContext() {
     GL_CALL(Disable(GR_GL_SCISSOR_TEST));
     fHWBounds.fViewportRect.invalidate();
 
-    fHWDrawState.fStencilSettings.invalidate();
+    fHWDrawState.stencil()->invalidate();
     fHWStencilClip = false;
     fClipInStencil = false;
 
@@ -536,7 +535,7 @@ void GrGpuGL::onResetContext() {
     fHWGeometryState.fArrayPtrsDirty = true;
 
     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
-    fHWDrawState.fRenderTarget = NULL;
+    fHWDrawState.setRenderTarget(NULL);
 
     // we assume these values
     if (this->glCaps().fUnpackRowLengthSupport) {
@@ -1191,7 +1190,7 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
         GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb;
         GrGLuint rb = glsb->renderbufferID();
 
-        fHWDrawState.fRenderTarget = NULL;
+        fHWDrawState.setRenderTarget(NULL);
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
                                       GR_GL_STENCIL_ATTACHMENT,
@@ -1276,9 +1275,9 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
 }
 
 void GrGpuGL::flushScissor(const GrIRect* rect) {
-    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrAssert(this->getRenderTarget() != NULL);
     const GrGLIRect& vp =
-            ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport();
+            ((GrGLRenderTarget*)this->getRenderTarget())->getViewport();
 
     GrGLIRect scissor;
     if (NULL != rect) {
@@ -1307,15 +1306,17 @@ void GrGpuGL::flushScissor(const GrIRect* rect) {
 }
 
 void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
+    const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
     // parent class should never let us get here with no RT
-    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrAssert(rt != NULL);
+
 
     GrIRect clippedRect;
     if (NULL != rect) {
         // flushScissor expects rect to be clipped to the target.
         clippedRect = *rect;
-        GrIRect rtRect = SkIRect::MakeWH(fCurrDrawState.fRenderTarget->width(),
-                                         fCurrDrawState.fRenderTarget->height());
+        GrIRect rtRect = SkIRect::MakeWH(rt->width(),
+                                         rt->height());
         if (clippedRect.intersect(rtRect)) {
             rect = &clippedRect;
         } else {
@@ -1329,7 +1330,7 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
     static const GrGLfloat scale255 = 1.f / 255.f;
     a = GrColorUnpackA(color) * scale255;
     GrGLfloat scaleRGB = scale255;
-    if (GrPixelConfigIsUnpremultiplied(fCurrDrawState.fRenderTarget->config())) {
+    if (GrPixelConfigIsUnpremultiplied(rt->config())) {
         scaleRGB *= a;
     }
     r = GrColorUnpackR(color) * scaleRGB;
@@ -1337,13 +1338,13 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
     b = GrColorUnpackB(color) * scaleRGB;
 
     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
-    fHWDrawState.fFlagBits &= ~kNoColorWrites_StateBit;
+    fHWDrawState.disableState(GrDrawState::kNoColorWrites_StateBit);
     GL_CALL(ClearColor(r, g, b, a));
     GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
 }
 
 void GrGpuGL::clearStencil() {
-    if (NULL == fCurrDrawState.fRenderTarget) {
+    if (NULL == this->getRenderTarget()) {
         return;
     }
     
@@ -1356,17 +1357,17 @@ void GrGpuGL::clearStencil() {
     GL_CALL(StencilMask(0xffffffff));
     GL_CALL(ClearStencil(0));
     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
-    fHWDrawState.fStencilSettings.invalidate();
+    fHWDrawState.stencil()->invalidate();
 }
 
 void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
-    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrRenderTarget* rt = this->getRenderTarget();
+    GrAssert(NULL != rt);
 
     // this should only be called internally when we know we have a
     // stencil buffer.
-    GrAssert(NULL != fCurrDrawState.fRenderTarget->getStencilBuffer());
-    GrGLint stencilBitCount = 
-        fCurrDrawState.fRenderTarget->getStencilBuffer()->bits();
+    GrAssert(NULL != rt->getStencilBuffer());
+    GrGLint stencilBitCount = rt->getStencilBuffer()->bits();
 #if 0
     GrAssert(stencilBitCount > 0);
     GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
@@ -1389,7 +1390,7 @@ void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
     GL_CALL(StencilMask(clipStencilMask));
     GL_CALL(ClearStencil(value));
     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
-    fHWDrawState.fStencilSettings.invalidate();
+    fHWDrawState.stencil()->invalidate();
 }
 
 void GrGpuGL::onForceRenderTargetFlush() {
@@ -1445,13 +1446,12 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
 
     // resolve the render target if necessary
     GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
-    GrAutoTPtrValueRestore<GrRenderTarget*> autoTargetRestore;
+    GrDrawState::AutoRenderTargetRestore arr;
     switch (tgt->getResolveType()) {
         case GrGLRenderTarget::kCantResolve_ResolveType:
             return false;
         case GrGLRenderTarget::kAutoResolves_ResolveType:
-            autoTargetRestore.save(&fCurrDrawState.fRenderTarget);
-            fCurrDrawState.fRenderTarget = target;
+            arr.set(this->drawState(), target);
             this->flushRenderTarget(&GrIRect::EmptyIRect());
             break;
         case GrGLRenderTarget::kCanResolve_ResolveType:
@@ -1549,10 +1549,11 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
 
 void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
 
-    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrAssert(this->getRenderTarget() != NULL);
 
-    GrGLRenderTarget* rt = (GrGLRenderTarget*)fCurrDrawState.fRenderTarget;
-    if (fHWDrawState.fRenderTarget != fCurrDrawState.fRenderTarget) {
+    GrGLRenderTarget* rt =
+        static_cast<GrGLRenderTarget*>(this->getRenderTarget());
+    if (fHWDrawState.getRenderTarget() != rt) {
         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID()));
     #if GR_COLLECT_STATS
         ++fStats.fRenderTargetChngCnt;
@@ -1565,7 +1566,7 @@ void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
         }
     #endif
         fDirtyFlags.fRenderTargetChanged = true;
-        fHWDrawState.fRenderTarget = fCurrDrawState.fRenderTarget;
+        fHWDrawState.setRenderTarget(rt);
         const GrGLIRect& vp = rt->getViewport();
         if (fHWBounds.fViewportRect != vp) {
             vp.pushToGLViewport(this->glInterface());
@@ -1682,7 +1683,7 @@ void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) {
     #endif
         // make sure we go through flushRenderTarget() since we've modified
         // the bound DRAW FBO ID.
-        fHWDrawState.fRenderTarget = NULL;
+        fHWDrawState.setRenderTarget(NULL);
         const GrGLIRect& vp = rt->getViewport();
         const GrIRect dirtyRect = rt->getResolveRect();
         GrGLIRect r;
@@ -1754,21 +1755,24 @@ GR_STATIC_ASSERT(6 == kZero_StencilOp);
 GR_STATIC_ASSERT(7 == kInvert_StencilOp);
 
 void GrGpuGL::flushStencil() {
-    const GrStencilSettings* settings = &fCurrDrawState.fStencilSettings;
+    const GrDrawState& drawState = this->getDrawState();
+    const GrStencilSettings* settings = &drawState.getStencil();
 
     // use stencil for clipping if clipping is enabled and the clip
     // has been written into the stencil.
-    bool stencilClip = fClipInStencil &&
-                       (kClip_StateBit & fCurrDrawState.fFlagBits);
+    bool stencilClip = fClipInStencil && drawState.isClipState();
+
+    bool modifyingStencilClip = drawState.isStateFlagEnabled(
+        kModifyStencilClip_StateBit);
     bool stencilChange = fHWStencilClip != stencilClip  ||
-                         fHWDrawState.fStencilSettings != *settings ||
-                         ((fHWDrawState.fFlagBits & kModifyStencilClip_StateBit) !=
-                          (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit));
+                         fHWDrawState.getStencil() != *settings ||
+                         (fHWDrawState.isStateFlagEnabled(kModifyStencilClip_StateBit) !=
+                          modifyingStencilClip);
 
     if (stencilChange) {
 
         // we can't simultaneously perform stencil-clipping and modify the stencil clip
-        GrAssert(!stencilClip || !(fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit));
+        GrAssert(!stencilClip || !drawState.isStateFlagEnabled(kModifyStencilClip_StateBit));
 
         if (settings->isDisabled()) {
             if (stencilClip) {
@@ -1793,15 +1797,14 @@ void GrGpuGL::flushStencil() {
             }
     #endif
             int stencilBits = 0;
-            GrStencilBuffer* stencilBuffer = 
-                            fCurrDrawState.fRenderTarget->getStencilBuffer();
+            GrStencilBuffer* stencilBuffer =
+                drawState.getRenderTarget()->getStencilBuffer();
             if (NULL != stencilBuffer) {
                 stencilBits = stencilBuffer->bits();
             }
             // TODO: dynamically attach a stencil buffer
             GrAssert(stencilBits ||
-                     (GrStencilSettings::gDisabled ==
-                      fCurrDrawState.fStencilSettings));
+                     (GrStencilSettings::gDisabled == *settings));
 
             GrGLuint clipStencilMask = 0;
             GrGLuint userStencilMask = ~0;
@@ -1815,7 +1818,7 @@ void GrGpuGL::flushStencil() {
             unsigned int frontWriteMask = settings->fFrontWriteMask;
             GrGLenum frontFunc;
 
-            if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) {
+            if (modifyingStencilClip) {
 
                 GrAssert(settings->fFrontFunc < kBasicStencilFuncCount);
                 frontFunc = grToGLStencilFunc[settings->fFrontFunc];
@@ -1847,7 +1850,7 @@ void GrGpuGL::flushStencil() {
                 unsigned int backWriteMask = settings->fBackWriteMask;
 
 
-                if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) {
+                if (modifyingStencilClip) {
                     GrAssert(settings->fBackFunc < kBasicStencilFuncCount);
                     backFunc = grToGLStencilFunc[settings->fBackFunc];
                 } else {
@@ -1885,7 +1888,7 @@ void GrGpuGL::flushStencil() {
                                 grToGLStencilOp[settings->fFrontPassOp]));
             }
         }
-        fHWDrawState.fStencilSettings = fCurrDrawState.fStencilSettings;
+        *fHWDrawState.stencil() = *settings;
         fHWStencilClip = stencilClip;
     }
 }
@@ -1897,6 +1900,8 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) {
 
         // we prefer smooth lines over multisampled lines
         // msaa should be disabled if drawing smooth lines.
+
+        GrRenderTarget* rt = this->getRenderTarget();
         if (GrIsPrimTypeLines(type)) {
             bool smooth = this->willUseHWAALines();
             if (!fHWAAState.fSmoothLineEnabled && smooth) {
@@ -1906,13 +1911,13 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) {
                 GL_CALL(Disable(GR_GL_LINE_SMOOTH));
                 fHWAAState.fSmoothLineEnabled = false;
             }
-            if (fCurrDrawState.fRenderTarget->isMultisampled() && 
+            if (rt->isMultisampled() && 
                 fHWAAState.fMSAAEnabled) {
                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
                 fHWAAState.fMSAAEnabled = false;
             }
-        } else if (fCurrDrawState.fRenderTarget->isMultisampled() &&
-                   SkToBool(kHWAntialias_StateBit & fCurrDrawState.fFlagBits) !=
+        } else if (rt->isMultisampled() &&
+                   this->getDrawState().isHWAntialiasState() !=
                    fHWAAState.fMSAAEnabled) {
             if (fHWAAState.fMSAAEnabled) {
                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
@@ -1933,12 +1938,11 @@ void GrGpuGL::flushBlend(GrPrimitiveType type,
             GL_CALL(Enable(GR_GL_BLEND));
             fHWBlendDisabled = false;
         }
-        if (kSA_BlendCoeff != fHWDrawState.fSrcBlend ||
-            kISA_BlendCoeff != fHWDrawState.fDstBlend) {
+        if (kSA_BlendCoeff != fHWDrawState.getSrcBlendCoeff() ||
+            kISA_BlendCoeff != fHWDrawState.getDstBlendCoeff()) {
             GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_BlendCoeff],
                               gXfermodeCoeff2Blend[kISA_BlendCoeff]));
-            fHWDrawState.fSrcBlend = kSA_BlendCoeff;
-            fHWDrawState.fDstBlend = kISA_BlendCoeff;
+            fHWDrawState.setBlendFunc(kSA_BlendCoeff, kISA_BlendCoeff);
         }
     } else {
         // any optimization to disable blending should
@@ -1955,25 +1959,25 @@ void GrGpuGL::flushBlend(GrPrimitiveType type,
             fHWBlendDisabled = blendOff;
         }
         if (!blendOff) {
-            if (fHWDrawState.fSrcBlend != srcCoeff ||
-                fHWDrawState.fDstBlend != dstCoeff) {
+            if (fHWDrawState.getSrcBlendCoeff() != srcCoeff ||
+                fHWDrawState.getDstBlendCoeff() != dstCoeff) {
                 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
                                   gXfermodeCoeff2Blend[dstCoeff]));
-                fHWDrawState.fSrcBlend = srcCoeff;
-                fHWDrawState.fDstBlend = dstCoeff;
+                fHWDrawState.setBlendFunc(srcCoeff, dstCoeff);
             }
+            GrColor blendConstant = this->getDrawState().getBlendConstant();
             if ((BlendCoeffReferencesConstant(srcCoeff) ||
                  BlendCoeffReferencesConstant(dstCoeff)) &&
-                fHWDrawState.fBlendConstant != fCurrDrawState.fBlendConstant) {
+                fHWDrawState.getBlendConstant() != blendConstant) {
 
                 float c[] = {
-                    GrColorUnpackR(fCurrDrawState.fBlendConstant) / 255.f,
-                    GrColorUnpackG(fCurrDrawState.fBlendConstant) / 255.f,
-                    GrColorUnpackB(fCurrDrawState.fBlendConstant) / 255.f,
-                    GrColorUnpackA(fCurrDrawState.fBlendConstant) / 255.f
+                    GrColorUnpackR(blendConstant) / 255.f,
+                    GrColorUnpackG(blendConstant) / 255.f,
+                    GrColorUnpackB(blendConstant) / 255.f,
+                    GrColorUnpackA(blendConstant) / 255.f
                 };
                 GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
-                fHWDrawState.fBlendConstant = fCurrDrawState.fBlendConstant;
+                fHWDrawState.setBlendConstant(blendConstant);
             }
         }
     }
@@ -2033,12 +2037,13 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
 
     // GrGpu::setupClipAndFlushState should have already checked this
     // and bailed if not true.
-    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrAssert(this->getRenderTarget() != NULL);
 
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         // bind texture and set sampler state
         if (this->isStageEnabled(s)) {
-            GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTextures[s];
+            GrGLTexture* nextTexture =
+                static_cast<GrGLTexture*>(this->drawState()->getTexture(s));
 
             // true for now, but maybe not with GrEffect.
             GrAssert(NULL != nextTexture);
@@ -2052,20 +2057,20 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
                 resolveRenderTarget(texRT);
             }
 
-            if (fHWDrawState.fTextures[s] != nextTexture) {
+            if (fHWDrawState.getTexture(s) != nextTexture) {
                 setTextureUnit(s);
                 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID()));
             #if GR_COLLECT_STATS
                 ++fStats.fTextureChngCnt;
             #endif
                 //GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
-                fHWDrawState.fTextures[s] = nextTexture;
+                fHWDrawState.setTexture(s, nextTexture);
                 // The texture matrix has to compensate for texture width/height
                 // and NPOT-embedded-in-POT
                 fDirtyFlags.fTextureChangedMask |= (1 << s);
             }
 
-            const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+            const GrSamplerState& sampler = this->getSampler(s);
             ResetTimestamp timestamp;
             const GrGLTexture::TexParams& oldTexParams =
                                     nextTexture->getCachedTexParams(&timestamp);
@@ -2117,7 +2122,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
 
     GrIRect* rect = NULL;
     GrIRect clipBounds;
-    if ((fCurrDrawState.fFlagBits & kClip_StateBit) &&
+    if (this->getDrawState().isClipState() &&
         fClip.hasConservativeBounds()) {
         fClip.getConservativeBounds().roundOut(&clipBounds);
         rect = &clipBounds;
@@ -2125,19 +2130,19 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
     this->flushRenderTarget(rect);
     this->flushAAState(type);
     
-    if ((fCurrDrawState.fFlagBits & kDither_StateBit) !=
-        (fHWDrawState.fFlagBits & kDither_StateBit)) {
-        if (fCurrDrawState.fFlagBits & kDither_StateBit) {
+    if (this->getDrawState().isDitherState() !=
+        fHWDrawState.isDitherState()) {
+        if (this->getDrawState().isDitherState()) {
             GL_CALL(Enable(GR_GL_DITHER));
         } else {
             GL_CALL(Disable(GR_GL_DITHER));
         }
     }
 
-    if ((fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) !=
-        (fHWDrawState.fFlagBits & kNoColorWrites_StateBit)) {
+    if (this->getDrawState().isColorWriteDisabled() !=
+        fHWDrawState.isColorWriteDisabled()) {
         GrGLenum mask;
-        if (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) {
+        if (this->getDrawState().isColorWriteDisabled()) {
             mask = GR_GL_FALSE;
         } else {
             mask = GR_GL_TRUE;
@@ -2145,8 +2150,8 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
         GL_CALL(ColorMask(mask, mask, mask, mask));
     }
 
-    if (fHWDrawState.fDrawFace != fCurrDrawState.fDrawFace) {
-        switch (fCurrDrawState.fDrawFace) {
+    if (fHWDrawState.getDrawFace() != this->getDrawFace()) {
+        switch (this->getDrawFace()) {
             case GrDrawState::kCCW_DrawFace:
                 GL_CALL(Enable(GR_GL_CULL_FACE));
                 GL_CALL(CullFace(GR_GL_BACK));
@@ -2161,24 +2166,27 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
             default:
                 GrCrash("Unknown draw face.");
         }
-        fHWDrawState.fDrawFace = fCurrDrawState.fDrawFace;
+        fHWDrawState.setDrawFace(this->getDrawFace());
     }
 
 #if GR_DEBUG
     // check for circular rendering
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         GrAssert(!this->isStageEnabled(s) ||
-                 NULL == fCurrDrawState.fRenderTarget ||
-                 NULL == fCurrDrawState.fTextures[s] ||
-                 fCurrDrawState.fTextures[s]->asRenderTarget() !=
-                    fCurrDrawState.fRenderTarget);
+                 NULL == this->getRenderTarget() ||
+                 NULL == this->getTexture(s) ||
+                 this->getTexture(s)->asRenderTarget() !=
+                 this->getRenderTarget());
     }
 #endif
 
-    flushStencil();
+    this->flushStencil();
+
+    // the flushStencil() function called above detecs a change in the
+    // kModifyStencilClip_StateBit flag. Therefore this copy must happen after
+    // flushStencil()
+    fHWDrawState.copyStateFlags(this->getDrawState());
 
-    // flushStencil may look at the private state bits, so keep it before this.
-    fHWDrawState.fFlagBits = fCurrDrawState.fFlagBits;
     return true;
 }
 
@@ -2210,22 +2218,22 @@ void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
 
 void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
     GrAssert(NULL != renderTarget);
-    if (fCurrDrawState.fRenderTarget == renderTarget) {
-        fCurrDrawState.fRenderTarget = NULL;
+    if (this->getRenderTarget() == renderTarget) {
+        this->setRenderTarget(NULL);
     }
-    if (fHWDrawState.fRenderTarget == renderTarget) {
-        fHWDrawState.fRenderTarget = NULL;
+    if (this->getRenderTarget() == renderTarget) {
+        fHWDrawState.setRenderTarget(NULL);
     }
 }
 
 void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        if (fCurrDrawState.fTextures[s] == texture) {
-            fCurrDrawState.fTextures[s] = NULL;
+        if (this->getTexture(s) == texture) {
+            this->setTexture(s, NULL);
         }
-        if (fHWDrawState.fTextures[s] == texture) {
+        if (fHWDrawState.getTexture(s) == texture) {
             // deleting bound texture does implied bind to 0
-            fHWDrawState.fTextures[s] = NULL;
+            this->setTexture(s, NULL);
        }
     }
 }
index 9018a4e..5109a10 100644 (file)
@@ -343,7 +343,7 @@ const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
 
     if (GrGLProgram::kSetAsAttribute == 
         fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
-        return fHWDrawState.fSamplerStates[stage].getMatrix();
+        return fHWDrawState.getSampler(stage).getMatrix();
     } else {
         return fProgramData->fTextureMatrices[stage];
     }
@@ -351,9 +351,9 @@ const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
 
 void GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
     GrAssert(fProgramData);
-    if (GrGLProgram::kSetAsAttribute == 
+    if (GrGLProgram::kSetAsAttribute ==
         fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
-        fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
+        fHWDrawState.sampler(stage)->setMatrix(matrix);
     } else {
         fProgramData->fTextureMatrices[stage] = matrix;
     }
@@ -388,47 +388,68 @@ void GrGpuGLShaders::onResetContext() {
 }
 
 void GrGpuGLShaders::flushViewMatrix() {
-    GrAssert(NULL != fCurrDrawState.fRenderTarget);
-    GrMatrix m;
-    m.setAll(
-        GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
-        0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
-        0, 0, GrMatrix::I()[8]);
-    m.setConcat(m, fCurrDrawState.fViewMatrix);
-
-    // ES doesn't allow you to pass true to the transpose param,
-    // so do our own transpose
-    GrGLfloat mt[]  = {
-        GrScalarToFloat(m[GrMatrix::kMScaleX]),
-        GrScalarToFloat(m[GrMatrix::kMSkewY]),
-        GrScalarToFloat(m[GrMatrix::kMPersp0]),
-        GrScalarToFloat(m[GrMatrix::kMSkewX]),
-        GrScalarToFloat(m[GrMatrix::kMScaleY]),
-        GrScalarToFloat(m[GrMatrix::kMPersp1]),
-        GrScalarToFloat(m[GrMatrix::kMTransX]),
-        GrScalarToFloat(m[GrMatrix::kMTransY]),
-        GrScalarToFloat(m[GrMatrix::kMPersp2])
-    };
 
-    if (GrGLProgram::kSetAsAttribute ==  
+    const GrMatrix* hwViewMatrix;
+    // If we are using a uniform for the matrix then the cached value is
+    // stored with each program. If we are using an attribute than it is global
+    // to all programs.
+    if (GrGLProgram::kSetAsAttribute ==
         fProgramData->fUniLocations.fViewMatrixUni) {
-        int baseIdx = GrGLProgram::ViewMatrixAttributeIdx();
-        GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
-        GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
-        GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
+        hwViewMatrix = &fHWDrawState.getViewMatrix();
     } else {
-        GrAssert(GrGLProgram::kUnusedUniform != 
-                 fProgramData->fUniLocations.fViewMatrixUni);
-        GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
-                                 1, false, mt));
+        hwViewMatrix = &fProgramData->fViewMatrix;
+    }
+
+    if (*hwViewMatrix != this->getViewMatrix()) {
+
+        GrRenderTarget* rt = this->getRenderTarget();
+        GrAssert(NULL != rt);
+        GrMatrix m;
+        m.setAll(
+            GrIntToScalar(2) / rt->width(), 0, -GR_Scalar1,
+            0,-GrIntToScalar(2) / rt->height(), GR_Scalar1,
+            0, 0, GrMatrix::I()[8]);
+        m.setConcat(m, this->getViewMatrix());
+
+        // ES doesn't allow you to pass true to the transpose param,
+        // so do our own transpose
+        GrGLfloat mt[]  = {
+            GrScalarToFloat(m[GrMatrix::kMScaleX]),
+            GrScalarToFloat(m[GrMatrix::kMSkewY]),
+            GrScalarToFloat(m[GrMatrix::kMPersp0]),
+            GrScalarToFloat(m[GrMatrix::kMSkewX]),
+            GrScalarToFloat(m[GrMatrix::kMScaleY]),
+            GrScalarToFloat(m[GrMatrix::kMPersp1]),
+            GrScalarToFloat(m[GrMatrix::kMTransX]),
+            GrScalarToFloat(m[GrMatrix::kMTransY]),
+            GrScalarToFloat(m[GrMatrix::kMPersp2])
+        };
+
+        if (GrGLProgram::kSetAsAttribute ==  
+            fProgramData->fUniLocations.fViewMatrixUni) {
+            int baseIdx = GrGLProgram::ViewMatrixAttributeIdx();
+            GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
+            GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
+            GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
+        } else {
+            GrAssert(GrGLProgram::kUnusedUniform != 
+                     fProgramData->fUniLocations.fViewMatrixUni);
+            GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
+                                     1, false, mt));
+        }
+        if (GrGLProgram::kSetAsAttribute ==
+            fProgramData->fUniLocations.fViewMatrixUni) {
+            fHWDrawState.setViewMatrix(this->getViewMatrix());
+        } else {
+            fProgramData->fViewMatrix = this->getViewMatrix();
+        }
     }
 }
 
 void GrGpuGLShaders::flushTextureDomain(int s) {
     const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni;
     if (GrGLProgram::kUnusedUniform != uni) {
-        const GrRect &texDom =
-            fCurrDrawState.fSamplerStates[s].getTextureDomain();
+        const GrRect &texDom = this->getSampler(s).getTextureDomain();
 
         if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
             fProgramData->fTextureDomain[s] != texDom) {
@@ -442,7 +463,7 @@ void GrGpuGLShaders::flushTextureDomain(int s) {
                 GrScalarToFloat(texDom.bottom())
             };
 
-            GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+            GrGLTexture* texture = (GrGLTexture*) this->getTexture(s);
             GrGLTexture::Orientation orientation = texture->orientation();
 
             // vertical flip if necessary
@@ -461,19 +482,18 @@ void GrGpuGLShaders::flushTextureDomain(int s) {
 
 void GrGpuGLShaders::flushTextureMatrix(int s) {
     const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni;
-    GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+    GrGLTexture* texture = (GrGLTexture*) this->getTexture(s);
     if (NULL != texture) {
+        const GrMatrix& hwMat = fHWDrawState.getSampler(s).getMatrix();
+        const GrMatrix& currMat = this->getSampler(s).getMatrix();
         if (GrGLProgram::kUnusedUniform != uni &&
             (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
-            getHWSamplerMatrix(s) != getSamplerMatrix(s))) {
+            hwMat != currMat)) {
 
-            GrAssert(NULL != fCurrDrawState.fTextures[s]);
-
-            GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+            GrAssert(NULL != texture);
 
-            GrMatrix m = getSamplerMatrix(s);
-            GrSamplerState::SampleMode mode = 
-                fCurrDrawState.fSamplerStates[s].getSampleMode();
+            GrMatrix m = currMat;
+            GrSamplerState::SampleMode mode = this->getSampler(s).getSampleMode();
             AdjustTextureMatrix(texture, mode, &m);
 
             // ES doesn't allow you to pass true to the transpose param,
@@ -499,7 +519,7 @@ void GrGpuGLShaders::flushTextureMatrix(int s) {
             } else {
                 GL_CALL(UniformMatrix3fv(uni, 1, false, mt));
             }
-            recordHWSamplerMatrix(s, getSamplerMatrix(s));
+            this->recordHWSamplerMatrix(s, currMat);
         }
     }
 }
@@ -507,7 +527,7 @@ void GrGpuGLShaders::flushTextureMatrix(int s) {
 void GrGpuGLShaders::flushRadial2(int s) {
 
     const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
-    const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+    const GrSamplerState& sampler = fCurrDrawState.getSampler(s);
     if (GrGLProgram::kUnusedUniform != uni &&
         (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
          fProgramData->fRadial2Radius0[s]  != sampler.getRadial2Radius0()  ||
@@ -539,7 +559,7 @@ void GrGpuGLShaders::flushRadial2(int s) {
 }
 
 void GrGpuGLShaders::flushConvolution(int s) {
-    const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+    const GrSamplerState& sampler = this->getSampler(s);
     int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni;
     if (GrGLProgram::kUnusedUniform != kernelUni) {
         GL_CALL(Uniform1fv(kernelUni, sampler.getKernelWidth(),
@@ -554,7 +574,7 @@ void GrGpuGLShaders::flushConvolution(int s) {
 void GrGpuGLShaders::flushTexelSize(int s) {
     const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
     if (GrGLProgram::kUnusedUniform != uni) {
-        GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+        GrGLTexture* texture = (GrGLTexture*) this->getTexture(s);
         if (texture->width() != fProgramData->fTextureWidth[s] ||
             texture->height() != fProgramData->fTextureHeight[s]) {
 
@@ -570,13 +590,14 @@ void GrGpuGLShaders::flushTexelSize(int s) {
 void GrGpuGLShaders::flushEdgeAAData() {
     const int& uni = fProgramData->fUniLocations.fEdgesUni;
     if (GrGLProgram::kUnusedUniform != uni) {
-        int count = fCurrDrawState.fEdgeAANumEdges;
+
+        int count = this->getDrawState().getNumAAEdges();
         GrDrawState::Edge edges[GrDrawState::kMaxEdges];
         // Flip the edges in Y
         float height = 
-            static_cast<float>(fCurrDrawState.fRenderTarget->height());
+            static_cast<float>(this->getRenderTarget()->height());
         for (int i = 0; i < count; ++i) {
-            edges[i] = fCurrDrawState.fEdgeAAEdges[i];
+            edges[i] = this->getDrawState().getAAEdges()[i];
             float b = edges[i].fY;
             edges[i].fY = -b;
             edges[i].fZ += b * height;
@@ -599,16 +620,16 @@ void GrGpuGLShaders::flushColor(GrColor color) {
     if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
         // color will be specified per-vertex as an attribute
         // invalidate the const vertex attrib color
-        fHWDrawState.fColor = GrColor_ILLEGAL;
+        fHWDrawState.setColor(GrColor_ILLEGAL);
     } else {
         switch (desc.fColorInput) {
             case ProgramDesc::kAttribute_ColorInput:
-                if (fHWDrawState.fColor != color) {
+                if (fHWDrawState.getColor() != color) {
                     // OpenGL ES only supports the float varities of glVertexAttrib
                     float c[] = GR_COLOR_TO_VEC4(color);
                     GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), 
                                             c));
-                    fHWDrawState.fColor = color;
+                    fHWDrawState.setColor(color);
                 }
                 break;
             case ProgramDesc::kUniform_ColorInput:
@@ -629,13 +650,13 @@ void GrGpuGLShaders::flushColor(GrColor color) {
                 GrCrash("Unknown color type.");
         }
     }
-    if (fProgramData->fUniLocations.fColorFilterUni
-                != GrGLProgram::kUnusedUniform
-            && fProgramData->fColorFilterColor
-                != fCurrDrawState.fColorFilterColor) {
-        float c[] = GR_COLOR_TO_VEC4(fCurrDrawState.fColorFilterColor);
-        GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c));
-        fProgramData->fColorFilterColor = fCurrDrawState.fColorFilterColor;
+    GrColor filterColor = this->getDrawState().getColorFilterColor();
+    int uni = fProgramData->fUniLocations.fColorFilterUni;
+    if (uni != GrGLProgram::kUnusedUniform &&
+        fProgramData->fColorFilterColor != filterColor) {
+        float c[] = GR_COLOR_TO_VEC4(filterColor);
+        GL_CALL(Uniform4fv(uni, 1, c));
+        fProgramData->fColorFilterColor = filterColor;
     }
 }
 
@@ -648,7 +669,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
     if (fDirtyFlags.fRenderTargetChanged) {
         // our coords are in pixel space and the GL matrices map to NDC
         // so if the viewport changed, our matrix is now wrong.
-        fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
+        fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
         // we assume all shader matrices may be wrong after viewport changes
         fProgramCache->invalidateViewMatrices();
     }
@@ -680,22 +701,11 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
     } else if (blendOpts & kEmitCoverage_BlendOptFlag) {
         color = 0xffffffff;
     } else {
-        color = fCurrDrawState.fColor;
+        color = this->getColor();
     }
     this->flushColor(color);
 
-    GrMatrix* currViewMatrix;
-    if (GrGLProgram::kSetAsAttribute == 
-        fProgramData->fUniLocations.fViewMatrixUni) {
-        currViewMatrix = &fHWDrawState.fViewMatrix;
-    } else {
-        currViewMatrix = &fProgramData->fViewMatrix;
-    }
-
-    if (*currViewMatrix != fCurrDrawState.fViewMatrix) {
-        flushViewMatrix();
-        *currViewMatrix = fCurrDrawState.fViewMatrix;
-    }
+    this->flushViewMatrix();
 
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         this->flushTextureMatrix(s);
@@ -709,7 +719,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
         this->flushTextureDomain(s);
     }
     this->flushEdgeAAData();
-    resetDirtyFlags();
+    this->resetDirtyFlags();
     return true;
 }
 
@@ -856,6 +866,7 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
 void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
                                   BlendOptFlags blendOpts,
                                   GrBlendCoeff dstCoeff) {
+    const GrDrawState& drawState = this->getDrawState();
     ProgramDesc& desc = fCurrentProgram.fProgramDesc;
 
     // This should already have been caught
@@ -885,7 +896,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
 
     desc.fColorFilterXfermode = skipColor ?
                                 SkXfermode::kDst_Mode :
-                                fCurrDrawState.fColorFilterXfermode;
+                                drawState.getColorFilterMode();
 
     // no reason to do edge aa or look at per-vertex coverage if coverage is
     // ignored
@@ -897,7 +908,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
     bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
     bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) ||
                              (!requiresAttributeColors &&
-                              0xffffffff == fCurrDrawState.fColor);
+                              0xffffffff == this->getColor());
     if (GR_AGGRESSIVE_SHADER_OPTS && colorIsTransBlack) {
         desc.fColorInput = ProgramDesc::kTransBlack_ColorInput;
     } else if (GR_AGGRESSIVE_SHADER_OPTS && colorIsSolidWhite) {
@@ -908,16 +919,15 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
         desc.fColorInput = ProgramDesc::kAttribute_ColorInput;
     }
 
-    desc.fEdgeAANumEdges = skipCoverage ? 0 : fCurrDrawState.fEdgeAANumEdges;
+    desc.fEdgeAANumEdges = skipCoverage ? 0 : drawState.getNumAAEdges();
     desc.fEdgeAAConcave = desc.fEdgeAANumEdges > 0 &&
-                          SkToBool(fCurrDrawState.fFlagBits &
-                                   kEdgeAAConcave_StateBit);
+                          drawState.isConcaveEdgeAAState();
 
     int lastEnabledStage = -1;
 
     if (!skipCoverage && (desc.fVertexLayout &
                           GrDrawTarget::kEdge_VertexLayoutBit)) {
-        desc.fVertexEdgeType = fCurrDrawState.fVertexEdgeType;
+        desc.fVertexEdgeType = drawState.getVertexEdgeType();
     } else {
         // use canonical value when not set to avoid cache misses
         desc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
@@ -929,19 +939,19 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
         stage.fOptFlags = 0;
         stage.setEnabled(this->isStageEnabled(s));
 
-        bool skip = s < fCurrDrawState.fFirstCoverageStage ? skipColor :
-                                                             skipCoverage;
+        bool skip = s < drawState.getFirstCoverageStage() ? skipColor :
+                                                            skipCoverage;
 
         if (!skip && stage.isEnabled()) {
             lastEnabledStage = s;
-            GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+            GrGLTexture* texture = (GrGLTexture*) drawState.getTexture(s);
             GrAssert(NULL != texture);
-            const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+            const GrSamplerState& sampler = drawState.getSampler(s);
             // we matrix to invert when orientation is TopDown, so make sure
             // we aren't in that case before flagging as identity.
             if (TextureMatrixIsIdentity(texture, sampler)) {
                 stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
-            } else if (!getSamplerMatrix(s).hasPerspective()) {
+            } else if (!drawState.getSampler(s).getMatrix().hasPerspective()) {
                 stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
             }
             switch (sampler.getSampleMode()) {
@@ -1024,7 +1034,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
         }
     }
 
-    if (GrPixelConfigIsUnpremultiplied(fCurrDrawState.fRenderTarget->config())) {
+    if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
         desc.fOutputPM = ProgramDesc::kNo_OutputPM;
     } else {
         desc.fOutputPM = ProgramDesc::kYes_OutputPM;
@@ -1046,9 +1056,9 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
     // immaterial.
     int firstCoverageStage = GrDrawState::kNumStages;
     desc.fFirstCoverageStage = GrDrawState::kNumStages;
-    bool hasCoverage = fCurrDrawState.fFirstCoverageStage <= lastEnabledStage;
+    bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage;
     if (hasCoverage) {
-        firstCoverageStage = fCurrDrawState.fFirstCoverageStage;
+        firstCoverageStage = drawState.getFirstCoverageStage();
     }
 
     // other coverage inputs
index 340cff1..829d9f0 100644 (file)
@@ -102,7 +102,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
         // simply because the clip has changed if the clip doesn't affect
         // the rect.
         bool disabledClip = false;
-        if (this->isClipState() && fClip.isRect()) {
+        if (this->getDrawState().isClipState() && fClip.isRect()) {
 
             GrRect clipRect = fClip.getRect(0);
             // If the clip rect touches the edge of the viewport, extended it
@@ -132,7 +132,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
                 }
             }
             if (insideClip) {
-                this->disableState(kClip_StateBit);
+                this->drawState()->disableState(GrDrawState::kClip_StateBit);
                 disabledClip = true;
             }
         }
@@ -176,7 +176,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
             fLastRectVertexLayout = layout;
         }
         if (disabledClip) {
-            this->enableState(kClip_StateBit);
+            this->drawState()->disableState(GrDrawState::kClip_StateBit);
         }
     } else {
         INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
@@ -328,9 +328,9 @@ void GrInOrderDrawBuffer::reset() {
     for (uint32_t i = 0; i < numStates; ++i) {
         const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-            GrSafeUnref(dstate.fTextures[s]);
+            GrSafeUnref(dstate.getTexture(s));
         }
-        GrSafeUnref(dstate.fRenderTarget);
+        GrSafeUnref(dstate.getRenderTarget());
     }
     int numDraws = fDraws.count();
     for (int d = 0; d < numDraws; ++d) {
@@ -594,14 +594,14 @@ bool GrInOrderDrawBuffer::needsNewState() const {
 
 void GrInOrderDrawBuffer::pushState() {
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        GrSafeRef(fCurrDrawState.fTextures[s]);
+        GrSafeRef(fCurrDrawState.getTexture(s));
     }
-    GrSafeRef(fCurrDrawState.fRenderTarget);
+    GrSafeRef(fCurrDrawState.getRenderTarget());
     this->saveCurrentDrawState(&fStates.push_back());
  }
 
 bool GrInOrderDrawBuffer::needsNewClip() const {
-   if (fCurrDrawState.fFlagBits & kClip_StateBit) {
+   if (this->getDrawState().isClipState()) {
        if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
            return true;
        }
index b6612d1..5834dfd 100644 (file)
@@ -471,7 +471,7 @@ FINISHED:
             if (count <= maxEdges) {
                 // All edges fit; upload all edges and draw all verts as a fan
                 fTarget->setVertexSourceToArray(layout, base, count);
-                fTarget->setEdgeAAData(&edges[0], count);
+                fTarget->drawState()->setEdgeAAData(&edges[0], count);
                 fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
             } else {
                 // Upload "maxEdges" edges and verts at a time, and draw as
@@ -481,11 +481,11 @@ FINISHED:
                     base[i] = base[0];
                     int size = GR_CT_MIN(count - i, maxEdges);
                     fTarget->setVertexSourceToArray(layout, &base[i], size);
-                    fTarget->setEdgeAAData(&edges[i], size);
+                    fTarget->drawState()->setEdgeAAData(&edges[i], size);
                     fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size);
                 }
             }
-            fTarget->setEdgeAAData(NULL, 0);
+            fTarget->drawState()->setEdgeAAData(NULL, 0);
         } else {
             fTarget->setVertexSourceToArray(layout, base, count);
             fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
@@ -534,7 +534,7 @@ FINISHED:
         }
 
         // Draw the resulting polys and upload their edge data.
-        fTarget->enableState(GrDrawTarget::kEdgeAAConcave_StateBit);
+        fTarget->drawState()->enableState(GrDrawState::kEdgeAAConcave_StateBit);
         const GrPointArray& vertices = ptess.vertices();
         const GrIndexArray& indices = ptess.indices();
         const GrDrawState::Edge* edges = ptess.edges();
@@ -567,12 +567,13 @@ FINISHED:
                 tri_edges[t++] = edge4;
                 tri_edges[t++] = edge5;
             }
-            fTarget->setEdgeAAData(&tri_edges[0], t);
+            fTarget->drawState()->setEdgeAAData(&tri_edges[0], t);
             fTarget->setVertexSourceToArray(layout, &tri_verts[0], 3);
             fTarget->drawNonIndexed(kTriangles_PrimitiveType, 0, 3);
         }
-        fTarget->setEdgeAAData(NULL, 0);
-        fTarget->disableState(GrDrawTarget::kEdgeAAConcave_StateBit);
+        fTarget->drawState()->setEdgeAAData(NULL, 0);
+        fTarget->drawState()->disableState(
+            GrDrawState::kEdgeAAConcave_StateBit);
         return;
     }
 
index 4b78d4a..ef98487 100644 (file)
@@ -25,6 +25,7 @@ enum {
 void GrTextContext::flushGlyphs() {
     if (fCurrVertex > 0) {
         GrDrawTarget::AutoStateRestore asr(fDrawTarget);
+        GrDrawState* drawState = fDrawTarget->drawState();
 
         // setup our sampler state for our text texture/atlas
         GrSamplerState::Filter filter;
@@ -41,6 +42,7 @@ void GrTextContext::flushGlyphs() {
         int nIndices = fCurrVertex + (fCurrVertex >> 1);
         GrAssert(fCurrTexture);
         fDrawTarget->setTexture(kGlyphMaskStage, fCurrTexture);
+        drawState->setTexture(kGlyphMaskStage, fCurrTexture);
 
         if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
             if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff ||
@@ -49,15 +51,15 @@ void GrTextContext::flushGlyphs() {
                 GrPrintf("LCD Text will not draw correctly.\n");
             }
             // setup blend so that we get mask * paintColor + (1-mask)*dstColor
-            fDrawTarget->setBlendConstant(fPaint.fColor);
-            fDrawTarget->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff);
+            drawState->setBlendConstant(fPaint.fColor);
+            drawState->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff);
             // don't modulate by the paint's color in the frag since we're
             // already doing it via the blend const.
-            fDrawTarget->setColor(0xffffffff);
+            drawState->setColor(0xffffffff);
         } else {
             // set back to normal in case we took LCD path previously.
-            fDrawTarget->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff);
-            fDrawTarget->setColor(fPaint.fColor);
+            drawState->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff);
+            drawState->setColor(fPaint.fColor);
         }
 
         fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());