Reland 3503 with fix



git-svn-id: http://skia.googlecode.com/svn/trunk@3506 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index dd63d6e..12c8861 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -773,6 +773,9 @@
 
         fViewMatrix = s.fViewMatrix;
 
+        GrAssert(0 == s.fEdgeAANumEdges);
+        fEdgeAANumEdges = 0;
+    
         for (int i = 0; i < kNumStages; i++) {
             if (s.fTextures[i]) {
                 memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 6d52c2a..5cce435 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -474,6 +474,9 @@
 #if GR_DEBUG
     VertexLayoutUnitTest();
 #endif
+    fDrawState = &fDefaultDrawState;
+    // We assume that fDrawState always owns a ref to the object it points at.
+    fDefaultDrawState.ref();
     GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
 #if GR_DEBUG
     geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
@@ -490,6 +493,7 @@
     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
     GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc);
     GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc);
+    fDrawState->unref();
 }
 
 void GrDrawTarget::releaseGeometry() {
@@ -511,16 +515,28 @@
     return fClip;
 }
 
+void GrDrawTarget::setDrawState(GrDrawState*  drawState) {
+    GrAssert(NULL != fDrawState);
+    if (NULL == drawState) {
+        drawState = &fDefaultDrawState;
+    }
+    if (fDrawState != drawState) {
+        fDrawState->unref();
+        drawState->ref();
+        fDrawState = drawState;
+    }
+}
+
 void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
-    state->fState.set(fCurrDrawState);
+    state->fState.set(this->getDrawState());
 }
 
 void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
-    fCurrDrawState = *state.fState.get();
+    *fDrawState = *state.fState.get();
 }
 
 void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
-    fCurrDrawState = srcTarget.fCurrDrawState;
+    *fDrawState = srcTarget.getDrawState();
 }
 
 bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
@@ -855,7 +871,7 @@
     }
     // Check if a color stage could create a partial alpha
     for (int s = 0; s < drawState.getFirstCoverageStage(); ++s) {
-        if (StageWillBeUsed(s, layout, fCurrDrawState)) {
+        if (StageWillBeUsed(s, layout, this->getDrawState())) {
             GrAssert(NULL != drawState.getTexture(s));
             GrPixelConfig config = drawState.getTexture(s)->config();
             if (!GrPixelConfigIsOpaque(config)) {
@@ -932,7 +948,7 @@
     for (int s = drawState.getFirstCoverageStage();
          !hasCoverage && s < GrDrawState::kNumStages;
          ++s) {
-        if (StageWillBeUsed(s, layout, fCurrDrawState)) {
+        if (StageWillBeUsed(s, layout, this->getDrawState())) {
             hasCoverage = true;
         }
     }
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 3a85767..731cae5 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -86,8 +86,24 @@
      */
     const GrClip& getClip() const;
 
-    const GrDrawState& getDrawState() const { return fCurrDrawState; }
-    GrDrawState* drawState() { return &fCurrDrawState; }
+    /**
+     * Sets the draw state object for the draw target. Note that this does not
+     * make a copy. The GrDrawTarget will take a reference to passed object.
+     * Passing NULL will cause the GrDrawTarget to use its own internal draw
+     * state object rather than an externally provided one.
+     */
+    void setDrawState(GrDrawState*  drawState);
+
+    /**
+     * Read-only access to the GrDrawTarget's current draw state.
+     */
+    const GrDrawState& getDrawState() const { return *fDrawState; }
+
+    /**
+     * Read-write access to the GrDrawTarget's current draw state. Note that
+     * this doesn't ref.
+     */
+    GrDrawState* drawState() { return fDrawState; }
 
     /**
      * Shortcut for drawState()->preConcatSamplerMatrices() on all enabled
@@ -962,7 +978,7 @@
 
     bool isStageEnabled(int stage) const {
         return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout, 
-                               fCurrDrawState);
+                               this->getDrawState());
     }
 
     StageMask enabledStages() const {
@@ -1041,7 +1057,8 @@
 
     GrClip fClip;
 
-    GrDrawState fCurrDrawState;
+    GrDrawState* fDrawState;
+    GrDrawState fDefaultDrawState;
 
     Caps fCaps;
 
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 05f9a3f..37cac0f 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -509,9 +509,10 @@
     fVertexPool.unlock();
     fIndexPool.unlock();
 
-    GrDrawTarget::AutoStateRestore asr(target);
     GrDrawTarget::AutoClipRestore acr(target);
     AutoGeometryPush agp(target);
+    GrDrawState* prevDrawState = target->drawState();
+    prevDrawState->ref();
 
     int currState = ~0;
     int currClip  = ~0;
@@ -527,7 +528,8 @@
         const Draw& draw = fDraws[i];
         if (draw.fStateChanged) {
             ++currState;
-            target->restoreDrawState(fStates[currState]);
+            GrDrawState* ds = &GrDrawTarget::accessSavedDrawState(fStates[currState]);
+            target->setDrawState(ds);
         }
         if (draw.fClipChanged) {
             ++currClip;
@@ -557,6 +559,8 @@
         target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
         ++currClear;
     }
+    target->setDrawState(prevDrawState);
+    prevDrawState->unref();
 }
 
 void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
@@ -776,7 +780,7 @@
         return true;
      } else {
         const GrDrawState& old = this->accessSavedDrawState(fStates.back());
-        return old != fCurrDrawState;
+        return old != this->getDrawState();
      }
 }
 
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 10b42c0..8754ac3 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1911,7 +1911,7 @@
                                   gXfermodeCoeff2Blend[dstCoeff]));
                 fHWDrawState.setBlendFunc(srcCoeff, dstCoeff);
             }
-            GrColor blendConst = fCurrDrawState.getBlendConstant();
+            GrColor blendConst = this->getDrawState().getBlendConstant();
             if ((BlendCoeffReferencesConstant(srcCoeff) ||
                  BlendCoeffReferencesConstant(dstCoeff)) &&
                 fHWDrawState.getBlendConstant() != blendConst) {
@@ -2099,7 +2099,7 @@
     }
 
     if (fHWDrawState.getDrawFace() != drawState->getDrawFace()) {
-        switch (fCurrDrawState.getDrawFace()) {
+        switch (this->getDrawState().getDrawFace()) {
             case GrDrawState::kCCW_DrawFace:
                 GL_CALL(Enable(GR_GL_CULL_FACE));
                 GL_CALL(CullFace(GR_GL_BACK));
@@ -2178,7 +2178,7 @@
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         GrDrawState* drawState = this->drawState();
         if (drawState->getTexture(s) == texture) {
-            fCurrDrawState.setTexture(s, NULL);
+            this->drawState()->setTexture(s, NULL);
         }
         if (fHWDrawState.getTexture(s) == texture) {
             // deleting bound texture does implied bind to 0