Store clip mask location in GrClipMaskManager as a enum rather than two bools

Review URL: http://codereview.appspot.com/6306092/



git-svn-id: http://skia.googlecode.com/svn/trunk@4274 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index ee1bcae..55a8192 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -119,9 +119,9 @@
     GrAssert(scissorSettings);
 
     scissorSettings->fEnableScissoring = false;
-    fClipMaskInStencil = false;
-    fClipMaskInAlpha = false;
 
+    fCurrClipMaskType = kNone_ClipMaskType;
+    
     GrDrawState* drawState = fGpu->drawState();
     if (!drawState->isClipState()) {
         return true;
@@ -143,8 +143,6 @@
         GrTexture* result = NULL;
         GrIRect bound;
         if (this->createSoftwareClipMask(fGpu, clipIn, &result, &bound)) {
-            fClipMaskInAlpha = true;
-
             setup_drawstate_aaclip(fGpu, result, bound);
             return true;
         }
@@ -165,8 +163,6 @@
         GrTexture* result = NULL;
         GrIRect bound;
         if (this->createAlphaClipMask(fGpu, clipIn, &result, &bound)) {
-            fClipMaskInAlpha = true;
-
             setup_drawstate_aaclip(fGpu, result, bound);
             return true;
         }
@@ -208,10 +204,10 @@
     scissorSettings->fEnableScissoring = true;
 
     // use the stencil clip if we can't represent the clip as a rectangle.
-    fClipMaskInStencil = !clipIn.isRect() && !clipIn.isEmpty() &&
-                         !bounds.isEmpty();
+    bool useStencil = !clipIn.isRect() && !clipIn.isEmpty() &&
+                      !bounds.isEmpty();
 
-    if (fClipMaskInStencil) {
+    if (useStencil) {
         return this->createStencilClipMask(clipIn, bounds, scissorSettings);
     }
 
@@ -546,13 +542,15 @@
                                             GrTexture** result,
                                             GrIRect *resultBounds) {
 
+    GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
+
     if (this->clipMaskPreamble(clipIn, result, resultBounds)) {
+        fCurrClipMaskType = kAlpha_ClipMaskType;
         return true;
     }
 
     GrTexture* accum = fAACache.getLastMask();
     if (NULL == accum) {
-        fClipMaskInAlpha = false;
         fAACache.reset();
         return false;
     }
@@ -613,7 +611,6 @@
 
             getTemp(*resultBounds, &temp);
             if (NULL == temp.texture()) {
-                fClipMaskInAlpha = false;
                 fAACache.reset();
                 return false;
             }
@@ -659,7 +656,7 @@
     }
 
     *result = accum;
-
+    fCurrClipMaskType = kAlpha_ClipMaskType;
     return true;
 }
 
@@ -669,7 +666,7 @@
                                               const GrRect& bounds,
                                               ScissoringSettings* scissorSettings) {
 
-    GrAssert(fClipMaskInStencil);
+    GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
 
     GrDrawState* drawState = fGpu->drawState();
     GrAssert(drawState->isClipState());
@@ -758,7 +755,6 @@
                                                          fill, fGpu, false,
                                                          true);
                 if (NULL == pr) {
-                    fClipMaskInStencil = false;
                     fGpu->setClip(clipCopy);     // restore to the original
                     return false;
                 }
@@ -824,11 +820,10 @@
         }
         // restore clip
         fGpu->setClip(clipCopy);
-        // recusive draws would have disabled this since they drew with
-        // the clip bounds as clip.
-        fClipMaskInStencil = true;
     }
-
+    // set this last because recursive draws may overwrite it back to kNone.
+    GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
+    fCurrClipMaskType = kStencil_ClipMaskType;
     return true;
 }
 
@@ -950,6 +945,7 @@
 bool GrClipMaskManager::createSoftwareClipMask(const GrClip& clipIn,
                                                GrTexture** result,
                                                GrIRect *resultBounds) {
+    GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
 
     if (this->clipMaskPreamble(clipIn, result, resultBounds)) {
         return true;
@@ -957,7 +953,6 @@
 
     GrTexture* accum = fAACache.getLastMask();
     if (NULL == accum) {
-        fClipMaskInAlpha = false;
         fAACache.reset();
         return false;
     }
@@ -1057,6 +1052,7 @@
 
     *result = accum;
 
+    fCurrClipMaskType = kAlpha_ClipMaskType;
     return true;
 }
 
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index 2e46c08..1ceee16 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -285,8 +285,7 @@
 public:
     GrClipMaskManager(GrGpu* gpu)
         : fGpu(gpu)
-        , fClipMaskInStencil(false)
-        , fClipMaskInAlpha(false) {
+        , fCurrClipMaskType(kNone_ClipMaskType) {
     }
 
     bool createClipMask(const GrClip& clip, 
@@ -294,11 +293,17 @@
 
     void releaseResources();
 
-    bool isClipInStencil() const { return fClipMaskInStencil; }
-    bool isClipInAlpha() const { return fClipMaskInAlpha; }
+    bool isClipInStencil() const {
+        return kStencil_ClipMaskType == fCurrClipMaskType;
+    }
+    bool isClipInAlpha() const {
+        return kAlpha_ClipMaskType == fCurrClipMaskType;
+    }
 
-    void resetMask() {
-        fClipMaskInStencil = false;
+    void invalidateStencilMask() {
+        if (kStencil_ClipMaskType == fCurrClipMaskType) {
+            fCurrClipMaskType = kNone_ClipMaskType;
+        }
     }
 
     void postClipPush() {
@@ -350,8 +355,18 @@
 
 private:
     GrGpu* fGpu;
-    bool fClipMaskInStencil;        // is the clip mask in the stencil buffer?
-    bool fClipMaskInAlpha;          // is the clip mask in an alpha texture?
+
+    /**
+     * We may represent the clip as a mask in the stencil buffer or as an alpha
+     * texture. It may be neither because the scissor rect suffices or we
+     * haven't yet examined the clip.
+     */
+    enum ClipMaskType {
+        kNone_ClipMaskType,
+        kStencil_ClipMaskType,
+        kAlpha_ClipMaskType,
+    } fCurrClipMaskType;
+    
     GrClipMaskCache fAACache;       // cache for the AA path
 
     bool createStencilClipMask(const GrClip& clip, 
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 9302393..edbad34 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -429,7 +429,7 @@
     void finalizeReservedIndices();
 
     // called when the 3D context state is unknown. Subclass should emit any
-    // assumed 3D context state and dirty any state cache
+    // assumed 3D context state and dirty any state cache.
     virtual void onResetContext() = 0;
 
     
@@ -558,6 +558,10 @@
     void prepareIndexPool();
 
     void resetContext() {
+        // We call this because the client may have messed with the
+        // stencil buffer. Perhaps we should detect whether it is a
+        // internally created stencil buffer and if so skip the invalidate.
+        fClipMaskManager.invalidateStencilMask();
         this->onResetContext();
         ++fResetTimestamp;
     }
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index dd65394..5c1764c 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -508,10 +508,6 @@
     // stencil on the next draw.
     fHWStencilClipMode = GrClipMaskManager::kRespectClip_StencilClipMode;
 
-    // TODO: I believe this should actually go in GrGpu::onResetContext
-    // rather than here
-    fClipMaskManager.resetMask();
-
     fHWGeometryState.fIndexBuffer = NULL;
     fHWGeometryState.fVertexBuffer = NULL;