Replace fixed-size array of effect stages in GrDrawState with two appendable arrays, one for color, one for coverage.

R=robertphillips@google.com

Review URL: https://codereview.chromium.org/16952006

git-svn-id: http://skia.googlecode.com/svn/trunk@9592 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 712eff6..5c796b2 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -903,9 +903,10 @@
 
     void flushDrawBuffer();
 
+    class AutoRestoreEffects;
     /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
     /// draw state is left unmodified.
-    GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw);
+    GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*);
 
     void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
                           const SkStrokeRec& stroke);
diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h
index 0ef334e..3f10bdc 100644
--- a/include/gpu/GrEffectStage.h
+++ b/include/gpu/GrEffectStage.h
@@ -20,21 +20,38 @@
 
 class GrEffectStage {
 public:
-    GrEffectStage()
-    : fEffectRef (NULL) {
-        GR_DEBUGCODE(fSavedCoordChangeCnt = 0;)
+    GrEffectStage() {
+        fCoordChangeMatrixSet = false;
+        fVertexAttribIndices[0] = -1;
+        fVertexAttribIndices[1] = -1;
     }
 
-    ~GrEffectStage() {
-        GrSafeUnref(fEffectRef);
-        GrAssert(0 == fSavedCoordChangeCnt);
+    explicit GrEffectStage(const GrEffectRef* effectRef, int attrIndex0 = -1, int attrIndex1 = -1)
+    : fEffectRef(SkSafeRef(effectRef)) {
+        fCoordChangeMatrixSet = false;
+        fVertexAttribIndices[0] = attrIndex0;
+        fVertexAttribIndices[1] = attrIndex1;
     }
 
-    bool operator ==(const GrEffectStage& other) const {
+    GrEffectStage(const GrEffectStage& other) {
+        *this = other;
+    }
+
+    GrEffectStage& operator= (const GrEffectStage& other) {
+        fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
+        if (other.fCoordChangeMatrixSet) {
+            fCoordChangeMatrix = other.fCoordChangeMatrix;
+        }
+        fEffectRef.reset(SkSafeRef(other.fEffectRef.get()));
+        memcpy(fVertexAttribIndices, other.fVertexAttribIndices, sizeof(fVertexAttribIndices));
+        return *this;
+    }
+
+    bool operator== (const GrEffectStage& other) const {
         // first handle cases where one or the other has no effect
-        if (NULL == fEffectRef) {
-            return NULL == other.fEffectRef;
-        } else if (NULL == other.fEffectRef) {
+        if (NULL == fEffectRef.get()) {
+            return NULL == other.fEffectRef.get();
+        } else if (NULL == other.fEffectRef.get()) {
             return false;
         }
 
@@ -55,15 +72,6 @@
 
     bool operator!= (const GrEffectStage& s) const { return !(*this == s); }
 
-    GrEffectStage& operator= (const GrEffectStage& other) {
-        GrSafeAssign(fEffectRef, other.fEffectRef);
-        fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
-        if (NULL != fEffectRef && fCoordChangeMatrixSet) {
-            fCoordChangeMatrix = other.fCoordChangeMatrix;
-        }
-        return *this;
-    }
-
     /**
      * This is called when the coordinate system in which the geometry is specified will change.
      *
@@ -100,9 +108,8 @@
             savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
         }
         GrAssert(NULL == savedCoordChange->fEffectRef.get());
-        GR_DEBUGCODE(GrSafeRef(fEffectRef);)
-        GR_DEBUGCODE(savedCoordChange->fEffectRef.reset(fEffectRef);)
-        GR_DEBUGCODE(++fSavedCoordChangeCnt);
+        GR_DEBUGCODE(GrSafeRef(fEffectRef.get());)
+        GR_DEBUGCODE(savedCoordChange->fEffectRef.reset(fEffectRef.get());)
     }
 
     /**
@@ -114,7 +121,6 @@
             fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
         }
         GrAssert(savedCoordChange.fEffectRef.get() == fEffectRef);
-        GR_DEBUGCODE(--fSavedCoordChangeCnt);
         GR_DEBUGCODE(savedCoordChange.fEffectRef.reset(NULL);)
     }
 
@@ -136,7 +142,7 @@
 
         void saveFrom(const GrEffectStage& stage) {
             GrAssert(!fInitialized);
-            if (NULL != stage.fEffectRef) {
+            if (NULL != stage.fEffectRef.get()) {
                 stage.fEffectRef->get()->incDeferredRefCounts();
                 fEffect = stage.fEffectRef->get();
                 fCoordChangeMatrixSet = stage.fCoordChangeMatrixSet;
@@ -151,9 +157,8 @@
 
         void restoreTo(GrEffectStage* stage) {
             GrAssert(fInitialized);
-            const GrEffectRef* oldEffectRef = stage->fEffectRef;
             if (NULL != fEffect) {
-                stage->fEffectRef = GrEffect::CreateEffectRef(fEffect);
+                stage->fEffectRef.reset(GrEffect::CreateEffectRef(fEffect));
                 stage->fCoordChangeMatrixSet = fCoordChangeMatrixSet;
                 if (fCoordChangeMatrixSet) {
                     stage->fCoordChangeMatrix = fCoordChangeMatrix;
@@ -161,13 +166,12 @@
                 stage->fVertexAttribIndices[0] = fVertexAttribIndices[0];
                 stage->fVertexAttribIndices[1] = fVertexAttribIndices[1];
             } else {
-                stage->fEffectRef = NULL;
+                stage->fEffectRef.reset(NULL);
             }
-            SkSafeUnref(oldEffectRef);
         }
 
         bool isEqual(const GrEffectStage& stage, bool ignoreCoordChange) const {
-            if (NULL == stage.fEffectRef) {
+            if (NULL == stage.fEffectRef.get()) {
                 return NULL == fEffect;
             } else if (NULL == fEffect) {
                 return false;
@@ -219,44 +223,28 @@
         }
     }
 
-    void reset() {
-        GrSafeSetNull(fEffectRef);
-    }
+    void reset() { fEffectRef.reset(NULL); }
 
-    const GrEffectRef* setEffect(const GrEffectRef* EffectRef) {
-        GrAssert(0 == fSavedCoordChangeCnt);
-        GrSafeAssign(fEffectRef, EffectRef);
-        fCoordChangeMatrixSet = false;
-
-        fVertexAttribIndices[0] = -1;
-        fVertexAttribIndices[1] = -1;
-
-        return EffectRef;
-    }
-
-    const GrEffectRef* setEffect(const GrEffectRef* EffectRef, int attr0, int attr1 = -1) {
-        GrAssert(0 == fSavedCoordChangeCnt);
-        GrSafeAssign(fEffectRef, EffectRef);
+    const GrEffectRef* setEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
+        fEffectRef.reset(SkSafeRef(effect));
         fCoordChangeMatrixSet = false;
 
         fVertexAttribIndices[0] = attr0;
         fVertexAttribIndices[1] = attr1;
 
-        return EffectRef;
+        return effect;
     }
 
-    const GrEffectRef* getEffect() const { return fEffectRef; }
+    const GrEffectRef* getEffect() const { return fEffectRef.get(); }
 
     const int* getVertexAttribIndices() const { return fVertexAttribIndices; }
     int getVertexAttribIndexCount() const { return fEffectRef->get()->numVertexAttribs(); }
 
 private:
-    bool                    fCoordChangeMatrixSet;
-    SkMatrix                fCoordChangeMatrix;
-    const GrEffectRef*      fEffectRef;
-    int                     fVertexAttribIndices[2];
-
-    GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;)
+    bool                                fCoordChangeMatrixSet;
+    SkMatrix                            fCoordChangeMatrix;
+    SkAutoTUnref<const GrEffectRef>     fEffectRef;
+    int                                 fVertexAttribIndices[2];
 };
 
 #endif