Moved GrClipMaskCache to its own files

https://codereview.appspot.com/6496055/



git-svn-id: http://skia.googlecode.com/svn/trunk@5331 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrClipMaskCache.h b/src/gpu/GrClipMaskCache.h
new file mode 100644
index 0000000..f1152cc
--- /dev/null
+++ b/src/gpu/GrClipMaskCache.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrClipMaskCache_DEFINED
+#define GrClipMaskCache_DEFINED
+
+#include "GrContext.h"
+#include "GrNoncopyable.h"
+#include "SkClipStack.h"
+
+class GrTexture;
+
+/**
+ * The stencil buffer stores the last clip path - providing a single entry
+ * "cache". This class provides similar functionality for AA clip paths
+ */
+class GrClipMaskCache : public GrNoncopyable {
+public:
+    GrClipMaskCache();
+
+    ~GrClipMaskCache() {
+
+        while (!fStack.empty()) {
+            GrClipStackFrame* temp = (GrClipStackFrame*) fStack.back();
+            temp->~GrClipStackFrame();
+            fStack.pop_back();
+        }
+    }
+
+    bool canReuse(const SkClipStack& clip, int width, int height) {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            return false;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        if (back->fLastMask.texture() &&
+            back->fLastMask.texture()->width() >= width &&
+            back->fLastMask.texture()->height() >= height &&
+            clip == back->fLastClip) {
+            return true;
+        }
+
+        return false;
+    }
+
+    void reset() {
+        if (fStack.empty()) {
+//            GrAssert(false);
+            return;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        back->reset();
+    }
+
+    /**
+     * After a "push" the clip state is entirely open. Currently, the
+     * entire clip stack will be re-rendered into a new clip mask.
+     * TODO: can we take advantage of the nested nature of the clips to
+     * reduce the mask creation cost?
+     */
+    void push();
+
+    void pop() {
+        //GrAssert(!fStack.empty());
+
+        if (!fStack.empty()) {
+            GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+            back->~GrClipStackFrame();
+            fStack.pop_back();
+        }
+    }
+
+    void getLastClip(SkClipStack* clip) const {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            clip->reset();
+            return;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        *clip = back->fLastClip;
+    }
+
+    GrTexture* getLastMask() {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            return NULL;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        return back->fLastMask.texture();
+    }
+
+    const GrTexture* getLastMask() const {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            return NULL;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        return back->fLastMask.texture();
+    }
+
+    void acquireMask(const SkClipStack& clip,
+                     const GrTextureDesc& desc,
+                     const GrIRect& bound) {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            return;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        back->acquireMask(fContext, clip, desc, bound);
+    }
+
+    int getLastMaskWidth() const {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            return -1;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        if (NULL == back->fLastMask.texture()) {
+            return -1;
+        }
+
+        return back->fLastMask.texture()->width();
+    }
+
+    int getLastMaskHeight() const {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            return -1;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        if (NULL == back->fLastMask.texture()) {
+            return -1;
+        }
+
+        return back->fLastMask.texture()->height();
+    }
+
+    void getLastBound(GrIRect* bound) const {
+
+        if (fStack.empty()) {
+            GrAssert(false);
+            bound->setEmpty();
+            return;
+        }
+
+        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
+
+        *bound = back->fLastBound;
+    }
+
+    void setContext(GrContext* context) {
+        fContext = context;
+    }
+
+    GrContext* getContext() {
+        return fContext;
+    }
+
+    void releaseResources() {
+
+        SkDeque::F2BIter iter(fStack);
+        for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next();
+                frame != NULL;
+                frame = (GrClipStackFrame*) iter.next()) {
+            frame->reset();
+        }
+    }
+
+protected:
+private:
+    struct GrClipStackFrame {
+
+        GrClipStackFrame() {
+            reset();
+        }
+
+        void acquireMask(GrContext* context,
+                         const SkClipStack& clip,
+                         const GrTextureDesc& desc,
+                         const GrIRect& bound) {
+
+            fLastClip = clip;
+
+            fLastMask.set(context, desc);
+
+            fLastBound = bound;
+        }
+
+        void reset () {
+            fLastClip.reset();
+
+            GrTextureDesc desc;
+
+            fLastMask.set(NULL, desc);
+            fLastBound.setEmpty();
+        }
+
+        SkClipStack             fLastClip;
+        // The mask's width & height values are used in setupDrawStateAAClip to
+        // correctly scale the uvs for geometry drawn with this mask
+        GrAutoScratchTexture    fLastMask;
+        // fLastBound stores the bounding box of the clip mask in canvas
+        // space. The left and top fields are used to offset the uvs for
+        // geometry drawn with this mask (in setupDrawStateAAClip)
+        GrIRect                 fLastBound;
+    };
+
+    GrContext*   fContext;
+    SkDeque      fStack;
+
+    typedef GrNoncopyable INHERITED;
+};
+
+#endif // GrClipMaskCache_DEFINED