add gpu backend (not hooked up yet)



git-svn-id: http://skia.googlecode.com/svn/trunk@649 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/FlingState.h b/gpu/include/FlingState.h
new file mode 100644
index 0000000..a1da4fb
--- /dev/null
+++ b/gpu/include/FlingState.h
@@ -0,0 +1,59 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkFlingState_DEFINED
+#define SkFlingState_DEFINED
+
+#include "SkScalar.h"
+#include "SkPoint.h"
+
+class SkMatrix;
+
+struct FlingState {
+    FlingState() : fActive(false) {}
+
+    bool isActive() const { return fActive; }
+    void stop() { fActive = false; }
+
+    void reset(float sx, float sy);
+    bool evaluateMatrix(SkMatrix* matrix);
+
+private:
+    SkPoint     fDirection;
+    SkScalar    fSpeed0;
+    double      fTime0;
+    bool        fActive;
+};
+
+class GrAnimateFloat {
+public:
+    GrAnimateFloat();
+
+    void start(float v0, float v1, float duration);
+    bool isActive() const { return fTime0 != 0; }
+    void stop() { fTime0 = 0; }
+
+    float evaluate();
+
+private:
+    float   fValue0, fValue1, fDuration;
+    SkMSec  fTime0;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrAPI.h b/gpu/include/GrAPI.h
new file mode 100644
index 0000000..b660e8d
--- /dev/null
+++ b/gpu/include/GrAPI.h
@@ -0,0 +1,37 @@
+
+
+class GrAPI {
+public:
+
+    void setRenderTarget(GrRenderTarget* target);
+
+    void setMatrix(const GrMatrix&);
+
+    void setClip(rect, bool aa);
+    void setClip(rect[], bool aa);
+    void setClip(path, bool aa);
+    void setClip(rect, texture/key, state, matrix);
+    void setClip(path, texture/key, state, matrix);
+    
+    void setColor(color);
+    void setTexture(texture/key, sampler, const GrMatrix* = NULL);
+    void setBlend(src, dst);
+    
+    void drawRect(const GrRect&, stroke, join);
+    void drawOval(const GrRect&, stroke);
+    void drawRoundRect(const GrRect&, GrScalar ovalW, GrScalar ovalH, stroke);
+    void drawPath(const GrPathIter&, GrPathFill);
+    void drawVertices(...);
+    void drawGlyphs(const uint16_t[], int count, const GrPoint[], GrFontScaler*);
+
+///
+
+    void save();
+    void restore();
+    void concatMatrix(const GrMatrix&);
+    void concatClipRect(const GrRect&);
+    void concatClipPath(const GrPathIter&, bool aa);
+
+};
+
+
diff --git a/gpu/include/GrAllocPool.h b/gpu/include/GrAllocPool.h
new file mode 100644
index 0000000..46359e5
--- /dev/null
+++ b/gpu/include/GrAllocPool.h
@@ -0,0 +1,71 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrAllocPool_DEFINED
+#define GrAllocPool_DEFINED
+
+#include "GrNoncopyable.h"
+
+class GrAllocPool : GrNoncopyable {
+public:
+    GrAllocPool(size_t blockSize = 0);
+    ~GrAllocPool();
+
+    /**
+     *  Frees all blocks that have been allocated with alloc().
+     */
+    void reset();
+
+    /**
+     *  Returns a block of memory bytes size big. This address must not be
+     *  passed to realloc/free/delete or any other function that assumes the
+     *  address was allocated by malloc or new (becuase it hasn't).
+     */
+    void* alloc(size_t bytes);
+    
+    /**
+     * Releases the most recently allocated bytes back to allocpool.
+     */
+    void release(size_t bytes);
+
+private:
+    struct Block;
+
+    Block*  fBlock;
+    size_t  fMinBlockSize;
+
+#if GR_DEBUG
+    int fBlocksAllocated;
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+};
+
+template <typename T> class GrTAllocPool {
+public:
+    GrTAllocPool(int count) : fPool(count * sizeof(T)) {}
+
+    void reset() { fPool.reset(); }
+    T* alloc() { return (T*)fPool.alloc(sizeof(T)); }
+
+private:
+    GrAllocPool fPool;
+};
+
+#endif
+
diff --git a/gpu/include/GrAllocator.h b/gpu/include/GrAllocator.h
new file mode 100755
index 0000000..da02ba4
--- /dev/null
+++ b/gpu/include/GrAllocator.h
@@ -0,0 +1,230 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrAllocator_DEFINED
+#define GrAllocator_DEFINED
+
+#include "GrConfig.h"
+#include "GrTArray.h"
+
+class GrAllocator {
+public:
+    virtual ~GrAllocator() {
+        reset();
+    }
+
+    /**
+     * Create an allocator
+     *
+     * @param   itemSize        the size of each item to allocate
+     * @param   itemsPerBlock   the number of items to allocate at once
+     * @param   initialBlock    optional memory to use for the first block.
+     *                          Must be at least itemSize*itemsPerBlock sized.
+     *                          Caller is responsible for freeing this memory.
+     */
+    GrAllocator(size_t itemSize, uint32_t itemsPerBlock, void* initialBlock) :
+            fBlocks(fBlockInitialStorage, NUM_INIT_BLOCK_PTRS),
+            fItemSize(itemSize),
+            fItemsPerBlock(itemsPerBlock),
+            fOwnFirstBlock(NULL == initialBlock),
+            fCount(0) {
+        fBlockSize = fItemSize * fItemsPerBlock;
+        fBlocks.push_back() = initialBlock;
+        GR_DEBUGCODE(if (!fOwnFirstBlock) {*((char*)initialBlock+fBlockSize-1)='a';} );
+    }
+
+    /**
+     * Adds an item and returns pointer to it.
+     *
+     * @return pointer to the added item.
+     */
+    void* push_back() {        
+        uint32_t indexInBlock = fCount % fItemsPerBlock;
+        // we always have at least one block
+        if (0 == indexInBlock) {
+            if (0 != fCount) {
+                fBlocks.push_back() = GrMalloc(fBlockSize);
+            } else if (fOwnFirstBlock) {
+                fBlocks[0] = GrMalloc(fBlockSize);
+            }
+        }        
+        void* ret = (char*)fBlocks[fCount/fItemsPerBlock] + 
+                    fItemSize * indexInBlock;
+        ++fCount;
+        return ret;
+    }
+
+    /**
+     * removes all added items
+     */
+    void reset() {        
+        uint32_t blockCount = GrMax((unsigned)1, 
+                                    GrUIDivRoundUp(fCount, fItemsPerBlock));
+        for (uint32_t i = 1; i < blockCount; ++i) {
+            GrFree(fBlocks[i]);
+        }
+        if (fOwnFirstBlock) {
+            GrFree(fBlocks[0]);
+            fBlocks[0] = NULL;
+        }
+        fBlocks.pop_back_n(blockCount-1);
+        fCount = 0;
+    }
+
+    /**
+     * count of items
+     */
+    uint32_t count() const {
+        return fCount;
+    }
+    
+    /**
+     * is the count 0
+     */
+    bool empty() const { return fCount == 0; }
+    
+    /**
+     * access last item, only call if count() != 0
+     */
+    void* back() {
+        GrAssert(fCount);
+        return (*this)[fCount-1];
+    }
+    
+    /**
+     * access last item, only call if count() != 0
+     */
+    const void* back() const {
+        GrAssert(fCount);
+        return (*this)[fCount-1];
+    }
+    
+    /**
+     * access item by index.
+     */    
+    void* operator[] (uint32_t i) {
+        GrAssert(i < fCount);
+        return (char*)fBlocks[i / fItemsPerBlock] + 
+               fItemSize * (i % fItemsPerBlock);
+    }
+
+    /**
+     * access item by index.
+     */  
+    const void* operator[] (uint32_t i) const {
+        GrAssert(i < fCount);
+        return (const char*)fBlocks[i / fItemsPerBlock] + 
+               fItemSize * (i % fItemsPerBlock);
+    }
+
+private:
+    static const uint32_t NUM_INIT_BLOCK_PTRS = 8;
+    
+    GrTArray<void*> fBlocks;
+    size_t          fBlockSize;    
+    char            fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];    
+    size_t          fItemSize;
+    uint32_t        fItemsPerBlock;
+    bool            fOwnFirstBlock;
+    uint32_t        fCount;    
+};
+
+template <typename T>
+class GrTAllocator {
+private:
+    GrAllocator fAllocator;
+    
+public:
+    virtual ~GrTAllocator() {};
+    
+    /**
+     * Create an allocator
+     *
+     * @param   itemsPerBlock   the number of items to allocate at once
+     * @param   initialBlock    optional memory to use for the first block.
+     *                          Must be at least size(T)*itemsPerBlock sized.
+     *                          Caller is responsible for freeing this memory.
+     */
+    GrTAllocator(uint32_t itemsPerBlock, void* initialBlock) :
+        fAllocator(sizeof(T), itemsPerBlock, initialBlock)
+    {}
+    
+    /**
+     * Adds an item and returns it.
+     *
+     * @return the added item.
+     */
+    T& push_back() {
+        void* item = fAllocator.push_back();
+        GrAssert(NULL != item);
+        new (item) T;
+        return *(T*)item;
+    }
+    
+    /**
+     * removes all added items
+     */
+    void reset() {
+        uint32_t c = fAllocator.count();
+        for (uint32_t i = 0; i < c; ++i) {
+            ((T*)fAllocator[i])->~T();
+        }
+        fAllocator.reset();
+    }
+    
+    /**
+     * count of items
+     */
+    uint32_t count() const {
+        return fAllocator.count();
+    }
+    
+    /**
+     * is the count 0
+     */
+    bool empty() const { return fAllocator.empty(); }
+    
+    /**
+     * access last item, only call if count() != 0
+     */
+    T& back() {
+        return *(T*)fAllocator.back();
+    }
+
+    /**
+     * access last item, only call if count() != 0
+     */
+    const T& back() const {
+        return *(const T*)fAllocator.back();
+    }
+
+    /**
+     * access item by index.
+     */  
+    T& operator[] (uint32_t i) {
+        return *(T*)(fAllocator[i]);
+    }
+    
+    /**
+     * access item by index.
+     */
+    const T& operator[] (uint32_t i) const {
+        return *(const T*)(fAllocator[i]);
+    }    
+};
+
+#endif
diff --git a/gpu/include/GrAtlas.h b/gpu/include/GrAtlas.h
new file mode 100644
index 0000000..9526e0b
--- /dev/null
+++ b/gpu/include/GrAtlas.h
@@ -0,0 +1,88 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrAtlas_DEFINED
+#define GrAtlas_DEFINED
+
+#include "GrPoint.h"
+#include "GrTexture.h"
+#include "GrTDArray.h"
+
+class GrGpu;
+class GrRectanizer;
+class GrAtlasMgr;
+
+class GrAtlas {
+public:
+    GrAtlas(GrAtlasMgr*, int plotX, int plotY);
+
+    int getPlotX() const { return fPlot.fX; }
+    int getPlotY() const { return fPlot.fY; }
+
+    GrTexture* texture() const { return fTexture; }
+
+    bool addSubImage(int width, int height, const void*, GrIPoint16*);
+
+    static void FreeLList(GrAtlas* atlas) {
+        while (atlas) {
+            GrAtlas* next = atlas->fNext;
+            delete atlas;
+            atlas = next;
+        }
+    }
+
+    // testing
+    GrAtlas* nextAtlas() const { return fNext; }
+
+private:
+    ~GrAtlas(); // does not try to delete the fNext field
+
+    GrAtlas*        fNext;
+    GrTexture*      fTexture;
+    GrRectanizer*   fRects;
+    GrAtlasMgr*     fAtlasMgr;
+    GrIPoint16      fPlot;
+
+    friend class GrAtlasMgr;
+};
+
+class GrPlotMgr;
+
+class GrAtlasMgr {
+public:
+    GrAtlasMgr(GrGpu*);
+    ~GrAtlasMgr();
+
+    GrAtlas* addToAtlas(GrAtlas*, int width, int height, const void*,
+                        GrIPoint16*);
+
+    GrTexture* getTexture() const { return fTexture; }
+
+    // to be called by ~GrAtlas()
+    void freePlot(int x, int y);
+
+    void abandonAll();
+
+private:
+    GrGpu*      fGpu;
+    GrTexture*  fTexture;
+    GrPlotMgr*  fPlotMgr;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrClip.h b/gpu/include/GrClip.h
new file mode 100644
index 0000000..8e3030c
--- /dev/null
+++ b/gpu/include/GrClip.h
@@ -0,0 +1,115 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrClip_DEFINED
+#define GrClip_DEFINED
+
+#include "GrClipIterator.h"
+#include "GrRect.h"
+#include "GrTDArray.h"
+
+class GrClip {
+public:
+    GrClip();
+    GrClip(const GrClip& src);
+    GrClip(GrClipIterator* iter);
+    ~GrClip();
+
+    GrClip& operator=(const GrClip& src);
+
+    bool isEmpty() const { return fBounds.isEmpty(); }
+    bool isComplex() const { return fList.count() > 0; }
+    bool isRect() const {
+        return !this->isEmpty() && !this->isComplex();
+    }
+    
+    const GrIRect& getBounds() const { return fBounds; }
+
+    /**
+     *  Resets this clip to be empty (fBounds is empty, and fList is empty)
+     */
+    void setEmpty();
+
+    /**
+     *  Resets this clip to have fBounds == rect, and fList is empty.
+     */
+    void setRect(const GrIRect& rect);
+
+    /**
+     *  Append a rect to an existing clip. The call must ensure that rect does
+     *  not overlap with any previous rect in this clip (either from setRect
+     *  or addRect). fBounds is automatically updated to reflect the union of
+     *  all rects that have been added.
+     */
+    void addRect(const GrIRect&);
+
+    void setFromIterator(GrClipIterator* iter);
+
+    friend bool operator==(const GrClip& a, const GrClip& b) {
+        return a.fBounds == b.fBounds && a.fList == b.fList;
+    }
+    friend bool operator!=(const GrClip& a, const GrClip& b) {
+        return !(a == b);
+    }
+
+    /**
+     *  Return the number of rects in this clip: 0 for empty, 1 for a rect,
+     *  or N for a complex clip.
+     */
+    int countRects() const {
+        return this->isEmpty() ? 0 : GrMax<int>(1, fList.count());
+    }
+
+    /**
+     *  Return an array of rects for this clip. Use countRects() to know the
+     *  number of entries.
+     */
+    const GrIRect* getRects() const {
+        return fList.count() > 0 ? fList.begin() : &fBounds;
+    }
+
+#if GR_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+
+private:
+    GrTDArray<GrIRect>  fList;
+    GrIRect             fBounds;
+};
+
+class GrClipIter : public GrClipIterator {
+public:
+    GrClipIter(const GrClip& clip) : fClip(&clip), fIndex(0) {}
+    GrClipIter() : fClip(NULL), fIndex(0) {}
+    
+    void reset(const GrClip& clip);
+    
+    virtual bool isDone();
+    virtual void rewind();
+    virtual void getRect(GrIRect* r);
+    virtual void next();
+    virtual void computeBounds(GrIRect* r);
+    
+private:
+    const GrClip*   fClip;
+    int             fIndex;
+};
+
+#endif
+
diff --git a/gpu/include/GrClipIterator.h b/gpu/include/GrClipIterator.h
new file mode 100644
index 0000000..d1fe4dd
--- /dev/null
+++ b/gpu/include/GrClipIterator.h
@@ -0,0 +1,81 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrClipIterator_DEFINED
+#define GrClipIterator_DEFINED
+
+#include "GrRect.h"
+
+class GrClipIterator {
+public:
+    GrClipIterator() : fNeedBounds(true) {}
+    virtual ~GrClipIterator() {}
+
+    /**
+     *  Returns true if there are no more rects to process
+     */
+    virtual bool isDone() = 0;
+
+    /**
+     *  Rewind the iterate to replay the set of rects again
+     */
+    virtual void rewind() = 0;
+
+    /**
+     *  Return the current rect. It is an error to call this when done() is true
+     */
+    virtual void getRect(GrIRect*) = 0;
+
+    /**
+     *  Call to move to the next rect in the set
+     */
+    virtual void next() = 0;
+
+    /**
+     *  Set bounds to be the bounds of the clip.
+     */
+    virtual void computeBounds(GrIRect* bounds) = 0;
+
+    /**
+     *  Subclass should call this whenever their underlying bounds has changed.
+     */
+    void invalidateBoundsCache() { fNeedBounds = true; }
+
+    const GrIRect& getBounds() {
+        if (fNeedBounds) {
+            this->computeBounds(&fBounds);
+            fNeedBounds = false;
+        }
+        return fBounds;
+    }
+
+private:
+    GrIRect fBounds;
+    bool    fNeedBounds;
+};
+
+/**
+ *  Call to rewind iter, first checking to see if iter is NULL
+ */
+static inline void GrSafeRewind(GrClipIterator* iter) {
+    if (iter) {
+        iter->rewind();
+    }
+}
+
+#endif
+
diff --git a/gpu/include/GrColor.h b/gpu/include/GrColor.h
new file mode 100644
index 0000000..8dc03d2
--- /dev/null
+++ b/gpu/include/GrColor.h
@@ -0,0 +1,72 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrColor_DEFINED
+#define GrColor_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ *  GrColor is 4 bytes for R, G, B, A, in a compile-time specific order. The
+ *  components are stored premultiplied.
+ */
+typedef uint32_t GrColor;
+
+// indices for address a GrColor as an array of bytes
+
+#define GrColor_INDEX_R     0
+#define GrColor_INDEX_G     1
+#define GrColor_INDEX_B     2
+#define GrColor_INDEX_A     3
+
+// shfit amount to assign a component to a GrColor int
+
+#define GrColor_SHIFT_R     0
+#define GrColor_SHIFT_G     8
+#define GrColor_SHIFT_B     16
+#define GrColor_SHIFT_A     24
+
+/**
+ *  Pack 4 components (RGBA) into a GrColor int
+ */
+static inline GrColor GrColorPackRGBA(unsigned r, unsigned g,
+                                      unsigned b, unsigned a) {
+    GrAssert((uint8_t)r == r);
+    GrAssert((uint8_t)g == g);
+    GrAssert((uint8_t)b == b);
+    GrAssert((uint8_t)a == a);
+    return  (r << GrColor_SHIFT_R) |
+            (g << GrColor_SHIFT_G) |
+            (b << GrColor_SHIFT_B) |
+            (a << GrColor_SHIFT_A);
+}
+
+// extract a component (byte) from a GrColor int
+
+#define GrColorUnpackR(color)   (((color) >> GrColor_SHIFT_R) & 0xFF)
+#define GrColorUnpackG(color)   (((color) >> GrColor_SHIFT_G) & 0xFF)
+#define GrColorUnpackB(color)   (((color) >> GrColor_SHIFT_B) & 0xFF)
+#define GrColorUnpackA(color)   (((color) >> GrColor_SHIFT_A) & 0xFF)
+
+/**
+ *  Since premultiplied means that alpha >= color, we construct a color with
+ *  each component==255 and alpha == 0 to be "illegal"
+ */
+#define GrColor_ILLEGAL     (~(0xFF << GrColor_SHIFT_A))
+
+#endif
+
diff --git a/gpu/include/GrConfig.h b/gpu/include/GrConfig.h
new file mode 100644
index 0000000..9c18f60
--- /dev/null
+++ b/gpu/include/GrConfig.h
@@ -0,0 +1,344 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrConfig_DEFINED
+#define GrConfig_DEFINED
+
+///////////////////////////////////////////////////////////////////////////////
+// preconfig section:
+//
+// All the work before including GrUserConfig.h should center around guessing
+// what platform we're on, and defining low-level symbols based on that.
+//
+// A build environment may have already defined symbols, so we first check
+// for that
+//
+
+// hack to ensure we know what sort of Apple platform we're on
+#if defined(__APPLE_CPP__) || defined(__APPLE_CC__)
+    #include <TargetConditionals.h>
+#endif
+
+/**
+ *  Gr defines are set to 0 or 1, rather than being undefined or defined
+ */
+
+#if !defined(GR_ANDROID_BUILD)
+    #define GR_ANDROID_BUILD    0
+#endif
+#if !defined(GR_IOS_BUILD)
+    #define GR_IOS_BUILD        0
+#endif
+#if !defined(GR_LINUX_BUILD)
+    #define GR_LINUX_BUILD      0
+#endif
+#if !defined(GR_MAC_BUILD)
+    #define GR_MAC_BUILD        0
+#endif
+#if !defined(GR_WIN32_BUILD)
+    #define GR_WIN32_BUILD      0
+#endif
+#if !defined(GR_QNX_BUILD)
+    #define GR_QNX_BUILD        0
+#endif
+
+/**
+ *  If no build target has been defined, attempt to infer.
+ */
+#if !GR_ANDROID_BUILD && !GR_IOS_BUILD && !GR_LINUX_BUILD && !GR_MAC_BUILD && !GR_WIN32_BUILD && !GR_QNX_BUILD
+    #if defined(_WIN32)
+        #undef GR_WIN32_BUILD
+        #define GR_WIN32_BUILD      1
+//      #error "WIN"
+    #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+        #undef GR_IOS_BUILD
+        #define GR_IOS_BUILD        1
+//      #error "IOS"
+    #elif ANDROID_NDK || defined(ANDROID)
+        #undef GR_ANDROID_BUILD
+        #define GR_ANDROID_BUILD    1
+//      #error "ANDROID"
+    #elif TARGET_OS_MAC
+        #undef GR_MAC_BUILD
+        #define GR_MAC_BUILD        1
+//      #error "MAC"
+    #elif TARGET_OS_QNX || defined(__QNXNTO__)
+        #undef GR_QNX_BUILD
+        #define GR_QNX_BUILD        1
+//      #error "QNX"
+    #else
+        #undef GR_LINUX_BUILD
+        #define GR_LINUX_BUILD      1
+//      #error "LINUX"
+    #endif    
+#endif
+
+#if !defined(GR_DEBUG) && !defined(GR_RELEASE)
+    #ifdef NDEBUG
+        #define GR_DEBUG    0
+    #else
+        #define GR_DEBUG    1
+    #endif
+    #define GR_RELEASE  !GR_DEBUG
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+ *  Pull stdint.h in before user-config, to be sure our __STDC... macros are
+ *  defined before anyone else might try to include stdint.h
+ */
+#define __STDC_LIMIT_MACROS
+#define __STDC_CONSTANT_MACROS
+#include <stdint.h>
+
+/*
+ *  The "user config" file can be empty, and everything should work. It is 
+ *  meant to store a given platform/client's overrides of our guess-work.
+ *
+ *  A alternate user config file can be specified by defining 
+ *  GR_USER_CONFIG_FILE. It should be defined relative to GrConfig.h
+ *
+ *  e.g. it can specify GR_DEBUG/GR_RELEASE as it please, change the BUILD
+ *  target, or supply its own defines for anything else (e.g. GR_SCALAR)
+ */
+#if !defined(GR_USER_CONFIG_FILE)
+    #include "GrUserConfig.h"
+#else 
+    #include GR_USER_CONFIG_FILE
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// postconfig section:
+//
+// By now we must have a GR_..._BUILD symbol set to 1, and a decision about
+// debug -vs- release
+//
+
+extern void GrPrintf(const char format[], ...);
+
+/**
+ *  GR_STRING makes a string of X where X is expanded before conversion to a string
+ *  if X itself contains macros.
+ */
+#define GR_STRING(X) GR_STRING_IMPL(X)
+#define GR_STRING_IMPL(X) #X
+
+/**
+ *  GR_CONCAT concatenates X and Y  where each is expanded before 
+ *  contanenation if either contains macros.
+ */
+#define GR_CONCAT(X,Y) GR_CONCAT_IMPL(X,Y)
+#define GR_CONCAT_IMPL(X,Y) X##Y
+
+/**
+ *  Creates a string of the form "<filename>(<linenumber>) : "
+ */
+#define GR_FILE_AND_LINE_STR __FILE__ "(" GR_STRING(__LINE__) ") : "
+
+/**
+ *  Compilers have different ways of issuing warnings. This macro 
+ *  attempts to abstract them, but may need to be specialized for your 
+ *  particular compiler.
+ *  To insert compiler warnings use "#pragma message GR_WARN(<string>)"
+ */
+#if _MSC_VER
+    #define GR_WARN(MSG) (GR_FILE_AND_LINE_STR "WARNING: " MSG)
+#else//__GNUC__ - may need other defines for different compilers
+    #define GR_WARN(MSG) ("WARNING: " MSG)
+#endif
+
+/**
+ *  GR_ALWAYSBREAK is an unconditional break in all builds.
+ */
+#if !defined(GR_ALWAYSBREAK)
+    #if     GR_WIN32_BUILD
+        #define GR_ALWAYSBREAK __debugbreak()
+    #else 
+        // TODO: do other platforms really not have continuable breakpoints?
+        // sign extend for 64bit architectures to be sure this is 
+        // in the high address range
+        #define GR_ALWAYSBREAK *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
+    #endif
+#endif
+
+/**
+ *  GR_DEBUGBREAK is an unconditional break in debug builds.
+ */
+#if !defined(GR_DEBUGBREAK)
+    #if GR_DEBUG
+        #define GR_DEBUGBREAK GR_ALWAYSBREAK
+    #else
+        #define GR_DEBUGBREAK
+    #endif
+#endif
+
+/**
+ *  GR_ALWAYSASSERT is an assertion in all builds.
+ */
+#if !defined(GR_ALWAYSASSERT)
+    #define GR_ALWAYSASSERT(COND)                                        \
+        do {                                                             \
+            if (!(COND)) {                                               \
+                GrPrintf("%s %s failed\n", GR_FILE_AND_LINE_STR, #COND); \
+                GR_ALWAYSBREAK;                                          \
+            }                                                            \
+        } while (false)
+#endif
+
+/**
+ *  GR_DEBUGASSERT is an assertion in debug builds only.
+ */
+#if !defined(GR_DEBUGASSERT)
+    #if GR_DEBUG
+        #define GR_DEBUGASSERT(COND) GR_ALWAYSASSERT(COND)
+    #else
+        #define GR_DEBUGASSERT(COND)
+    #endif
+#endif
+
+/**
+ *  Prettier forms of the above macros.
+ */
+#define GrAssert(COND) GR_DEBUGASSERT(COND)
+#define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND)
+
+/**
+ *  GR_DEBUGCODE compiles the code X in debug builds only 
+ */
+#if !defined(GR_DEBUGCODE)
+    #if GR_DEBUG
+        #define GR_DEBUGCODE(X) X
+    #else
+        #define GR_DEBUGCODE(X)
+    #endif
+#endif
+
+/**
+ *  GR_STATIC_ASSERT is a compile time assertion. Depending on the platform
+ *  it may print the message in the compiler log. Obviously, the condition must
+ *  be evaluatable at compile time.
+ */
+// VS 2010 and GCC compiled with c++0x or gnu++0x support the new 
+// static_assert.
+#if !defined(GR_STATIC_ASSERT)
+    #if (_MSC_VER >= 1600) || __GXX_EXPERIMENTAL_CXX0X__
+        #define GR_STATIC_ASSERT(CONDITION) static_assert(CONDITION, "bug")
+    #else
+        template <bool> class GR_STATIC_ASSERT_FAILURE;
+        template <> class GR_STATIC_ASSERT_FAILURE<true> {};
+        #define GR_STATIC_ASSERT(CONDITION) \
+            enum {GR_CONCAT(X,__LINE__) = \
+            sizeof(GR_STATIC_ASSERT_FAILURE<CONDITION>)}
+    #endif
+#endif
+
+#if !defined(GR_SCALAR_IS_FLOAT)
+    #define GR_SCALAR_IS_FLOAT   0
+#endif
+#if !defined(GR_SCALAR_IS_FIXED)
+    #define GR_SCALAR_IS_FIXED   0
+#endif
+
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_USHORT)
+    #define GR_TEXT_SCALAR_TYPE_IS_USHORT  0
+#endif    
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_FLOAT)
+    #define GR_TEXT_SCALAR_TYPE_IS_FLOAT   0
+#endif
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_FIXED)
+    #define GR_TEXT_SCALAR_TYPE_IS_FIXED   0
+#endif
+
+#ifndef GR_DUMP_TEXTURE_UPLOAD
+    #define GR_DUMP_TEXTURE_UPLOAD  0
+#endif
+
+/**
+ *  GR_COLLECT_STATS controls whether the GrGpu class collects stats.
+ *  If not already defined then collect in debug build but not release.
+ */
+#if !defined(GR_COLLECT_STATS)
+    #define GR_COLLECT_STATS GR_DEBUG
+#endif
+
+/**
+ *  GR_GL_LOG_CALLS controls whether each GL call is logged.
+ */
+#if !defined(GR_GL_LOG_CALLS)
+    #define GR_GL_LOG_CALLS 0 
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// tail section:
+//
+// Now we just assert if we are missing some required define, or if we detect
+// and inconsistent combination of defines
+//
+
+
+/**
+ *  Only one build target macro should be 1 and the rest should be 0.
+ */
+#define GR_BUILD_SUM    (GR_WIN32_BUILD + GR_MAC_BUILD + GR_IOS_BUILD + GR_ANDROID_BUILD + GR_LINUX_BUILD + GR_QNX_BUILD)
+#if 0 == GR_BUILD_SUM
+    #error "Missing a GR_BUILD define"
+#elif 1 != GR_BUILD_SUM
+    #error "More than one GR_BUILD defined"
+#endif
+
+
+#if !GR_SCALAR_IS_FLOAT && !GR_SCALAR_IS_FIXED
+    #undef  GR_SCALAR_IS_FLOAT
+    #define GR_SCALAR_IS_FLOAT              1
+    #pragma message GR_WARN("Scalar type not defined, defaulting to float")
+#endif
+
+#if !GR_TEXT_SCALAR_IS_FLOAT && \
+    !GR_TEXT_SCALAR_IS_FIXED && \
+    !GR_TEXT_SCALAR_IS_USHORT
+    #undef  GR_TEXT_SCALAR_IS_FLOAT
+    #define GR_TEXT_SCALAR_IS_FLOAT         1
+    #pragma message GR_WARN("Text scalar type not defined, defaulting to float")
+#endif
+
+#if 0
+#if GR_WIN32_BUILD
+//    #pragma message GR_WARN("GR_WIN32_BUILD")
+#endif
+#if GR_MAC_BUILD
+//    #pragma message GR_WARN("GR_MAC_BUILD")
+#endif
+#if GR_IOS_BUILD
+//    #pragma message GR_WARN("GR_IOS_BUILD")
+#endif
+#if GR_ANDROID_BUILD
+//    #pragma message GR_WARN("GR_ANDROID_BUILD")
+#endif
+#if GR_LINUX_BUILD
+//    #pragma message GR_WARN("GR_LINUX_BUILD")
+#endif
+#if GR_QNX_BUILD
+//    #pragma message GR_WARN("GR_QNX_BUILD")
+#endif
+#endif
+
+#endif
+
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
new file mode 100644
index 0000000..f9d5ed5
--- /dev/null
+++ b/gpu/include/GrContext.h
@@ -0,0 +1,322 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrContext_DEFINED

+#define GrContext_DEFINED

+

+#include "GrClip.h"

+#include "GrGpu.h"

+#include "GrSamplerState.h"

+#include "GrTextureCache.h"

+#include "GrInOrderDrawBuffer.h"

+#include "GrVertexBufferAllocPool.h"

+

+class GrFontCache;

+class GrPathIter;

+

+//TODO: move GrGpu enums/nested types here

+

+class GrContext : public GrRefCnt {

+public:

+    /**

+     * Creates a GrContext from within a 3D context.

+     */

+    static GrContext* Create(GrGpu::Engine engine,

+                             GrGpu::Platform3DContext context3D);

+

+    virtual ~GrContext();

+

+    /**

+     * The GrContext normally assumes that no outsider is setting state

+     * within the underlying 3D API's context/device/whatever. This call informs

+     * the context that the state was modified and it should resend. Shouldn't

+     * be called frequently for good performance.

+     */

+    void resetContext();

+

+    /**

+     *  Abandons all textures. Call this if you have lost the associated GPU

+     *  context, and thus internal texture references/IDs are now invalid.

+     */

+    void abandonAllTextures();

+

+    /**

+     *  Search for an entry with the same Key. If found, "lock" it and return it.

+     *  If not found, return null.

+     */

+    GrTextureEntry* findAndLockTexture(GrTextureKey*,

+                                       const GrSamplerState&);

+

+

+    /**

+     *  Create a new entry, based on the specified key and texture, and return

+     *  its "locked" entry.

+     *

+     *  Ownership of the texture is transferred to the Entry, which will unref()

+     *  it when we are purged or deleted.

+     */

+    GrTextureEntry* createAndLockTexture(GrTextureKey* key,

+                                         const GrSamplerState&,

+                                         const GrGpu::TextureDesc&,

+                                         void* srcData, size_t rowBytes);

+

+    /**

+     *  When done with an entry, call unlockTexture(entry) on it, which returns

+     *  it to the cache, where it may be purged.

+     */

+    void unlockTexture(GrTextureEntry* entry);

+

+    /**

+     *  Removes an texture from the cache. This prevents the texture from

+     *  being found by a subsequent findAndLockTexture() until it is

+     *  reattached. The entry still counts against the cache's budget and should

+     *  be reattached when exclusive access is no longer needed.

+     */

+    void detachCachedTexture(GrTextureEntry*);

+

+    /**

+     * Reattaches a texture to the cache and unlocks it. Allows it to be found

+     * by a subsequent findAndLock or be purged (provided its lock count is

+     * now 0.)

+     */

+    void reattachAndUnlockCachedTexture(GrTextureEntry*);

+

+    /**

+     * Creates a texture that is outside the cache. Does not count against

+     * cache's budget.

+     */

+    GrTexture* createUncachedTexture(const GrGpu::TextureDesc&,

+                                     void* srcData,

+                                     size_t rowBytes);

+

+    /**

+     * Wraps an externally-created rendertarget in a GrRenderTarget.

+     * e.g. in GL platforamRenderTarget is an FBO id.

+     */

+    GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,

+                                               int width, int height);

+

+    /**

+     *  Returns true if the specified use of an indexed texture is supported.

+     */

+    bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);

+

+    ///////////////////////////////////////////////////////////////////////////

+

+    GrRenderTarget* currentRenderTarget() const;

+    void getViewMatrix(GrMatrix* m) const;

+    const GrClip& getClip() const { return fGpu->getClip(); }

+

+    void setRenderTarget(GrRenderTarget* target);

+    void setDefaultRenderTargetSize(uint32_t width, uint32_t height);

+    GrRenderTarget* defaultRenderTarget() { return fGpu->defaultRenderTarget(); }

+

+    void setTexture(GrTexture* texture);

+    void setSamplerState(const GrSamplerState&);

+    void setTextureMatrix(const GrMatrix& m);

+

+    void setAntiAlias(bool);

+    void setDither(bool);

+    void setAlpha(uint8_t alpha);

+    void setColor(GrColor color);

+    void setPointSize(float size);

+    void setBlendFunc(GrGpu::BlendCoeff srcCoef, GrGpu::BlendCoeff dstCoef);

+    void setViewMatrix(const GrMatrix& m);

+    void setClip(const GrClip&);

+

+    /**

+     *  Erase the entire render target, ignoring any clips/scissors.

+     */

+    void eraseColor(GrColor color);

+

+    /**

+     *  Draw everywhere (respecting the clip) with the current color.

+     */

+    void drawFull(bool useTexture);

+

+    /**

+     *  Draw the rect, respecting the current texture if useTexture is true.

+     *  If strokeWidth < 0, then the rect is filled, else the rect is stroked

+     *  based on strokeWidth. If strokeWidth == 0, then the stroke is always

+     *  a single pixel thick.

+     */

+    void drawRect(const GrRect&, bool useTexture, GrScalar strokeWidth);

+

+    void fillRect(const GrRect& rect, bool useTexture) {

+        this->drawRect(rect, useTexture, -1);

+    }

+

+    /**

+     * Path filling rules

+     */

+    enum PathFills {

+        kWinding_PathFill,

+        kEvenOdd_PathFill,

+        kInverseWinding_PathFill,

+        kInverseEvenOdd_PathFill,

+        kHairLine_PathFill,

+

+        kPathFillCount

+    };

+

+    /**

+     * Tessellates and draws a path.

+     *

+     * @param path          the path to draw

+     * @param paint         the paint to set before drawing

+     * @param useTexture    if true the path vertices will also be used as

+     *                      texture coorindates referencing last texture passed

+     *                      to setTexture.

+     */

+    void drawPath(GrPathIter* path,

+                  PathFills fill,

+                  bool useTexture,

+                  const GrPoint* translate = NULL);

+

+    /**

+     * Call to ensure all drawing to the context has been issued to the

+     * underlying 3D API.

+     * if flushRenderTarget is true then after the call the last

+     * rendertarget set will be current in the underlying 3D API, otherwise

+     * it may not be. It is useful to set if the caller plans to use the 3D

+     * context outside of Ganesh to render into the current RT.

+     */

+    void flush(bool flushRenderTarget);

+

+    /**

+     *  Return true on success, i.e. if we could copy the specified range of

+     *  pixels from the current render-target into the buffer, converting into

+     *  the specified pixel-config.

+     */

+    bool readPixels(int left, int top, int width, int height,

+                    GrTexture::PixelConfig, void* buffer);

+

+    /**

+     *  Copy the src pixels [buffer, stride, pixelconfig] into the current

+     *  render-target at the specified rectangle.

+     */

+    void writePixels(int left, int top, int width, int height,

+                     GrTexture::PixelConfig, const void* buffer, size_t stride);

+

+    /* -------------------------------------------------------

+     * Mimicking the GrGpu interface for now

+     * TODO: define appropriate higher-level API for context

+     */

+

+    GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);

+

+    GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);

+

+    bool reserveAndLockGeometry(GrVertexLayout    vertexLayout,

+                                uint32_t          vertexCount,

+                                uint32_t          indexCount,

+                                void**            vertices,

+                                void**            indices);

+

+    void drawIndexed(GrGpu::PrimitiveType type,

+                     uint32_t startVertex,

+                     uint32_t startIndex,

+                     uint32_t vertexCount,

+                     uint32_t indexCount);

+

+    void drawNonIndexed(GrGpu::PrimitiveType type,

+                        uint32_t startVertex,

+                        uint32_t vertexCount);

+

+    void setVertexSourceToArray(const void* array,

+                                GrVertexLayout vertexLayout);

+    void setIndexSourceToArray(const void* array);

+    void setVertexSourceToBuffer(GrVertexBuffer* buffer,

+                                GrVertexLayout vertexLayout);

+    void setIndexSourceToBuffer(GrIndexBuffer* buffer);

+

+    void releaseReservedGeometry();

+

+    void resetStats();

+

+    const GrGpu::Stats& getStats() const;

+

+    void printStats() const;

+

+    class AutoRenderTarget : ::GrNoncopyable {

+    public:

+        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {

+            fContext = NULL;

+            fPrevTarget = context->currentRenderTarget();

+            if (fPrevTarget != target) {

+                context->setRenderTarget(target);

+                fContext = context;

+            }

+        }

+        ~AutoRenderTarget() {

+            if (fContext) {

+                fContext->setRenderTarget(fPrevTarget);

+            }

+        }

+    private:

+        GrContext*      fContext;

+        GrRenderTarget* fPrevTarget;

+    };

+

+    /* -------------------------------------------------------

+     */

+

+    // Intended only to be used within Ganesh:

+    GrGpu* getGpu() { return fGpu; }

+    GrFontCache* getFontCache() { return fFontCache; }

+    GrDrawTarget* getTextTarget();

+    void flushText();

+

+    const GrIndexBuffer* quadIndexBuffer() const;

+    int maxQuadsInIndexBuffer() const;

+

+private:

+    GrGpu*          fGpu;

+    GrTextureCache* fTextureCache;

+    GrFontCache*    fFontCache;

+

+    GrVertexBufferAllocPool fVBAllocPool;

+    GrInOrderDrawBuffer     fTextDrawBuffer;

+

+    GrContext(GrGpu* gpu);

+    bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;

+

+    void drawClipIntoStencil();

+};

+

+/**

+ *  Save/restore the view-matrix in the context.

+ */

+class GrAutoViewMatrix : GrNoncopyable {

+public:

+    GrAutoViewMatrix(GrContext* ctx) : fContext(ctx) {

+        ctx->getViewMatrix(&fMatrix);

+    }

+    GrAutoViewMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {

+        ctx->getViewMatrix(&fMatrix);

+        ctx->setViewMatrix(matrix);

+    }

+    ~GrAutoViewMatrix() {

+        fContext->setViewMatrix(fMatrix);

+    }

+

+private:

+    GrContext*  fContext;

+    GrMatrix    fMatrix;

+};

+

+#endif

+
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
new file mode 100644
index 0000000..fee13a6
--- /dev/null
+++ b/gpu/include/GrDrawTarget.h
@@ -0,0 +1,736 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrDrawTarget_DEFINED
+#define GrDrawTarget_DEFINED
+
+#include "GrScalar.h"
+#include "GrMatrix.h"
+#include "GrColor.h"
+#include "GrRefCnt.h"
+#include "GrSamplerState.h"
+#include "GrClip.h"
+
+class GrTexture;
+class GrRenderTarget;
+class GrClipIterator;
+class GrVertexBuffer;
+class GrIndexBuffer;
+
+class GrDrawTarget : public GrRefCnt {
+public:
+    /**
+     * Geometric primitives used for drawing.
+     */
+    enum PrimitiveType {
+        kTriangles_PrimitiveType,
+        kTriangleStrip_PrimitiveType,
+        kTriangleFan_PrimitiveType,
+        kPoints_PrimitiveType,
+        kLines_PrimitiveType,
+        kLineStrip_PrimitiveType
+    };
+
+    /**
+     *  Flags that affect rendering. Controlled using enable/disableState(). All
+     *  default to disabled.
+     */
+    enum StateBits {
+        kDither_StateBit          = 0x1,//<! Perform color dithering
+        kAntialias_StateBit       = 0x2,//<! Perform anti-aliasing. The render-
+                                        //   target must support some form of AA
+                                        //   (msaa, coverage sampling, etc). For
+                                        //   GrGpu-created rendertarget/textures
+                                        //   this is controlled by parameters
+                                        //   passed to createTexture.
+        kClip_StateBit            = 0x4,//<! Controls whether drawing is clipped
+                                        //   against the region specified by
+                                        //   setClip.
+    };
+
+    /**
+     * Coeffecients for alpha-blending.
+     */
+    enum BlendCoeff {
+        kZero_BlendCoeff,    //<! 0
+        kOne_BlendCoeff,     //<! 1
+        kSC_BlendCoeff,      //<! src color
+        kISC_BlendCoeff,     //<! one minus src color
+        kDC_BlendCoeff,      //<! dst color
+        kIDC_BlendCoeff,     //<! one minus dst color
+        kSA_BlendCoeff,      //<! src alpha
+        kISA_BlendCoeff,     //<! one minus src alpha
+        kDA_BlendCoeff,      //<! dst alpha
+        kIDA_BlendCoeff,     //<! one minus dst alpha
+    };
+
+    /**
+     * StencilPass
+     *
+     * Sets the stencil state for subsequent draw calls. Used to fill paths.
+     *
+     * Winding requires two passes when the GPU/API doesn't support separate
+     * stencil.
+     *
+     * The color pass for path fill is used to zero out stencil bits used for
+     * path filling. Every pixel covere by a winding/EO stencil pass must get
+     * covered by the color pass in order to leave stencil buffer in the correct
+     * state for the next path draw.
+     *
+     * NOTE: Stencil-based Winding fill has alias-to-zero problems. (e.g. A
+     * winding count of 128,256,512,etc with a 8 bit stencil buffer
+     * will be unfilled)
+     */
+    enum StencilPass {
+        kNone_StencilPass,            //<! Not drawing a path or clip.
+        kEvenOddStencil_StencilPass,  //<! records in/out in stencil buffer
+                                      //   using the Even/Odd fill rule.
+        kEvenOddColor_StencilPass,    //<! writes colors to color target in
+                                      //   pixels marked inside the fill by
+                                      //   kEOFillStencil_StencilPass. Clears
+                                      //   stencil in pixels covered by
+                                      //   geometry.
+        kWindingStencil1_StencilPass, //<! records in/out in stencil buffer
+                                      //   using the Winding fill rule.
+        kWindingStencil2_StencilPass, //<! records in/out in stencil buffer
+                                      //   using the Winding fill rule.
+                                      //   Run when single-stencil-pass winding
+                                      //   not supported (i.e. no separate
+                                      //   stencil support)
+        kWindingColor_StencilPass,    //<! writes colors to color target in
+                                      //   pixels marked inside the fill by
+                                      //   kWindFillStencil_StencilPass. Clears
+                                      //   stencil in pixels covered by
+                                      //   geometry.
+        kDrawTargetCount_StencilPass  //<! Subclass may extend this enum to use
+                                      //   the stencil for other purposes (e.g.
+                                      //   to do stencil-based clipping)
+                                      //   This value is provided as basis for
+                                      //   defining these extended enum values.
+    };
+
+protected:
+    enum MatrixMode {
+        kModelView_MatrixMode = 0,
+        kTexture_MatrixMode,
+
+        kMatrixModeCount
+    };
+
+    struct DrawState {
+        uint32_t                fFlagBits;
+        BlendCoeff          	fSrcBlend;
+        BlendCoeff          	fDstBlend;
+        GrTexture*          	fTexture;
+        GrSamplerState        	fSamplerState;
+        GrRenderTarget*     	fRenderTarget;
+        GrColor             	fColor;
+        float               	fPointSize;
+        StencilPass             fStencilPass;
+        bool                    fReverseFill;
+        GrMatrix                fMatrixModeCache[kMatrixModeCount];
+        bool operator ==(const DrawState& s) const {
+            return 0 == memcmp(this, &s, sizeof(DrawState));
+        }
+        bool operator !=(const DrawState& s) const { return !(*this == s); }
+    };
+
+public:
+    ///////////////////////////////////////////////////////////////////////////
+
+    GrDrawTarget();
+
+    /**
+     * Sets the current clip to the region specified by clip. All draws will be
+     * clipped against this clip if kClip_StateBit is enabled.
+     *
+     * @param description of the clipping region
+     */
+    void setClip(const GrClip& clip);
+
+    /**
+     * Gets the current clip.
+     *
+     * @return the clip.
+     */
+    const GrClip& getClip() const;
+
+    /**
+     * Sets the texture used at the next drawing call
+     *
+     * @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(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.
+     */
+    GrTexture* currentTexture() const;
+
+    /**
+     * Sets the rendertarget used at the next drawing call
+     *
+     * @param target  The render target to set. Must be a valid rendertarget.
+     *                That is it is a value that was returned by
+     *                currentRenderTarget() or GrTexture::asRenderTarget().
+     */
+    void setRenderTarget(GrRenderTarget* target);
+
+    /**
+     * Retrieves the currently set rendertarget.
+     *
+     * @return    The currently set render target.
+     */
+    GrRenderTarget* currentRenderTarget() const;
+
+    /**
+     * Sets the sampler state for the next draw.
+     *
+     * The sampler state determines the address wrap modes and
+     * filtering
+     *
+     * @param samplerState    Specifies the sampler state.
+     */
+    void setSamplerState(const GrSamplerState& samplerState);
+
+    /**
+     * Sets the matrix applied to texture coordinates.
+     *
+     * The post-matrix texture coordinates in the square [0,1]^2 cover the
+     * entire area of the texture. This means the full POT width when a NPOT
+     * texture is embedded in a POT width texture to meet the 3D API
+     * requirements. The texture matrix is applied both when the texture
+     * coordinates are explicit and when vertex positions are used as texture
+     * coordinates. In the latter case the texture matrix is applied to the
+     * pre-modelview position values.
+     *
+     * @param m the matrix used to transform the texture coordinates.
+     */
+    void setTextureMatrix(const GrMatrix& m) {
+        this->loadMatrix(m, kTexture_MatrixMode);
+    }
+
+    /**
+     * 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) {
+        this->loadMatrix(m, kModelView_MatrixMode);
+    }
+
+    /**
+     *  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 modelview matrix.
+     */
+    void concatViewMatrix(const GrMatrix& m);
+
+    /**
+     *  Sets color for next draw to a premultiplied-alpha color.
+     *
+     *  @param the color to set.
+     */
+    void setColor(GrColor);
+
+    /**
+     *  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);
+
+    /**
+     * Sets pass for path rendering
+     *
+     * @param pass of path rendering
+     */
+    void setStencilPass(StencilPass pass);
+
+    /**
+     * Reveses the in/out decision of the fill rule for path rendering.
+     * Only affects kEOFillColor_StencilPass and kWindingFillColor_StencilPass
+     *
+     * @param reverse true to reverse, false otherwise
+     */
+    void setReverseFill(bool reverse);
+
+    /**
+     * 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 fCurrDrawState.fFlagBits & kDither_StateBit;
+    }
+
+    /**
+     * Sets the size of points used the next time points are drawn.
+     *
+     * @param the point size
+     */
+    void setPointSize(float size);
+
+    /**
+     * 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(BlendCoeff srcCoef, BlendCoeff dstCoef);
+
+    /**
+     * Retrieves the current view matrix
+     * @param matrix will be the current view matrix after return.
+     */
+    void getViewMatrix(GrMatrix* matrix) 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;
+
+    /**
+     * Used to save and restore the GrGpu's drawing state
+     */
+    struct SavedDrawState {
+    private:
+        DrawState fState;
+        friend class GrDrawTarget;
+    };
+
+    /**
+     * Saves the current draw state. The state can be restored at a later time
+     * with restoreDrawState.
+     *
+     * See also AutoStateRestore class.
+     *
+     * @param   state will hold the state after the function returns.
+     */
+    void saveCurrentDrawState(SavedDrawState* state) const;
+
+    /**
+     * Restores previously saved draw state. The client guarantees that state
+     * was previously passed to saveCurrentDrawState and that the rendertarget
+     * and texture set at save are still valid.
+     *
+     * See also AutoStateRestore class.
+     *
+     * @param   state the previously saved state to restore.
+     */
+    void restoreDrawState(const SavedDrawState& state);
+
+    /**
+     * Copies the draw state from another target to this target.
+     *
+     * @param srcTarget     draw target used as src of the draw state.
+     */
+    void copyDrawState(const GrDrawTarget& srcTarget);
+
+    /**
+     * Flags that indicate the layout of vertex data.
+     *
+     * kSeparateTexCoord_VertexLayoutBit is incompatible with
+     * kPositionAsTexCoord_VertexLayoutBit. kTextFormat_VertexLayoutBit is
+     * incompatible with any other flags.
+     *
+     * When kTextFormat_VertexLayoutBit is set:
+     *      Texture coordinates are separate.
+     *      Positions and Texture coordinates are SkGpuTextVertex.
+     * For non-text vertices:
+     *      Position and texture coordinates are GrPoints.
+     *      Colors are GrColors.
+     *
+     * The order is always positions, texture coords, colors.
+     */
+    enum VertexLayoutBits {
+        kSeparateTexCoord_VertexLayoutBit   = 0x1, //<! vertices have texture
+                                                   //   coords that are not
+                                                   //   inferred from the
+                                                   //   positions
+        kPositionAsTexCoord_VertexLayoutBit = 0x2, //<! vertices use positions
+                                                   //   as texture coords.
+        kColor_VertexLayoutBit              = 0x4, //<! vertices have colors
+        kTextFormat_VertexLayoutBit         = 0x8, //<! vertices represent glyphs
+                                                   //   and therefore contain
+                                                   //   two GrGpuTextVertexs.
+                                                   //   One for pos and one for
+                                                   //   text coords.
+        // for below assert
+        kDummy,
+        kHighVertexLayoutBit = kDummy - 1
+    };
+    GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
+
+    /**
+     * Reserves space for vertices and/or indices. Draw target will use
+     * reserved vertices / indices at next draw.
+     *
+     * If succeeds:
+     *          if vertexCount is nonzero, *vertices will be the array
+     *          of vertices to be filled by caller. The next draw will read
+     *          these vertices.
+     *
+     *          if indecCount is nonzero, *indices will be the array of indices
+     *          to be filled by caller. The next indexed draw will read from
+     *          these indices.
+     *
+     * If a client does not already have a vertex buffer or cpu arrays then this
+     * is the preferred way to allocate vertex/index array. It allows the
+     * subclass of GrDrawTarget to decide whether to put data in buffers, to
+     * group vertex data that uses the same state (e.g. for deferred rendering),
+     * etc.
+     *
+     * This must be matched with a releaseReservedGeometry call after all
+     * draws that reference the reserved geometry data have been called.
+     *
+     * AutoGeometryRelease can be used to automatically call the release.
+     *
+     * @param vertexCount  the number of vertices to reserve space for. Can be 0.
+     * @param indexCount   the number of indices to reserve space for. Can be 0.
+     * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
+     * @param vertices     will point to reserved vertex space if vertexCount is
+     *                     non-zero. Illegal to pass NULL if vertexCount > 0.
+     * @param indices      will point to reserved index space if indexCount is
+     *                     non-zero. Illegal to pass NULL if indexCount > 0.
+     *
+     * @return  true if succeeded in allocating space for the vertices and false
+     *               if not.
+     */
+    bool reserveAndLockGeometry(GrVertexLayout    vertexLayout,
+                                uint32_t          vertexCount,
+                                uint32_t          indexCount,
+                                void**            vertices,
+                                void**            indices);
+    /**
+     * Provides hints to caller about the number of vertices and indices
+     * that can be allocated cheaply. This can be useful if caller is reserving
+     * space but doesn't know exactly how much geometry is needed.
+     *
+     * Also may hint whether the draw target should be flushed first. This is
+     * useful for deferred targets.
+     *
+     * @param vertexLayout layout of vertices caller would like to reserve
+     * @param vertexCount  in: hint about how many vertices the caller would
+     *                     like to allocate.
+     *                     out: a hint about the number of vertices that can be
+     *                     allocated cheaply. Negative means no hint.
+     *                     Ignored if NULL.
+     * @param indexCount   in: hint about how many indices the caller would
+     *                     like to allocate.
+     *                     out: a hint about the number of indices that can be
+     *                     allocated cheaply. Negative means no hint.
+     *                     Ignored if NULL.
+     *
+     * @return  true if target should be flushed based on the input values.
+     */
+    virtual bool geometryHints(GrVertexLayout vertexLayout,
+                               int32_t*       vertexCount,
+                               int32_t*       indexCount) const;
+
+    /**
+     * Releases reserved vertex/index data from reserveAndLockGeometry().
+     */
+    void releaseReservedGeometry();
+
+    /**
+     * Sets source of vertex data for the next draw. Data does not have to be
+     * in the array until drawIndexed or drawNonIndexed.
+     *
+     * @param array         cpu array containing vertex data.
+     * @param vertexLayout  layout of the vertex data in the array.
+     */
+    void setVertexSourceToArray(const void* array, GrVertexLayout vertexLayout);
+
+    /**
+     * Sets source of index data for the next indexed draw. Data does not have
+     * to be in the array until drawIndexed or drawNonIndexed.
+     *
+     * @param array cpu array containing index data.
+     */
+    void setIndexSourceToArray(const void* array);
+
+    /**
+     * Sets source of vertex data for the next draw. Data does not have to be
+     * in the buffer until drawIndexed or drawNonIndexed.
+     *
+     * @param buffer        vertex buffer containing vertex data. Must be
+     *                      unlocked before draw call.
+     * @param vertexLayout  layout of the vertex data in the buffer.
+     */
+    void setVertexSourceToBuffer(const GrVertexBuffer* buffer,
+                                 GrVertexLayout vertexLayout);
+
+    /**
+     * Sets source of index data for the next indexed draw. Data does not have
+     * to be in the buffer until drawIndexed or drawNonIndexed.
+     *
+     * @param buffer index buffer containing indices. Must be unlocked
+     *               before indexed draw call.
+     */
+    void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
+
+    /**
+     * Draws indexed geometry using the current state and current vertex / index
+     * sources.
+     *
+     * @param type         The type of primitives to draw.
+     * @param startVertex  the vertex in the vertex array/buffer corresponding
+     *                     to index 0
+     * @param startIndex   first index to read from index src.
+     * @param vertexCount  one greater than the max index.
+     * @param indexCount   the number of index elements to read. The index count
+     *                     is effectively trimmed to the last completely
+     *                     specified primitive.
+     */
+    virtual void drawIndexed(PrimitiveType type,
+                             uint32_t startVertex,
+                             uint32_t startIndex,
+                             uint32_t vertexCount,
+                             uint32_t indexCount) = 0;
+
+    /**
+     * Draws non-indexed geometry using the current state and current vertex
+     * sources.
+     *
+     * @param type         The type of primitives to draw.
+     * @param startVertex  the vertex in the vertex array/buffer corresponding
+     *                     to index 0
+     * @param vertexCount  one greater than the max index.
+     */
+    virtual void drawNonIndexed(PrimitiveType type,
+                                uint32_t startVertex,
+                                uint32_t vertexCount)  = 0;
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class AutoStateRestore : ::GrNoncopyable {
+    public:
+        AutoStateRestore(GrDrawTarget* target);
+        ~AutoStateRestore();
+
+    private:
+        GrDrawTarget*       fDrawTarget;
+        SavedDrawState      fDrawState;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class AutoReleaseGeometry : ::GrNoncopyable {
+    public:
+        AutoReleaseGeometry(GrDrawTarget*  target,
+                            GrVertexLayout vertexLayout,
+                            uint32_t       vertexCount,
+                            uint32_t       indexCount) {
+            fTarget = target;
+            fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
+                                                       vertexCount,
+                                                       indexCount,
+                                                       &fVertices,
+                                                       &fIndices);
+        }
+        ~AutoReleaseGeometry() {
+            if (fSuccess) {
+                fTarget->releaseReservedGeometry();
+            }
+        }
+
+        bool succeeded() const { return fSuccess; }
+        void* vertices() const { return fVertices; }
+        void* indices() const { return fIndices; }
+
+        GrPoint* positions() const {
+            return static_cast<GrPoint*>(fVertices);
+        }
+
+    private:
+        GrDrawTarget* fTarget;
+        bool          fSuccess;
+        void*         fVertices;
+        void*         fIndices;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class AutoClipRestore : ::GrNoncopyable {
+    public:
+        AutoClipRestore(GrDrawTarget* target) {
+            fTarget = target;
+            fClip = fTarget->getClip();
+        }
+
+        ~AutoClipRestore() {
+            fTarget->setClip(fClip);
+        }
+    private:
+        GrDrawTarget* fTarget;
+        GrClip        fClip;
+    };
+
+    ////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Helper function to compute the size of a vertex from a vertex layout
+     * @return size of a single vertex.
+     */
+    static size_t VertexSize(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the offset of texture coordinates in a vertex
+     * @return offset of texture coordinates in vertex layout or -1 if the
+     *         layout has no texture coordinates.
+     */
+    static int VertexTexCoordOffset(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute the offset of the color in a vertex
+     * @return offset of color in vertex layout or -1 if the
+     *         layout has no color.
+     */
+    static int VertexColorOffset(GrVertexLayout vertexLayout);
+
+    /**
+     * Helper function to compute vertex size and component offsets.
+     * @param texCoordOffset  after return it is the offset of texture coords
+     *                        in vertex layout or -1 if the layout has no
+     *                        texture coords.
+     * @param colorOffset     after return it is the offset of color in vertex
+     *                        layout or -1 if the layout has no color.
+     * @return size of a single vertex.
+     */
+    static int VertexSizeAndOffsets(GrVertexLayout vertexLayout,
+                                    int* texCoordOffset,
+                                    int* colorOffset);
+    /**
+     * Helper function to determine if vertex layout contains either explicit or
+     * implicit texture coordinates.
+     *
+     * @return true if vertex specifies texture coordinates, false otherwise.
+     */
+    static bool VertexHasTexCoords(GrVertexLayout vertexLayout);
+
+protected:
+
+    // Helpers for GrDrawTarget subclasses that won't have private access to
+    // SavedDrawState but need to peek at the state values.
+    static DrawState& accessSavedDrawState(SavedDrawState& sds)
+                                                        { return sds.fState; }
+    static const DrawState& accessSavedDrawState(const SavedDrawState& sds)
+                                                        { return sds.fState; }
+
+    // implemented by subclass
+    virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                       void** vertices,
+                                       void** indices) = 0;
+
+    virtual void releaseGeometryHelper() = 0;
+
+    virtual void clipWillChange(const GrClip& clip) = 0;
+
+    enum GeometrySrcType {
+        kArray_GeometrySrcType,
+        kReserved_GeometrySrcType,
+        kBuffer_GeometrySrcType
+    };
+
+    struct {
+        bool            fLocked;
+        uint32_t        fVertexCount;
+        uint32_t        fIndexCount;
+    } fReservedGeometry;
+
+    struct GeometrySrc {
+        GeometrySrcType             fVertexSrc;
+        union {
+            const GrVertexBuffer*   fVertexBuffer;
+            const void*             fVertexArray;
+        };
+        GeometrySrcType             fIndexSrc;
+        union {
+            const GrIndexBuffer*    fIndexBuffer;
+            const void*             fIndexArray;
+        };
+        GrVertexLayout              fVertexLayout;
+    } fGeometrySrc;
+
+    GrClip fClip;
+
+    DrawState fCurrDrawState;
+
+    // set texture or modelview matrix
+    void loadMatrix(const GrMatrix&, MatrixMode);
+
+    // not meant for outside usage. Could cause problems if calls between
+    // the save and restore mess with reserved geometry state.
+    class AutoGeometrySrcRestore {
+    public:
+        AutoGeometrySrcRestore(GrDrawTarget* target) {
+            fTarget = target;
+            fGeometrySrc = fTarget->fGeometrySrc;
+        }
+        ~AutoGeometrySrcRestore() {
+            fTarget->fGeometrySrc = fGeometrySrc;
+        }
+    private:
+        GrDrawTarget *fTarget;
+        GeometrySrc  fGeometrySrc;
+
+        AutoGeometrySrcRestore();
+        AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
+        AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
+    };
+
+};
+
+#endif
diff --git a/gpu/include/GrFontScaler.h b/gpu/include/GrFontScaler.h
new file mode 100644
index 0000000..6baa56f
--- /dev/null
+++ b/gpu/include/GrFontScaler.h
@@ -0,0 +1,43 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrFontScaler_DEFINED
+#define GrFontScaler_DEFINED
+
+#include "GrGlyph.h"
+#include "GrKey.h"
+
+class GrPath;
+
+/**
+ *  This is a virtual base class which Gr's interface to the host platform's
+ *  font scaler.
+ *
+ *  The client is responsible for subclassing, and instantiating this. The
+ *  instance is create for a specific font+size+matrix.
+ */
+class GrFontScaler : public GrRefCnt {
+public:
+    virtual const GrKey* getKey() = 0;
+    virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds) = 0;
+    virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+                                     int rowBytes, void* image) = 0;
+    virtual bool getGlyphPath(uint16_t glyphID, GrPath*) = 0;
+};
+
+#endif
+
diff --git a/gpu/include/GrGLConfig.h b/gpu/include/GrGLConfig.h
new file mode 100644
index 0000000..90763ab
--- /dev/null
+++ b/gpu/include/GrGLConfig.h
@@ -0,0 +1,323 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLConfig_DEFINED
+#define GrGLConfig_DEFINED
+
+#include "GrTypes.h"
+
+#if GR_WIN32_BUILD
+    // glew has to be included before gl
+    #define GR_INCLUDE_GLDESKTOP    <GL/glew.h>
+    #define GR_INCLUDE_GLDESKTOPext <GL/gl.h>
+    #define GR_GL_FUNC __stdcall
+    // undo stupid windows defines
+    #undef near
+    #undef far
+#elif GR_MAC_BUILD
+    #define GR_INCLUDE_GLDESKTOP    <OpenGL/gl.h>
+    #define GR_INCLUDE_GLDESKTOPext <OpenGL/glext.h>
+    #define GR_GL_FUNC
+#elif GR_IOS_BUILD
+    #define GR_INCLUDE_GLES1       <OpenGLES/ES1/gl.h>
+    #define GR_INCLUDE_GLES1ext    <OpenGLES/ES1/glext.h>
+    #define GR_INCLUDE_GLES2       <OpenGLES/ES2/gl.h>
+    #define GR_INCLUDE_GLES2ext    <OpenGLES/ES2/glext.h>
+    #define GR_GL_FUNC
+#elif GR_ANDROID_BUILD
+    #ifndef GL_GLEXT_PROTOTYPES
+        #define GL_GLEXT_PROTOTYPES
+    #endif
+    #define GR_INCLUDE_GLES2        <GLES2/gl2.h>
+    #define GR_INCLUDE_GLES2ext     <GLES2/gl2ext.h>
+    #define GR_GL_FUNC
+#elif GR_LINUX_BUILD
+    // need to distinguish between ES and Deskop versions for linux
+    #ifndef GL_GLEXT_PROTOTYPES
+        #define GL_GLEXT_PROTOTYPES
+    #endif
+    #define GR_INCLUDE_GLES1        <GLES/gl.h>
+    #define GR_INCLUDE_GLES1ext     <GLES/glext.h>
+    #define GR_INCLUDE_GLES2        <GLES2/gl2.h>
+    #define GR_INCLUDE_GLES2ext     <GLES2/gl2ext.h>
+    #define GR_GL_FUNC
+#elif GR_QNX_BUILD
+    #ifndef GL_GLEXT_PROTOTYPES
+        #define GL_GLEXT_PROTOTYPES
+    #endif
+    // This is needed by the QNX GLES2 headers
+    #define GL_API_EXT
+    #define GR_INCLUDE_GLES2        <GLES2/gl2.h>
+    #define GR_INCLUDE_GLES2ext     <GLES2/gl2ext.h>
+    #define GR_INCLUDE_EGL          <EGL/egl.h>
+    #define GR_GL_FUNC
+#else
+    #error "unsupported GR_???_BUILD"
+#endif
+
+// Ensure we're at least defined
+//
+
+#ifndef GR_SUPPORT_GLES1
+    #if defined(GR_INCLUDE_GLES1)
+        #define GR_SUPPORT_GLES1        1
+    #else
+        #define GR_SUPPORT_GLES1        0
+    #endif
+#endif
+
+#ifndef GR_SUPPORT_GLES2
+    #if defined(GR_INCLUDE_GLES2)
+        #define GR_SUPPORT_GLES2        1
+    #else
+        #define GR_SUPPORT_GLES2        0
+    #endif
+#endif
+
+#ifndef GR_SUPPORT_GLDESKTOP
+    #if defined(GR_INCLUDE_GLDESKTOP)
+        #define GR_SUPPORT_GLDESKTOP    1
+    #else
+        #define GR_SUPPORT_GLDESKTOP    0
+    #endif
+#endif
+
+#ifndef GR_SUPPORT_EGL
+    #if defined(GR_INCLUDE_EGL)
+        #define GR_SUPPORT_EGL          1
+    #else
+        #define GR_SUPPORT_EGL          0
+    #endif
+#endif
+// Filter the includes based on what we support
+//
+
+#if !GR_SUPPORT_GLES1
+    #undef GR_INCLUDE_GLES1
+    #undef GR_INCLUDE_GLES1ext
+#endif
+
+#if !GR_SUPPORT_GLES2
+    #undef GR_INCLUDE_GLES2
+    #undef GR_INCLUDE_GLES2ext
+#endif
+
+#if !GR_SUPPORT_GLDESKTOP
+    #undef GR_INCLUDE_GLDESKTOP
+    #undef GR_INCLUDE_GLDESKTOPext
+#endif
+
+#if !GR_SUPPORT_EGL
+    #undef GR_INCLUDE_EGL
+#endif
+
+// Begin including GL headers
+//
+
+#ifdef GR_INCLUDE_GLES1
+    #include GR_INCLUDE_GLES1
+#endif
+#ifdef GR_INCLUDE_GLES1ext
+    #include GR_INCLUDE_GLES1ext
+#endif
+#ifdef GR_INCLUDE_GLES2
+    #include GR_INCLUDE_GLES2
+#endif
+#ifdef GR_INCLUDE_GLES2ext
+    #include GR_INCLUDE_GLES2ext
+#endif
+#ifdef GR_INCLUDE_GLDESKTOP
+    #include GR_INCLUDE_GLDESKTOP
+#endif
+#ifdef GR_INCLUDE_GLDESKTOPext
+    #include GR_INCLUDE_GLDESKTOPext
+#endif
+#ifdef GR_INCLUDE_EGL
+    #include GR_INCLUDE_EGL
+#endif
+
+//
+// End including GL headers
+
+#if GL_VERSION_1_1
+    #define GR_GL_DESKTOP   1
+    #define GR_GL_ES        0
+#else
+    #ifndef GL_ES_VERSION_2_0
+        GR_STATIC_ASSERT(GL_VERSION_ES_CM_1_0 || 
+                         GL_VERSION_ES_CL_1_0 || 
+                         GL_VERSION_ES_CM_1_1 ||
+                         GL_VERSION_ES_CL_1_1);
+    #endif
+    #define GR_GL_DESKTOP   0
+    #define GR_GL_ES        1
+#endif
+
+#if GR_SCALAR_IS_FIXED
+    #define GrGLType   GL_FIXED
+#elif GR_SCALAR_IS_FLOAT
+    #define GrGLType   GL_FLOAT
+#else
+    #error "unknown GR_SCALAR type"
+#endif
+
+#if GR_TEXT_SCALAR_IS_USHORT
+    #define GrGLTextType                    GL_UNSIGNED_SHORT
+    #define GR_GL_TEXT_TEXTURE_NORMALIZED   1
+#elif GR_TEXT_SCALAR_IS_FLOAT
+    #define GrGLTextType                    GL_FLOAT
+    #define GR_GL_TEXT_TEXTURE_NORMALIZED   0
+#elif GR_TEXT_SCALAR_IS_FIXED
+    #define GrGLTextType                    GL_FIXED
+    #define GR_GL_TEXT_TEXTURE_NORMALIZED   0
+#else 
+    #error "unknown GR_TEXT_SCALAR type"
+#endif
+
+// Pick a pixel config for 32bit bitmaps. Our default is GL_RGBA
+#ifndef SK_GL_32BPP_COLOR_FORMAT    
+    #define SK_GL_32BPP_COLOR_FORMAT    GL_RGBA    
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// setup for opengl ES/desktop extensions
+// we make a struct of function pointers so that each GL context
+// can have it's own struct. (Some environments may have different proc 
+// addresses for different contexts).
+
+extern "C" {
+struct GrGLExts {
+// FBO
+    GLvoid (GR_GL_FUNC *GenFramebuffers)(GLsizei n, GLuint *framebuffers);
+    GLvoid (GR_GL_FUNC *BindFramebuffer)(GLenum target, GLuint framebuffer);
+    GLvoid (GR_GL_FUNC *FramebufferTexture2D)(GLenum target, GLenum attachment,
+                                              GLenum textarget, GLuint texture, 
+                                              GLint level);
+    GLenum (GR_GL_FUNC *CheckFramebufferStatus)(GLenum target);
+    GLvoid (GR_GL_FUNC *DeleteFramebuffers)(GLsizei n, const 
+                                            GLuint *framebuffers);
+    GLvoid (GR_GL_FUNC *RenderbufferStorage)(GLenum target, 
+                                             GLenum internalformat,
+                                             GLsizei width, GLsizei height);
+    GLvoid (GR_GL_FUNC *GenRenderbuffers)(GLsizei n, GLuint *renderbuffers);
+    GLvoid (GR_GL_FUNC *DeleteRenderbuffers)(GLsizei n, 
+                                             const GLuint *renderbuffers);
+    GLvoid (GR_GL_FUNC *FramebufferRenderbuffer)(GLenum target, 
+                                                 GLenum attachment,
+                                                 GLenum renderbuffertarget, 
+                                                 GLuint renderbuffer);
+    GLvoid (GR_GL_FUNC *BindRenderbuffer)(GLenum target, GLuint renderbuffer);
+
+// Multisampling
+    // same prototype for ARB_FBO, EXT_FBO, GL 3.0, & Apple ES extension
+    GLvoid (GR_GL_FUNC *RenderbufferStorageMultisample)(GLenum target, 
+                                                        GLsizei samples,
+                                                        GLenum internalformat,
+                                                        GLsizei width, 
+                                                        GLsizei height);
+    // desktop: ext_fbo_blit, arb_fbo, gl 3.0
+    GLvoid (GR_GL_FUNC *BlitFramebuffer)(GLint srcX0, GLint srcY0, 
+                                         GLint srcX1, GLint srcY1,
+                                         GLint dstX0, GLint dstY0, 
+                                         GLint dstX1, GLint dstY1,
+                                         GLbitfield mask, GLenum filter);
+    // apple's es extension
+    GLvoid (GR_GL_FUNC *ResolveMultisampleFramebuffer)();
+
+    // IMG'e es extension
+    GLvoid (GR_GL_FUNC *FramebufferTexture2DMultisample)(GLenum target, 
+                                                         GLenum attachment,
+                                                         GLenum textarget, 
+                                                         GLuint texture, 
+                                                         GLint level, 
+                                                         GLsizei samples);
+
+// Buffer mapping (extension in ES).
+    GLvoid* (GR_GL_FUNC *MapBuffer)(GLenum target, GLenum access);
+    GLboolean (GR_GL_FUNC *UnmapBuffer)(GLenum target);
+};
+}
+
+// FBO
+#define GR_FRAMEBUFFER              0x8D40
+#define GR_FRAMEBUFFER_COMPLETE     0x8CD5
+#define GR_COLOR_ATTACHMENT0        0x8CE0
+#define GR_FRAMEBUFFER_BINDING      0x8CA6          
+#define GR_RENDERBUFFER             0x8D41
+#define GR_STENCIL_ATTACHMENT       0x8D20
+#define GR_STENCIL_INDEX8           0x8D48
+#define GR_STENCIL_INDEX16          0x8D49
+#define GR_MAX_RENDERBUFFER_SIZE    0x84E8
+#define GR_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GR_UNSIGNED_INT_24_8        0x84FA
+#define GR_DEPTH_STENCIL            0x84F9
+#define GR_RGBA8                    0x8058
+#define GR_RGB565                   0x8D62
+
+
+// Multisampling
+
+// IMG MAX_SAMPLES uses a different value than desktop, Apple ES extension.
+#define GR_MAX_SAMPLES              0x8D57
+#define GR_MAX_SAMPLES_IMG          0x9135
+#define GR_READ_FRAMEBUFFER         0x8CA8
+#define GR_DRAW_FRAMEBUFFER         0x8CA9
+
+// Buffer mapping
+#define GR_WRITE_ONLY               0x88B9
+#define GR_BUFFER_MAPPED            0x88BC
+
+// Palette texture
+#define GR_PALETTE8_RGBA8           0x8B91
+
+extern void GrGLInitExtensions(GrGLExts* exts);
+////////////////////////////////////////////////////////////////////////////////
+          
+extern void GrGLCheckErr(const char* location, const char* call);
+
+static inline void GrGLClearErr() {
+    while (GL_NO_ERROR != glGetError()) {} 
+}
+
+// GR_FORCE_GLCHECKERR can be defined by GrUserConfig.h
+#if defined(GR_FORCE_GLCHECKERR)
+    #define GR_LOCAL_CALL_CHECKERR GR_FORCE_GLCHECKERR
+#else
+    #define GR_LOCAL_CALL_CHECKERR GR_DEBUG
+#endif
+static inline void GrDebugGLCheckErr(const char* location, const char* call) {
+#if GR_LOCAL_CALL_CHECKERR
+    GrGLCheckErr(location, call);
+#endif
+}
+#undef GR_LOCAL_CALL_CHECKERR
+
+#if GR_GL_LOG_CALLS
+    extern bool gPrintGL;
+    #define GR_GL(X)                 gl ## X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X); if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+    #define GR_GL_NO_ERR(X)          GrGLClearErr(); gl ## X; if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+    #define GR_GLEXT(exts, X)        exts. X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X); if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+    #define GR_GLEXT_NO_ERR(exts, X) GrGLClearErr(); exts. X; if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+#else
+    #define GR_GL(X)                 gl ## X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X)
+    #define GR_GL_NO_ERR(X)          GrGLClearErr(); gl ## X
+    #define GR_GLEXT(exts, X)        exts. X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X)
+    #define GR_GLEXT_NO_ERR(exts, X) GrGLClearErr(); exts. X
+#endif
+
+#endif
+
diff --git a/gpu/include/GrGLIndexBuffer.h b/gpu/include/GrGLIndexBuffer.h
new file mode 100644
index 0000000..5177b4b
--- /dev/null
+++ b/gpu/include/GrGLIndexBuffer.h
@@ -0,0 +1,53 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLIndexBuffer_DEFINED
+#define GrGLIndexBuffer_DEFINED
+
+#include "GrIndexBuffer.h"
+#include "GrGLConfig.h"
+
+class GrGpuGL;
+
+class GrGLIndexBuffer : public GrIndexBuffer {
+protected:
+    GrGLIndexBuffer(GLuint id,
+                    GrGpuGL* gl,
+                    uint32_t sizeInBytes,
+                    bool dynamic);
+public:
+    virtual ~GrGLIndexBuffer();
+
+    GLuint bufferID() const;
+
+    // overrides of GrIndexBuffer
+    virtual void abandon();
+    virtual void* lock();
+    virtual void unlock();
+    virtual bool isLocked() const;
+    virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+private:
+    GrGpuGL*     fGL;
+    GLuint       fBufferID;
+    void*        fLockPtr;
+    
+    friend class GrGpuGL;
+
+    typedef GrIndexBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h
new file mode 100644
index 0000000..ada3151
--- /dev/null
+++ b/gpu/include/GrGLTexture.h
@@ -0,0 +1,166 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLTexture_DEFINED
+#define GrGLTexture_DEFINED
+
+#include "GrGLConfig.h"
+#include "GrGpu.h"
+#include "GrTexture.h"
+#include "GrRect.h"
+
+class GrGpuGL;
+class GrGLTexture;
+
+class GrGLRenderTarget : public GrRenderTarget {
+protected:
+    
+    struct GLRenderTargetIDs {
+        GLuint      fRTFBOID;
+        GLuint      fTexFBOID;
+        GLuint      fStencilRenderbufferID;
+        GLuint      fMSColorRenderbufferID;
+        bool        fOwnIDs;
+    };
+    
+    GrGLRenderTarget(const GLRenderTargetIDs& ids, 
+                     const GrIRect& fViewport,
+                     GrGLTexture* texture,
+                     GrGpuGL* gl);
+    
+    void setViewport(const GrIRect& rect) { GrAssert(rect.height() <= 0); 
+                                            fViewport = rect;}
+    
+    virtual uint32_t width() const { return fViewport.width(); }
+    virtual uint32_t height() const { return -fViewport.height(); }
+    
+public:
+    virtual ~GrGLRenderTarget();
+    
+    bool resolveable() const { return fRTFBOID != fTexFBOID; }
+    bool needsResolve() const { return fNeedsResolve; }
+    void setDirty(bool dirty) { fNeedsResolve = resolveable() && dirty; }
+    
+    GLuint renderFBOID() const { return fRTFBOID; }
+    GLuint textureFBOID() const { return fTexFBOID; }
+
+    const GrIRect& viewport() const { return fViewport; }
+    void   abandon();
+
+private:
+    GrGpuGL*    fGL;
+    GLuint      fRTFBOID;
+    GLuint      fTexFBOID;    
+    GLuint      fStencilRenderbufferID;
+    GLuint      fMSColorRenderbufferID;
+   
+    // Should this object delete IDs when it is destroyed or does someone
+    // else own them.
+    bool        fOwnIDs;
+    
+    // If there separate Texture and RenderTarget FBO IDs then the rendertarget
+    // must be resolved to the texture FBO before it is used as a texture.
+    bool fNeedsResolve;
+    
+    // when we switch to this rendertarget we want to set the viewport to 
+    // only render to to content area (as opposed to the whole allocation) and
+    // we want the rendering to be at top left (GL has origin in bottom left) 
+    GrIRect fViewport;
+    
+    friend class GrGpuGL;
+    friend class GrGLTexture;
+    
+    typedef GrRenderTarget INHERITED;
+};
+
+class GrGLTexture : public GrTexture {
+public:
+    enum Orientation {
+        kBottomUp_Orientation,
+        kTopDown_Orientation,
+    };
+
+protected:
+    struct GLTextureDesc {
+        uint32_t    fContentWidth;
+        uint32_t    fContentHeight;
+        uint32_t    fAllocWidth;
+        uint32_t 	fAllocHeight;
+        PixelConfig fFormat;
+        GLuint      fTextureID;
+        GLenum      fUploadFormat;
+        GLenum      fUploadByteCount;
+        GLenum      fUploadType;
+        Orientation fOrientation;
+    };
+    typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs;
+    GrGLTexture(const GLTextureDesc& textureDesc,
+                const GLRenderTargetIDs& rtIDs,
+                GrGpuGL* gl);
+
+public:
+    virtual ~GrGLTexture();
+    
+    // overloads of GrTexture
+    virtual void abandon();
+    virtual bool isRenderTarget() const;
+    virtual GrRenderTarget* asRenderTarget();
+    virtual void removeRenderTarget();
+    virtual void uploadTextureData(uint32_t x,
+                                   uint32_t y,
+                                   uint32_t width,
+                                   uint32_t height,
+                                   const void* srcData);
+    virtual intptr_t getTextureHandle();
+
+    const GrSamplerState& samplerState() const { return fSamplerState; }
+    void setSamplerState(const GrSamplerState& state) 
+                                                    { fSamplerState = state; }
+    GLuint textureID() const { return fTextureID; }
+
+    GLenum uploadFormat() const { return fUploadFormat; }
+    GLenum uploadByteCount() const { return fUploadByteCount; }
+    GLenum uploadType() const { return fUploadType; }
+
+    // Ganesh assumes texture coordinates have their origin
+    // in the top-left corner of the image. OpenGL, however,
+    // has the origin in the lower-left corner. For content that
+    // is loaded by Ganesh we just push the content "upside down"
+    // (by GL's understanding of the world ) in glTex*Image and the 
+    // addressing just works out. However, content generated by GL 
+    // (FBO or externally imported texture) will be updside down 
+    // and it is up to the GrGpuGL derivative to handle y-mirroing.
+    Orientation orientation() const { return fOrientation; }
+
+private:
+    GrSamplerState      fSamplerState;
+    GLuint              fTextureID;
+    GLenum              fUploadFormat;
+    GLenum              fUploadByteCount;
+    GLenum              fUploadType;
+    Orientation         fOrientation;
+    GrGLRenderTarget*   fRenderTarget;    
+    GrGpuGL*            fGpuGL;
+    
+    static const GLenum gWrapMode2GLWrap[];
+
+    friend class GrGpuGL;
+
+    typedef GrTexture INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGLVertexBuffer.h b/gpu/include/GrGLVertexBuffer.h
new file mode 100644
index 0000000..6b99f57
--- /dev/null
+++ b/gpu/include/GrGLVertexBuffer.h
@@ -0,0 +1,55 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGLVertexBuffer_DEFINED
+#define GrGLVertexBuffer_DEFINED
+
+#include "GrVertexBuffer.h"
+#include "GrGLConfig.h"
+
+class GrGpuGL;
+
+class GrGLVertexBuffer : public GrVertexBuffer {
+protected:
+    GrGLVertexBuffer(GLuint id,
+                     GrGpuGL* gl,
+                     uint32_t sizeInBytes,
+                     bool dynamic);
+
+public:
+    virtual ~GrGLVertexBuffer();
+    
+    // overrides of GrVertexBuffer
+    virtual void abandon();
+    virtual void* lock();
+    virtual void unlock();
+    virtual bool isLocked() const;
+    virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+
+    GLuint bufferID() const;
+
+private:
+    GrGpuGL*     fGL;
+    GLuint       fBufferID;
+    void*        fLockPtr;
+
+    friend class GrGpuGL;
+
+    typedef GrVertexBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGlyph.h b/gpu/include/GrGlyph.h
new file mode 100644
index 0000000..4a3b307
--- /dev/null
+++ b/gpu/include/GrGlyph.h
@@ -0,0 +1,89 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGlyph_DEFINED
+#define GrGlyph_DEFINED
+
+#include "GrPath.h"
+#include "GrRect.h"
+
+class GrAtlas;
+
+/*  Need this to be quad-state:
+    - complete w/ image
+    - just metrics
+    - failed to get image, but has metrics
+    - failed to get metrics
+ */
+struct GrGlyph {
+    typedef uint32_t PackedID;
+
+    GrAtlas*    fAtlas;
+    GrPath*     fPath;
+    PackedID    fPackedID;
+    GrIRect16   fBounds;
+    GrIPoint16  fAtlasLocation;
+
+    void init(GrGlyph::PackedID packed, const GrIRect& bounds) {
+        fAtlas = NULL;
+        fPath = NULL;
+        fPackedID = packed;
+        fBounds.set(bounds);
+        fAtlasLocation.set(0, 0);
+    }
+    
+    void free() {
+        if (fPath) {
+            delete fPath;
+            fPath = NULL;
+        }
+    }
+    
+    int width() const { return fBounds.width(); }
+    int height() const { return fBounds.height(); }
+    bool isEmpty() const { return fBounds.isEmpty(); }
+    uint16_t glyphID() const { return UnpackID(fPackedID); }
+
+    ///////////////////////////////////////////////////////////////////////////
+    
+    static inline unsigned ExtractSubPixelBitsFromFixed(GrFixed pos) {
+        // two most significant fraction bits from fixed-point
+        return (pos >> 14) & 3;
+    }
+    
+    static inline PackedID Pack(uint16_t glyphID, GrFixed x, GrFixed y) {
+        x = ExtractSubPixelBitsFromFixed(x);
+        y = ExtractSubPixelBitsFromFixed(y);
+        return (x << 18) | (y << 16) | glyphID;
+    }
+    
+    static inline GrFixed UnpackFixedX(PackedID packed) {
+        return ((packed >> 18) & 3) << 14;
+    }
+    
+    static inline GrFixed UnpackFixedY(PackedID packed) {
+        return ((packed >> 16) & 3) << 14;
+    }
+    
+    static inline uint16_t UnpackID(PackedID packed) {
+        return (uint16_t)packed;
+    }
+};
+
+
+#endif
+
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
new file mode 100644
index 0000000..f1fdf01
--- /dev/null
+++ b/gpu/include/GrGpu.h
@@ -0,0 +1,446 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpu_DEFINED
+#define GrGpu_DEFINED
+
+#include "GrRect.h"
+#include "GrRefCnt.h"
+#include "GrDrawTarget.h"
+#include "GrGpuVertex.h"
+#include "GrTexture.h"
+#include "GrMemory.h"
+
+
+class GrGpu : public GrDrawTarget {
+
+public:
+    /**
+     * Possible 3D APIs that may be used by Ganesh.
+     */
+    enum Engine {
+        kOpenGL_Shaders_Engine,
+        kOpenGL_Fixed_Engine,
+        kDirect3D9_Engine
+    };
+
+    /**
+     * Platform specific 3D context.
+     * For
+     *    kOpenGL_Shaders_Engine use NULL
+     *    kOpenGL_Fixed_Engine   use NULL
+     *    kDirect3D9_Engine      use an IDirect3DDevice9*
+     */
+    typedef void* Platform3DContext;
+
+    /**
+     *  Create an instance of GrGpu that matches the specified Engine backend.
+     *  If the requested engine is not supported (at compile-time or run-time)
+     *  this returns NULL.
+     */
+    static GrGpu* Create(Engine, Platform3DContext context3D);
+
+    /**
+     * Describes levels of support for non-power-of-two textures.
+     */
+    enum NPOTTextureTypes {
+        /**
+         *  no support for NPOT textures
+         */
+        kNone_NPOTTextureType,
+        /**
+         *  only clamp is supported for textures
+         */
+        kNoRepeat_NPOTTextureType,
+        /**
+         *  no texture restrictions at all, but rendertargets must be POW2
+         */
+        kNonRendertarget_NPOTTextureType,
+        /**
+         * no POW2 restrictions at all
+         */
+        kFull_NPOTTextureType
+    };
+
+    /**
+     * Used to control the level of antialiasing available for a rendertarget.
+     * Anti-alias quality levels depend on the underlying API/GPU capabilities.
+     */
+    enum AALevels {
+        kNone_AALevel, //<! No antialiasing available.
+        kLow_AALevel,  //<! Low quality antialiased rendering. Actual
+                       //   interpretation is platform-dependent.
+        kMed_AALevel,  //<! Medium quality antialiased rendering. Actual
+                       //   interpretation is platform-dependent.
+        kHigh_AALevel, //<! High quality antialiased rendering. Actual
+                       //   interpretation is platform-dependent.
+    };
+
+
+    /**
+     * Optional bitfield flags that can be passed to createTexture.
+     */
+    enum TextureFlags {
+        kRenderTarget_TextureFlag  = 0x1,   //<! Creates a texture that can be
+                                            //   rendered to by calling
+                                            //   GrGpu::setRenderTarget() with
+                                            //   GrTexture::asRenderTarget().
+        kNoPathRendering_TextureFlag = 0x2, //<! If the texture is used as a
+                                            //   rendertarget but paths will not
+                                            //   be rendered to it.
+        kDynamicUpdate_TextureFlag = 0x4    //!< Hint that the CPU may modify
+                                            // this texture after creation
+    };
+
+    enum {
+        /**
+         *  For Index8 pixel config, the colortable must be 256 entries
+         */
+        kColorTableSize = 256 * sizeof(GrColor)
+    };
+    /**
+     * Describes a texture to be created.
+     */
+    struct TextureDesc {
+        uint32_t               fFlags;  //!< bitfield of TextureFlags
+        GrGpu::AALevels        fAALevel;//!< The level of antialiasing available
+                                        //   for a rendertarget texture. Only
+                                        //   flags contains
+                                        //   kRenderTarget_TextureFlag.
+        uint32_t               fWidth;  //!< Width of the texture
+        uint32_t               fHeight; //!< Height of the texture
+        GrTexture::PixelConfig fFormat; //!< Format of source data of the
+                                        //   texture. Not guaraunteed to be the
+                                        //   same as internal format used by
+                                        //   3D API.
+    };
+
+    /**
+     * Gpu usage statistics.
+     */
+    struct Stats {
+        uint32_t fVertexCnt;  //<! Number of vertices drawn
+        uint32_t fIndexCnt;   //<! Number of indices drawn
+        uint32_t fDrawCnt;    //<! Number of draws
+
+        uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
+
+        /*
+         *  Number of times the texture is set in 3D API
+         */
+        uint32_t fTextureChngCnt;
+        /*
+         *  Number of times the render target is set in 3D API
+         */
+        uint32_t fRenderTargetChngCnt;
+        /*
+         *  Number of textures created (includes textures that are rendertargets).
+         */
+        uint32_t fTextureCreateCnt;
+        /*
+         *  Number of rendertargets created.
+         */
+        uint32_t fRenderTargetCreateCnt;
+    };
+
+    ////////////////////////////////////////////////////////////////////////////
+
+    GrGpu();
+    virtual ~GrGpu();
+
+    /**
+     * The GrGpu object normally assumes that no outsider is setting state
+     * within the underlying 3D API's context/device/whatever. This call informs
+     * the GrGpu that the state was modified and it should resend. Shouldn't
+     * be called frequently for good performance.
+     */
+    virtual void resetContext();
+
+    void unimpl(const char[]);
+
+    /**
+     * Creates a texture object
+     *
+     * @param desc        describes the texture to be created.
+     * @param srcData     texel data to load texture. Begins with full-size
+     *                    palette data for paletted textures. Contains width*
+     *                    height texels. If NULL texture data is uninitialized.
+     *
+     * @return    The texture object if successful, otherwise NULL.
+     */
+    virtual GrTexture* createTexture(const TextureDesc& desc,
+                                     const void* srcData, size_t rowBytes) = 0;
+    /**
+     * Wraps an externally-created rendertarget in a GrRenderTarget.
+     * @param platformRenderTarget  handle to the the render target in the
+     *                              underlying 3D API. Interpretation depends on
+     *                              GrGpu subclass in use.
+     * @param width                 width of the render target
+     * @param height                height of the render target
+     */
+    virtual GrRenderTarget* createPlatformRenderTarget(
+                                                intptr_t platformRenderTarget,
+                                                int width, int height) = 0;
+
+    /**
+     * Creates a vertex buffer.
+     *
+     * @param size    size in bytes of the vertex buffer
+     * @param dynamic hints whether the data will be frequently changed
+     *                by either GrVertexBuffer::lock or
+     *                GrVertexBuffer::updateData.
+     *
+     * @return    The vertex buffer if successful, otherwise NULL.
+     */
+    virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic) = 0;
+
+    /**
+     * Creates an index buffer.
+     *
+     * @param size    size in bytes of the index buffer
+     * @param dynamic hints whether the data will be frequently changed
+     *                by either GrIndexBuffer::lock or
+     *                GrIndexBuffer::updateData.
+     *
+     * @return The index buffer if successful, otherwise NULL.
+     */
+    virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic) = 0;
+
+    /**
+     * Gets the default render target. This is the render target set in the
+     * 3D API at the time the GrGpu was created.
+     */
+    virtual GrRenderTarget* defaultRenderTarget() = 0;
+
+    /**
+     * At construction time the GrGpu infers the render target and viewport from
+     * the state of the underlying 3D API. However, a platform-specific resize
+     * event may occur.
+     * @param width     new width of the default rendertarget
+     * @param height    new height of the default rendertarget
+     */
+    virtual void setDefaultRenderTargetSize(uint32_t width, uint32_t height) = 0;
+
+    /**
+     * Erase the entire render target, ignoring any clips/scissors.
+     *
+     * This is issued to the GPU driver immediately.
+     */
+    virtual void eraseColor(GrColor color) = 0;
+
+    /**
+     * Are 8 bit paletted textures supported.
+     *
+     * @return    true if 8bit palette textures are supported, false otherwise
+     */
+    bool supports8BitPalette() const { return f8bitPaletteSupport; }
+
+    /**
+     * If single stencil pass winding is supported then one stencil pass
+     * (kWindingStencil1_PathPass) is required to do winding rule path filling
+     * (or inverse winding rule). Otherwise, two passes are required
+     * (kWindingStencil1_PathPass followed by kWindingStencil2_PathPass).
+     *
+     * @return    true if only a single stencil pass is needed.
+     */
+    bool supportsSingleStencilPassWinding() const
+                                        { return fSingleStencilPassForWinding; }
+
+    /**
+     * Checks whether locking vertex and index buffers is supported.
+     *
+     * @return true if locking is supported.
+     */
+    bool supportsBufferLocking() const { return fBufferLockSupport; }
+
+    /**
+     * Gets the minimum width of a render target. If a texture/rt is created
+     * with a width less than this size the GrGpu object will clamp it to this
+     * value.
+     */
+    int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
+
+    /**
+     * Gets the minimum width of a render target. If a texture/rt is created
+     * with a height less than this size the GrGpu object will clamp it to this
+     * value.
+     */
+    int minRenderTargetHeight() const  { return fMinRenderTargetHeight; }
+
+    /**
+     * Retrieves the level of NPOT texture support. Regardless of support level
+     * NPOT textures can always be created, but internally they may be imbedded
+     * in a POT texture. An exception is paletted textures which must be
+     * specified as a POT when npotTextureSupport() is not Full.
+     *
+     * @return    the level of NPOT texture support.
+     */
+    NPOTTextureTypes npotTextureSupport() const { return fNPOTTextureSupport; }
+
+    // GrDrawTarget overrides
+    virtual void drawIndexed(PrimitiveType type,
+                             uint32_t startVertex,
+                             uint32_t startIndex,
+                             uint32_t vertexCount,
+                             uint32_t indexCount);
+
+    virtual void drawNonIndexed(PrimitiveType type,
+                                uint32_t startVertex,
+                                uint32_t vertexCount);
+
+    /**
+     * Determines if blend is effectively disabled.
+     *
+     * @return true if blend can be disabled without changing the rendering
+     *  result given the current state including the vertex layout specified
+     *  with the vertex source.
+     */
+    bool canDisableBlend() const;
+
+    /**
+     * Returns an index buffer that can be used to render quads.
+     * Indices are 0, 1, 2, 0, 2, 3, etc.
+     * Draw with kTriangles_PrimitiveType
+     */
+    const GrIndexBuffer* quadIndexBuffer() const;
+    /**
+     * Gets the number of quads that can be rendered using quadIndexBuffer.
+     */
+    int maxQuadsInIndexBuffer() const;
+
+    /**
+     * Ensures that the current render target is actually set in the
+     * underlying 3D API. Used when client wants to use 3D API to directly
+     * render to the RT.
+     */
+    virtual void forceRenderTargetFlush() = 0;
+
+    virtual bool readPixels(int left, int top, int width, int height,
+                            GrTexture::PixelConfig, void* buffer) = 0;
+
+
+    const Stats& getStats() const;
+    void resetStats();
+    void printStats() const;
+
+protected:
+    /**
+     * Extensions to GrDrawTarget::StencilPass to implement stencil clipping
+     */
+    enum GpuStencilPass {
+        kSetClip_StencilPass = kDrawTargetCount_StencilPass,
+                                        /* rendering a hard clip to the stencil
+                                           buffer. Subsequent draws with other
+                                           StencilPass values will be clipped
+                                           if kStencilClip_StateBit is set. */
+        kGpuCount_StencilPass
+    };
+
+    /**
+     * Extensions to GrDrawTarget::StateBits to implement stencil clipping
+     */
+    struct ClipState {
+        bool            fClipInStencil;
+        bool            fClipIsDirty;
+        GrRenderTarget* fStencilClipTarget;
+    } fClipState;
+
+    virtual void clipWillChange(const GrClip& clip);
+    bool setupClipAndFlushState(PrimitiveType type);
+
+    struct BoundsState {
+        bool    fScissorEnabled;
+        GrIRect fScissorRect;
+        GrIRect fViewportRect;
+    };
+
+    // defaults to false, subclass can set true to support palleted textures
+    bool f8bitPaletteSupport;
+
+    // defaults to false, subclass can set higher support level
+    NPOTTextureTypes fNPOTTextureSupport;
+
+    // True if only one stencil pass is required to implement the winding path
+    // fill rule. Subclass responsible for setting this value.
+    bool fSingleStencilPassForWinding;
+
+    // set by subclass to true if index and vertex buffers can be locked, false
+    // otherwise.
+    bool fBufferLockSupport;
+
+    // set by subclass
+    int fMinRenderTargetWidth;
+    int fMinRenderTargetHeight;
+
+    // overridden by API specific GrGpu-derived class to perform the draw call.
+    virtual void drawIndexedHelper(PrimitiveType type,
+                                   uint32_t startVertex,
+                                   uint32_t startIndex,
+                                   uint32_t vertexCount,
+                                   uint32_t indexCount) = 0;
+
+    virtual void drawNonIndexedHelper(PrimitiveType type,
+                                      uint32_t vertexCount,
+                                      uint32_t numVertices) = 0;
+
+    // called to program the vertex data, indexCount will be 0 if drawing non-
+    // indexed geometry.
+    virtual void setupGeometry(uint32_t startVertex,
+                               uint32_t startIndex,
+                               uint32_t vertexCount,
+                               uint32_t indexCount) = 0;
+
+
+    // The GrGpu typically records the clients requested state and then flushes
+    // deltas from previous state at draw time. This function does the
+    // API-specific flush of the state
+    // returns false if current state is unsupported.
+    virtual bool flushGraphicsState(PrimitiveType type) = 0;
+
+    // Sets the scissor rect, or disables if rect is NULL.
+    virtual void flushScissor(const GrIRect* rect) = 0;
+
+    // GrGpu subclass removes the clip from the stencil buffer
+    virtual void eraseStencilClip() = 0;
+
+    // GrDrawTarget overrides
+    virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                       void**         vertices,
+                                       void**         indices);
+    virtual void releaseGeometryHelper();
+
+private:
+    mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
+                                             // created on-demand
+
+    static const int MAX_VERTEX_SIZE = GR_CT_MAX(2*sizeof(GrPoint) + sizeof(GrColor),
+                                                 2*sizeof(GrGpuTextVertex));
+    static const int VERTEX_STORAGE = 16 * MAX_VERTEX_SIZE;
+    static const int INDEX_STORAGE = 32 * sizeof(uint16_t);
+
+protected:
+    GrAutoSMalloc<VERTEX_STORAGE> fVertices;
+    GrAutoSMalloc<INDEX_STORAGE>  fIndices;
+
+    Stats           fStats;
+
+private:
+    typedef GrRefCnt INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrGpuD3D9.h b/gpu/include/GrGpuD3D9.h
new file mode 100644
index 0000000..c3d3e1a
--- /dev/null
+++ b/gpu/include/GrGpuD3D9.h
@@ -0,0 +1,259 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuD3D9_DEFINED
+#define GrGpuD3D9_DEFINED
+
+#include <Windows.h>
+#include <d3d9.h>
+
+#include "GrGpu.h"
+
+class GrD3D9VertexBuffer;
+class GrD3D9IndexBuffer;
+class GrD3D9Texture;
+
+// For D3D9 GrRenderTarget casts to a (GrD3D9RenderTarget*)
+struct GrD3D9RenderTarget {
+    IDirect3DSurface9* fColor;
+    IDirect3DSurface9* fStencil;
+    bool fClearStencil;
+};
+
+// GrGpu implementation for D3D9 fixed pipeline. 
+// Known needed improvements:
+//      vertex/index buffers need to be better managed:
+//          use no_overwrite and walk down VB/IB until reach end and wrap
+//      take advantage of the redrawHint and don't recopy vertex/idx data
+//      User created vertex buffers must have position Z values 
+//          (required for fixed pipeline) but there is no way to communicate 
+//          this now
+//      We create a temporary sysmem surface for each texture update.
+//      split this out into fixed/shader subclasses (use vdecls for shaders)
+class GrGpuD3D9 : public GrGpu {
+public:
+            GrGpuD3D9(IDirect3DDevice9* device);
+    virtual ~GrGpuD3D9();
+
+    // overrides from GrGpu
+    virtual GrTexture* createTexture(const TextureDesc& desc,
+                                     const void* srcData);
+    virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
+    virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
+
+    virtual void eraseColor(GrColor color);
+    virtual void eraseStencil();
+
+protected:
+    // overrides from GrGpu
+    virtual bool flushGraphicsState(PrimitiveTypes type);
+    virtual void drawIndexArrayApi(PrimitiveTypes type,
+                                   int baseVertex,
+                                   int vertexCount,
+                                   int indexCount,
+                                   const uint16_t* indexArray,
+                                   bool redrawHint);
+    virtual void drawIndexBufferApi(PrimitiveTypes type,
+                                    int baseVertex,
+                                    int startIndex,
+                                    int vertexCount,
+                                    int indexCount,
+                                    GrIndexBuffer* indexBuffer,
+                                    bool redrawHint);
+    virtual void drawNonIndexedApi(PrimitiveTypes type,
+                                   int baseVertex,
+                                   int indexCount,
+                                   bool redrawHint);
+    virtual void flushScissor();
+
+private:
+
+    // baseVertex may be modified while setting up the stage
+    GrD3D9VertexBuffer* setupVBufferStage(int vsize, int* baseVertex, 
+                                          int vertexCount, DrawModes mode);
+    GrD3D9IndexBuffer* setupIBufferStage(int* startIndex, int indexCount, 
+                                         const uint16_t* indices);
+    static int vertexSize(int vertFlagBits, GrGpu::DrawModes mode);
+    static bool positionsOnly(int vertFlagBits);
+
+    // notify callbacks to update state tracking when related
+    // objects are bound to the device or deleted outside of the class
+    void notifyVertexBufferBind(GrD3D9VertexBuffer* buffer);
+    void notifyVertexBufferDelete(GrD3D9VertexBuffer* buffer);
+    void notifyIndexBufferBind(GrD3D9IndexBuffer* buffer);
+    void notifyIndexBufferDelete(GrD3D9IndexBuffer* buffer);
+    void notifyTextureDelete(GrD3D9Texture* texture);
+    void notifyTextureRemoveRenderTarget(GrD3D9Texture* texture);
+
+    IDirect3DSurface9* createStencil(uint32_t width, 
+                                     uint32_t height,
+                                     D3DMULTISAMPLE_TYPE msType,
+                                     DWORD msQual);
+
+    void setRenderTargetImm();
+
+    friend class GrD3D9VertexBuffer;
+    friend class GrD3D9IndexBuffer;
+    friend class GrD3D9Texture;
+
+    GrIndexBuffer*                  fLastIndexBuffer;
+    
+    // used to track the COLORARG1 value for tex stage 0
+    // needs to use ALPHAREPLICATE when using alpha-only textures
+    DWORD                           fLastColorArg1;
+
+    IDirect3DDevice9*               fDevice;
+    // We may use Ex functionality if this is a Ex device
+    IDirect3DDevice9Ex*             fDeviceEx;
+
+    enum VertDecls {
+        kInvalid_VertDecl = -1,
+        kPosOnly_VertDecl = 0,
+        kTex_VertDecl,
+        kColors_VertDecl,
+        kTexAndColors_VertDecl,
+        kPosAsTex_VertDecl,
+        kPosAsTexAndColors_VertDecl,
+        kVertDeclCount
+    };
+
+    static const VertDecls gVertFlags2VertDeclIdx[];
+    static const DWORD gDeclToFVFs[];
+    static const DWORD gTextFVF;
+    
+    DWORD fLastVertFVF;
+
+    bool fLastBlendOff;
+
+    // D3D allows user pointers in place of buffers for vertex/index data
+    // but it doesn't allow:
+    //  -multiple streams (non-interleaved) ~ this will be resolved when we 
+    //                                        go AoS with our verts
+    //  -mixing user pointer verts with index buffer (or vice versa)
+    // So we use these staging buffers
+    GrD3D9VertexBuffer* fStageVBuffer;
+    GrD3D9IndexBuffer*  fStageIBuffer;
+
+    // did we use texture coordinate generation at the last flush
+    bool fLastTexGen;
+
+    GrD3D9RenderTarget fDefaultRenderTarget;
+
+    // We use texture stage 0 to set a constant color
+    // D3D disables the stage if NULL is bound (even when the ops don't
+    // reference the texture). So we have a 1x1 dummy texture that
+    // gets set when drawing constant color with no texture
+    GrD3D9Texture* fDummyTexture;
+};
+
+class GrD3D9Texture : public GrTexture {
+protected:
+    GrD3D9Texture(uint32_t width, 
+                  uint32_t height, 
+                  PixelConfig config,
+                  IDirect3DTexture9* texture,
+                  IDirect3DSurface9* stencil,
+                  bool clearStencil,
+                  GrGpuD3D9* gpuD3D9);
+public:
+    virtual ~GrD3D9Texture();
+    
+    // overloads of GrTexture
+    virtual void abandon();
+    virtual bool isRenderTarget();
+    virtual GrRenderTarget* asRenderTarget() 
+                                    { return (GrRenderTarget*) &fRenderTarget; }
+    virtual void removeRenderTarget();
+    virtual void uploadTextureData(uint32_t x,
+                                   uint32_t y,
+                                   uint32_t width,
+                                   uint32_t height,
+                                   const void* srcData);
+    IDirect3DTexture9* texture() const { return fTexture; }
+    IDirect3DSurface9* stencil() const { return fStencil; }
+    D3DFORMAT format() const { return fDesc.Format; }
+private:
+    IDirect3DTexture9*      fTexture;
+    GrD3D9RenderTarget      fRenderTarget;
+    IDirect3DSurface9*      fStencil;
+    D3DSURFACE_DESC         fDesc;
+    GrGpuD3D9*              fGpuD3D9;
+
+    friend class GrGpuD3D9;
+
+    typedef GrTexture INHERITED;
+};
+
+class GrD3D9VertexBuffer : public GrVertexBuffer {
+protected:
+    GrD3D9VertexBuffer(uint32_t size, 
+                       bool dynamic,
+                       IDirect3DVertexBuffer9* vbuffer,
+                       GrGpuD3D9* gpuD3D9);
+public:
+    virtual ~GrD3D9VertexBuffer();
+    
+    IDirect3DVertexBuffer9* buffer() const { return fBuffer; }
+
+    // overrides of GrVertexBuffer
+    virtual void abandon();
+    virtual void* lock();
+    virtual void unlock();
+    virtual bool isLocked();
+    virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+
+private:
+    IDirect3DVertexBuffer9* fBuffer;
+    D3DVERTEXBUFFER_DESC    fDesc;
+    bool                    fLocked;
+    GrGpuD3D9*              fGpuD3D9;
+
+    friend class GrGpuD3D9;
+
+    typedef GrVertexBuffer INHERITED;
+};
+
+class GrD3D9IndexBuffer : public GrIndexBuffer {
+protected:
+    GrD3D9IndexBuffer(uint32_t size, 
+                      bool dynamic,
+                      IDirect3DIndexBuffer9* vbuffer,
+                      GrGpuD3D9* gpuD3D9);
+public:
+    virtual ~GrD3D9IndexBuffer();
+
+    IDirect3DIndexBuffer9* buffer() const { return fBuffer; }
+
+    // overrides of GrIndexBuffer
+    virtual void abandon();
+    virtual void* lock();
+    virtual void unlock();
+    virtual bool isLocked();
+    virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+private:
+    IDirect3DIndexBuffer9*  fBuffer;
+    D3DINDEXBUFFER_DESC     fDesc;
+    bool                    fLocked;
+    GrGpuD3D9*              fGpuD3D9;
+
+    friend class GrGpuD3D9;
+
+    typedef GrIndexBuffer INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrGpuVertex.h b/gpu/include/GrGpuVertex.h
new file mode 100644
index 0000000..1e3293a
--- /dev/null
+++ b/gpu/include/GrGpuVertex.h
@@ -0,0 +1,104 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuVertex_DEFINED
+#define GrGpuVertex_DEFINED
+
+#include "GrGLConfig.h"
+#include "GrPoint.h"
+
+#if GR_TEXT_SCALAR_IS_USHORT
+    typedef uint16_t                GrTextScalar;  
+    #define GrIntToTextScalar(x)    ((uint16_t)x)
+    #define GrFixedToTextScalar(x)  (x)
+#elif GR_TEXT_SCALAR_IS_FIXED
+    typedef GrFixed                 GrTextScalar;
+    #define GrIntToTextScalar(x)    GrIntToFixed(x)
+    #define GrFixedToTextScalar(x)  (x)
+#elif GR_TEXT_SCALAR_IS_FLOAT
+    typedef float                   GrTextScalar;    
+    #define GrIntToTextScalar(x)    ((GrTextScalar)x)
+    #define GrFixedToTextScalar(x)  GrFixedToFloat(x)
+#else
+    #error "Text scalar type not defined"
+#endif
+
+// text has its own vertex class, since it may want to be in fixed point (given)
+// that it starts with all integers) even when the default vertices are floats
+struct GrGpuTextVertex {
+    GrTextScalar fX;
+    GrTextScalar fY;
+
+    void set(GrTextScalar x, GrTextScalar y) {
+        fX = x;
+        fY = y;
+    }
+
+    void setI(int x, int y) {
+        fX = GrIntToTextScalar(x);
+        fY = GrIntToTextScalar(y);
+    }
+    
+    void setX(GrFixed x, GrFixed y) {
+        fX = GrFixedToTextScalar(x);
+        fY = GrFixedToTextScalar(y);
+    }
+    
+    // rect fan is counter-clockwise
+
+    void setRectFan(GrTextScalar l, GrTextScalar t, GrTextScalar r,
+                    GrTextScalar b) {
+        GrGpuTextVertex* v = this;
+        v[0].set(l, t);
+        v[1].set(l, b);
+        v[2].set(r, b);
+        v[3].set(r, t);
+    }
+
+    void setIRectFan(int l, int t, int r, int b) {
+        this->setRectFan(GrIntToTextScalar(l), GrIntToTextScalar(t),
+                         GrIntToTextScalar(r), GrIntToTextScalar(b));
+    }
+
+    void setIRectFan(int l, int t, int r, int b, size_t stride) {
+        GrAssert(stride > sizeof(GrGpuTextVertex));
+        char* v = (char*)this;
+        ((GrGpuTextVertex*)(v + 0*stride))->setI(l, t);
+        ((GrGpuTextVertex*)(v + 1*stride))->setI(l, b);
+        ((GrGpuTextVertex*)(v + 2*stride))->setI(r, b);
+        ((GrGpuTextVertex*)(v + 3*stride))->setI(r, t);
+    }
+
+    // counter-clockwise fan
+    void setXRectFan(GrFixed l, GrFixed t, GrFixed r, GrFixed b) {
+        this->setRectFan(GrFixedToTextScalar(l), GrFixedToTextScalar(t),
+                         GrFixedToTextScalar(r), GrFixedToTextScalar(b));
+    }
+
+    void setXRectFan(GrFixed l, GrFixed t, GrFixed r, GrFixed b, size_t stride) {
+        GrAssert(stride > sizeof(GrGpuTextVertex));
+        char* v = (char*)this;
+        ((GrGpuTextVertex*)(v + 0*stride))->setX(l, t);
+        ((GrGpuTextVertex*)(v + 1*stride))->setX(l, b);
+        ((GrGpuTextVertex*)(v + 2*stride))->setX(r, b);
+        ((GrGpuTextVertex*)(v + 3*stride))->setX(r, t);
+    }
+
+};
+
+#endif
+
diff --git a/gpu/include/GrIPoint.h b/gpu/include/GrIPoint.h
new file mode 100644
index 0000000..b979a09
--- /dev/null
+++ b/gpu/include/GrIPoint.h
@@ -0,0 +1,35 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrIPoint_DEFINED
+#define GrIPoint_DEFINED
+
+#include "GrTypes.h"
+
+struct GrIPoint {
+public:
+    int32_t fX, fY;
+    
+    GrIPoint(int32_t x, int32_t y) : fX(x), fY(y) {}
+   
+    void set(int32_t x, int32_t y) {
+        fX = x;
+        fY = y;
+    }
+};
+
+#endif
diff --git a/gpu/include/GrInOrderDrawBuffer.h b/gpu/include/GrInOrderDrawBuffer.h
new file mode 100644
index 0000000..805861a
--- /dev/null
+++ b/gpu/include/GrInOrderDrawBuffer.h
@@ -0,0 +1,131 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrInOrderDrawBuffer_DEFINED
+#define GrInOrderDrawBuffer_DEFINED
+
+#include "GrDrawTarget.h"
+#include "GrAllocPool.h"
+#include "GrAllocator.h"
+#include "GrClip.h"
+
+class GrVertexBufferAllocPool;
+
+// TODO: don't save clip per draw
+class GrInOrderDrawBuffer : public GrDrawTarget {
+public:
+
+    GrInOrderDrawBuffer(GrVertexBufferAllocPool* pool = NULL);
+
+    virtual ~GrInOrderDrawBuffer();
+
+    void initializeDrawStateAndClip(const GrDrawTarget& target);
+
+    virtual void drawIndexed(PrimitiveType type,
+                             uint32_t startVertex,
+                             uint32_t startIndex,
+                             uint32_t vertexCount,
+                             uint32_t indexCount);
+
+    virtual void drawNonIndexed(PrimitiveType type,
+                                uint32_t startVertex,
+                                uint32_t vertexCount);
+
+    virtual bool geometryHints(GrVertexLayout vertexLayout,
+                               int32_t*       vertexCount,
+                               int32_t*       indexCount) const;
+
+    void reset();
+
+    void playback(GrDrawTarget* target);
+
+private:
+
+    struct Draw {
+        PrimitiveType   fType;
+        uint32_t        fStartVertex;
+        uint32_t        fStartIndex;
+        uint32_t        fVertexCount;
+        uint32_t        fIndexCount;
+        bool            fStateChange;
+        GrVertexLayout  fVertexLayout;
+        bool            fUseVertexBuffer;
+        bool            fClipChanged;
+        union {
+            const GrVertexBuffer*   fVertexBuffer;
+            const void*             fVertexArray;
+        };
+        bool            fUseIndexBuffer;
+        union {
+            const GrIndexBuffer*    fIndexBuffer;
+            const void*             fIndexArray;
+        };
+    };
+
+    virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                       void**         vertices,
+                                       void**         indices);
+    virtual void releaseGeometryHelper();
+    virtual void clipWillChange(const GrClip& clip);
+
+
+    bool grabState();
+    bool grabClip();
+
+    GrTAllocator<Draw>              fDraws;
+    // HACK: We hold refs on textures in saved state but not RTs, VBs, and IBs.
+    // a) RTs aren't ref counted (yet)
+    // b) we are only using this class for text which doesn't use VBs or IBs
+    // This should be fixed by either refcounting them all or having some
+    // notification occur if a cache is purging an object we have a ptr to.
+    GrTAllocator<SavedDrawState>    fStates;
+
+    GrTAllocator<GrClip>            fClips;
+    bool                            fClipChanged;
+
+    // vertices are either queued in cpu arrays or some vertex buffer pool
+    // that knows about a specific GrGpu object.
+    GrAllocPool                     fCPUVertices;
+    GrVertexBufferAllocPool*        fBufferVertices;
+    GrAllocPool                     fIndices;
+    void*                           fCurrReservedVertices;
+    void*                       	fCurrReservedIndices;
+    // valid if we're queueing vertices in fBufferVertices
+    GrVertexBuffer*                 fCurrVertexBuffer;
+    uint32_t                        fCurrStartVertex;
+
+    // caller may conservatively over allocate vertices / indices.
+    // we release unused space back to allocator if possible
+    size_t                          fReservedVertexBytes;
+    size_t                          fReservedIndexBytes;
+    size_t                          fUsedReservedVertexBytes;
+    size_t                          fUsedReservedIndexBytes;
+
+    static const uint32_t           STATES_BLOCK_SIZE = 8;
+    static const uint32_t           DRAWS_BLOCK_SIZE  = 8;
+    static const uint32_t           CLIPS_BLOCK_SIZE  = 8;
+    static const uint32_t           VERTEX_BLOCK_SIZE = 1 << 12;
+    static const uint32_t           INDEX_BLOCK_SIZE  = 1 << 10;
+    int8_t                          fDrawsStorage[sizeof(Draw) *
+                                                  DRAWS_BLOCK_SIZE];
+    int8_t                          fStatesStorage[sizeof(SavedDrawState) *
+                                                   STATES_BLOCK_SIZE];
+    int8_t                          fClipsStorage[sizeof(GrClip) *
+                                                  CLIPS_BLOCK_SIZE];
+};
+
+#endif
diff --git a/gpu/include/GrIndexBuffer.h b/gpu/include/GrIndexBuffer.h
new file mode 100644
index 0000000..0f4c4d6
--- /dev/null
+++ b/gpu/include/GrIndexBuffer.h
@@ -0,0 +1,92 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrIndexBuffer_DEFINED
+#define GrIndexBuffer_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrIndexBuffer : public GrRefCnt {
+protected:
+    GrIndexBuffer(uint32_t sizeInBytes, bool dynamic) : 
+                  fSizeInBytes(sizeInBytes),
+                  fDynamic(dynamic) {}
+public:
+    virtual ~GrIndexBuffer() {}
+    
+    /**
+     Retrieves the size of the index buffer
+
+     @return the size of the index buffer in bytes
+     */
+    uint32_t size() const { return fSizeInBytes; }
+   
+    /**
+     Retrieves whether the index buffer was created with the dynamic flag
+
+     @return true if the index buffer was created with the dynamic flag
+     */
+    bool dynamic() const { return fDynamic; }
+
+    /**
+     Indicates that GPU context in which this veretx buffer was created is 
+     destroyed and that Ganesh should not attempt to free the texture with the
+     underlying API.
+     */
+    virtual void abandon() = 0;
+
+    /**
+     Locks the index buffer to be written by the CPU.
+     
+     The previous content of the index buffer is invalidated. It is an error to
+     draw whil the buffer is locked.  It is an error to call lock on an already
+     locked index buffer.
+     
+     @return a pointer to the index data or NULL if the lock fails.
+     */
+    virtual void* lock() = 0;
+
+    /** 
+     Unlocks the index buffer. 
+     
+     The pointer returned by the previous lock call will no longer be valid.
+     */
+    virtual void unlock() = 0;
+
+    /** 
+     Queries whether the index buffer has been locked.
+     
+     @return true if the index buffer is locked, false otherwise.
+     */
+    virtual bool isLocked() const = 0;
+
+    /**
+     Updates the index buffer data. 
+     
+     The size of the index buffer will be preserved. However, only the updated 
+     region will have defined contents.
+
+     @return returns true if the update succeeds, false otherwise.
+     */
+    virtual bool updateData(const void* src, uint32_t srcSizeInBytes) = 0;
+
+private:
+    uint32_t fSizeInBytes;
+    bool     fDynamic;
+};
+
+#endif
diff --git a/gpu/include/GrInstanceCounter.h b/gpu/include/GrInstanceCounter.h
new file mode 100644
index 0000000..11cec2b
--- /dev/null
+++ b/gpu/include/GrInstanceCounter.h
@@ -0,0 +1,47 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrInstanceCounter_DEFINED
+#define GrInstanceCounter_DEFINED
+
+#include "GrTypes.h"
+
+template <typename T> class GrInstanceCounter {
+public:
+    GrInstanceCounter() {
+        ++gCounter;
+        GrPrintf("+ %s %d\n", T::InstanceCounterClassName(), gCounter);
+    }
+
+    ~GrInstanceCounter() {
+        --gCounter;
+        GrPrintf("- %s %d\n", T::InstanceCounterClassName(), gCounter);
+    }
+
+private:
+    static int gCounter;
+};
+
+template <typename T> int GrInstanceCounter<T>::gCounter;
+
+#define DECLARE_INSTANCE_COUNTER(T)                                 \
+    static const char* InstanceCounterClassName() { return #T; }    \
+    friend class GrInstanceCounter<T>;                              \
+    GrInstanceCounter<T> fInstanceCounter
+
+#endif
+
diff --git a/gpu/include/GrKey.h b/gpu/include/GrKey.h
new file mode 100644
index 0000000..19133ae
--- /dev/null
+++ b/gpu/include/GrKey.h
@@ -0,0 +1,47 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrKey_DEFINED
+#define GrKey_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrKey : public GrRefCnt {
+public:
+    typedef intptr_t Hash;
+
+    explicit GrKey(Hash hash) : fHash(hash) {}
+
+    intptr_t getHash() const { return fHash; }
+
+    bool operator<(const GrKey& rh) const {
+        return fHash < rh.fHash || (fHash == rh.fHash && this->lt(rh));
+    }
+    bool operator==(const GrKey& rh) const {
+        return fHash == rh.fHash && this->eq(rh);
+    }
+
+protected:
+    virtual bool lt(const GrKey& rh) const = 0;
+    virtual bool eq(const GrKey& rh) const = 0;
+
+private:
+    const Hash fHash;
+};
+
+#endif
+
diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h
new file mode 100644
index 0000000..43fd4a5
--- /dev/null
+++ b/gpu/include/GrMatrix.h
@@ -0,0 +1,370 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+

+#ifndef GrMatrix_DEFINED

+#define GrMatrix_DEFINED

+

+#include "GrPoint.h"

+

+struct GrRect;

+

+/*

+ * 3x3 matrix

+ */

+class GrMatrix {

+public:

+    static const GrMatrix& I();

+    static const GrScalar gRESCALE;

+    /** 

+     * Handy index constants

+     */

+    enum {

+        kScaleX,

+        kSkewX,

+        kTransX,

+        kSkewY,

+        kScaleY,

+        kTransY,

+        kPersp0,

+        kPersp1,

+        kPersp2

+    };

+    

+    /**

+     * Create an uninitialized matrix

+     */

+    GrMatrix() {

+        fTypeMask = 0;

+    }

+    

+    /**

+     * Create a matrix from an array of values

+     * @param values    row-major array of matrix components

+     */

+    explicit GrMatrix(GrScalar* values) {

+        setToArray(values);

+    }

+    

+    /**

+     * Create a matrix from values

+     * @param scaleX    (0,0) matrix element

+     * @param skewX     (0,1) matrix element

+     * @param transX    (0,2) matrix element

+     * @param skewY     (1,0) matrix element

+     * @param scaleY    (1,1) matrix element

+     * @param transY    (1,2) matrix element

+     * @param persp0    (2,0) matrix element

+     * @param persp1    (2,1) matrix element

+     * @param persp2    (2,2) matrix element

+     */

+    GrMatrix(GrScalar scaleX,

+             GrScalar skewX,

+             GrScalar transX,

+             GrScalar skewY,

+             GrScalar scaleY,

+             GrScalar transY,

+             GrScalar persp0,

+             GrScalar persp1,

+             GrScalar persp2) {

+        setAll(scaleX, skewX,  transX,

+               skewY,  scaleY, transY,

+               persp0, persp1, persp2);

+    }

+

+    /**

+     * access matrix component

+     * @return matrix component value

+     */

+    const GrScalar& operator[] (int idx) const {

+        GrAssert((unsigned)idx < 9);

+        return fM[idx];

+    }

+

+    /**

+     * Set a matrix from an array of values

+     * @param values    row-major array of matrix components

+     */

+    void setToArray(GrScalar* values) {

+        for (int i = 0; i < 9; ++i) {

+            fM[i] = values[i];

+        }

+        setTypeMask();

+    }

+    

+    /**

+     * Create a matrix from values

+     * @param scaleX    (0,0) matrix element

+     * @param skewX     (0,1) matrix element

+     * @param transX    (0,2) matrix element

+     * @param skewY     (1,0) matrix element

+     * @param scaleY    (1,1) matrix element

+     * @param transY    (1,2) matrix element

+     * @param persp0    (2,0) matrix element

+     * @param persp1    (2,1) matrix element

+     * @param persp2    (2,2) matrix element

+     */

+    void setAll(GrScalar scaleX,

+                GrScalar skewX,

+                GrScalar transX,

+                GrScalar skewY,

+                GrScalar scaleY,

+                GrScalar transY,

+                GrScalar persp0,

+                GrScalar persp1,                

+                GrScalar persp2) {

+        fM[kScaleX] = scaleX;

+        fM[kSkewX]  = skewX;

+        fM[kTransX] = transX;

+        fM[kSkewY]  = skewY;

+        fM[kScaleY] = scaleY;

+        fM[kTransY] = transY;

+        fM[kPersp0] = persp0;

+        fM[kPersp1] = persp1;

+        fM[kPersp2] = persp2;

+        

+        setTypeMask();

+    }

+    

+    /**

+     * set matrix component

+     * @param idx    index of component to set

+     * @param value  value to set component to

+     */

+    inline void set(int idx, GrScalar value);

+    

+    /**

+     * make this matrix an identity matrix

+     */

+    void setIdentity();

+

+    /**

+     * overwrite entire matrix to be a translation matrix

+     * @param dx    amount to translate by in x

+     * @param dy    amount to translate by in y

+     */

+    void setTranslate(GrScalar dx, GrScalar dy);

+

+    /**

+     * overwrite entire matrix to be a scaling matrix

+     * @param sx    x scale factor

+     * @param sy    y scale factor

+     */

+    void setScale(GrScalar sx, GrScalar sy);

+

+    /**

+     * overwrite entire matrix to be a skew matrix

+     * @param skx   x skew factor

+     * @param sky   y skew factor

+     */

+    void setSkew(GrScalar skx, GrScalar sky);

+

+    /**

+     * set this matrix to be a concantenation of two

+     * matrices (a*b). Either a, b, or both can be this matrix.

+     * @param a     first matrix to multiply

+     * @param b     second matrix to multiply

+     */

+    void setConcat(const GrMatrix& a, const GrMatrix& b);

+

+    /**

+     * Set this matrix to this*m

+     * @param m     matrix to concatenate

+     */

+    void preConcat(const GrMatrix& m);

+

+    /**

+     * Set this matrix to m*this

+     * @param m     matrix to concatenate

+     */

+    void postConcat(const GrMatrix& m);

+

+    /**

+     *  Compute the inverse of this matrix, and return true if it is invertible,

+     *  or false if not.

+     *

+     *  If inverted is not null, and the matrix is invertible, then the inverse

+     *  is written into it. If the matrix is not invertible (this method returns

+     *  false) then inverted is left unchanged.

+     */

+    bool invert(GrMatrix* inverted) const;

+    

+    /**

+     * Transforms a point by the matrix

+     *

+     * @param src   the point to transform

+     * @return the transformed point

+     */

+    GrPoint mapPoint(const GrPoint& src) const {

+        GrPoint result;

+        (this->*gMapProcs[fTypeMask])(&result, &src, 1);

+        return result;

+    }

+    

+    /**

+     * Transforms an array of points by the matrix.

+     *

+     * @param dstPts the array to write transformed points into

+     * @param srcPts the array of points to transform

+     @ @param count the number of points to transform

+     */

+    void mapPoints(GrPoint dstPts[], 

+                   const GrPoint srcPts[], 

+                   uint32_t count) const {

+        (this->*gMapProcs[fTypeMask])(dstPts, srcPts, count);

+    }

+

+    /**

+     * Transforms pts with arbitrary stride in place.

+     *

+     * @param start  pointer to first point to transform

+     * @param stride distance in bytes between consecutive points

+     @ @param count the number of points to transform

+     */

+    void mapPointsWithStride(GrPoint* start, 

+                             size_t stride, 

+                             uint32_t count) const {

+        for (uint32_t i = 0; i < count; ++i) {            

+            this->mapPoints(start, start, 1);

+            start = (GrPoint*)((intptr_t)start + stride);

+        }

+    }

+    

+    /**

+     *  Transform the 4 corners of the src rect, and return the bounding rect

+     *  in the dst rect. Note: src and dst may point to the same memory.

+     */

+    void mapRect(GrRect* dst, const GrRect& src) const;

+

+    /**

+     *  Transform the 4 corners of the rect, and return their bounds in the rect

+     */

+    void mapRect(GrRect* rect) const {

+        this->mapRect(rect, *rect);

+    }

+

+    /**

+     * Checks if matrix is a perspective matrix.

+     * @return true if third row is not (0, 0, 1)

+     */

+    bool hasPerspective() const;

+    

+    /**

+     * Checks whether matrix is identity

+     * @return true if matrix is idenity

+     */

+    bool isIdentity() const;

+    

+    /**

+     * Calculates the maximum stretching factor of the matrix. Only defined if

+     * the matrix does not have perspective.

+     *

+     * @return maximum strecthing factor or negative if matrix has perspective.

+     */

+    GrScalar getMaxStretch() const;

+

+    /**

+     * Checks for matrix equality. Test is element-by-element equality,

+     * not a homogeneous test.

+     * @return true if matrices are equal, false otherwise

+     */

+    bool operator == (const GrMatrix& m) const;

+

+    /**

+     * Checks for matrix inequality. Test is element-by-element inequality,

+     * not a homogeneous test.

+     * @return true if matrices are not equal, false otherwise

+     */

+    bool operator != (const GrMatrix& m) const;

+    

+    static void UnitTest();

+

+private:

+    

+    void setTypeMask();

+    

+    double determinant() const;

+    

+    enum TypeBits {

+        kScale_TypeBit       = 1 << 0, // set if scales are not both 1

+        kTranslate_TypeBit   = 1 << 1, // set if translates are not both 0

+        kSkew_TypeBit        = 1 << 2, // set if skews are not both 0

+        kPerspective_TypeBit = 1 << 3, // set if perspective

+        kZeroScale_TypeBit   = 1 << 4, // set if scales are both zero

+    };

+

+    void mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    void mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    

+    void mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    

+    typedef void (GrMatrix::*MapProc) (GrPoint* dst, const GrPoint* src, uint32_t count) const;

+    static const MapProc gMapProcs[];

+

+    int      fTypeMask;

+    

+    GrScalar fM[9];

+};

+

+void GrMatrix::set(int idx, GrScalar value) {

+    GrAssert((unsigned)idx < 9);

+    fM[idx] = value;

+    if (idx > 5) {

+        if (0 != fM[kPersp0] || 0 != fM[kPersp1] ||

+            gRESCALE != fM[kPersp2]) {

+            fTypeMask |= kPerspective_TypeBit;

+        } else {

+            fTypeMask &= ~kPerspective_TypeBit;

+        }

+    } else if (!(idx % 4)) {

+        if ((GR_Scalar1 == fM[kScaleX] && GR_Scalar1 == fM[kScaleY])) {

+            fTypeMask &= ~kScale_TypeBit;

+            fTypeMask &= ~kZeroScale_TypeBit;

+        } else {

+            fTypeMask |= kScale_TypeBit;

+            if ((0 == fM[kScaleX] && 0 == fM[kScaleY])) {

+                fTypeMask |= kZeroScale_TypeBit;

+            } else {

+                fTypeMask &= ~kZeroScale_TypeBit;

+            }

+        }

+    } else if (2 == (idx % 3)) {

+        if (0 != fM[kTransX] || 0 != fM[kTransY]) {

+            fTypeMask |= kTranslate_TypeBit;

+        } else {

+            fTypeMask &= ~kTranslate_TypeBit;

+        }

+    } else {

+        if (0 != fM[kSkewX] || 0 != fM[kSkewY]) {

+            fTypeMask |= kSkew_TypeBit;

+        } else {

+            fTypeMask &= ~kSkew_TypeBit;

+        }

+    }

+}

+

+#endif
diff --git a/gpu/include/GrMemory.h b/gpu/include/GrMemory.h
new file mode 100644
index 0000000..673d0ab
--- /dev/null
+++ b/gpu/include/GrMemory.h
@@ -0,0 +1,151 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrMemory_DEFINED
+#define GrMemory_DEFINED
+
+#include "GrNoncopyable.h"
+
+class GrAutoMalloc : GrNoncopyable {
+public:
+    GrAutoMalloc(size_t bytes) : fPtr(GrMalloc(bytes)) {}
+    ~GrAutoMalloc() { GrFree(fPtr); }
+
+    /**
+     *  Return the allocated memory, or NULL if it has already been freed or
+     *  detached.
+     */
+    void* get() const { return fPtr; }
+
+    /**
+     *  transfer ownership of the memory to the caller. It must be freed with
+     *  a call to GrFree()
+     */
+    void* detach() {
+        void* ptr = fPtr;
+        fPtr = NULL;    // we no longer own the block
+        return ptr;
+    }
+    
+    /**
+     *  free the block now. get() will now return NULL
+     */
+    void free() {
+        GrFree(fPtr);
+        fPtr = NULL;
+    }
+
+private:
+    void* fPtr;
+};
+
+/**
+ *  Variant of GrAutoMalloc with a compile-time specified byte size that is
+ *  pre-allocated in the class object, avoiding a call to to GrMalloc if
+ *  possible.
+ */
+template <size_t SIZE> class GrAutoSMalloc : GrNoncopyable {
+public:
+    GrAutoSMalloc() {
+        fPtr = fStorage;
+        fAllocatedBytes = SIZE;
+    }
+
+    explicit GrAutoSMalloc(size_t bytes) {
+        if (bytes > SIZE) {
+            fPtr = GrMalloc(bytes);
+            fAllocatedBytes = bytes;
+        } else {
+            fPtr = fStorage;
+            fAllocatedBytes = SIZE;
+        }
+    }
+
+    ~GrAutoSMalloc() {
+        if (fPtr != (void*)fStorage) {
+            GrFree(fPtr);
+        }
+    }
+
+    /**
+     *  Return the allocated memory, or NULL if it has already been freed or
+     *  detached.
+     */
+    void* get() const { return fPtr; }
+    
+    /**
+     *  Reallocates to a new size. May or may not call malloc. The contents 
+     *  are not preserved. If growOnly is true it will never reduce the 
+     *  allocated size.
+     */
+    void* realloc(size_t newSize, bool growOnly = false) {
+        if (newSize <= SIZE) {
+            if (NULL == fPtr) {
+                fPtr = fStorage;
+                fAllocatedBytes = SIZE;
+            } else if (!growOnly && fPtr != (void*)fStorage) {
+                GrFree(fPtr);
+                fPtr = fStorage;
+                fAllocatedBytes = SIZE;
+            }            
+        } else if ((newSize > fAllocatedBytes) ||
+                   (!growOnly && newSize < (fAllocatedBytes >> 1))) {
+            if (NULL != fPtr && fPtr != (void*)fStorage) {
+                GrFree(fPtr);
+            }
+            fPtr = GrMalloc(newSize);
+            fAllocatedBytes = newSize;
+        }
+        GrAssert(fAllocatedBytes >= newSize);
+        GrAssert((fPtr == fStorage) == (fAllocatedBytes == SIZE));
+        GR_DEBUGCODE(memset(fPtr, 0xEF, fAllocatedBytes));
+        return fPtr;
+    }
+   
+    /**
+     *  free the block now. get() will now return NULL
+     */
+    void free() {
+        if (fPtr != (void*)fStorage) {
+            GrFree(fPtr);
+        }
+        fAllocatedBytes = 0;
+        fPtr = NULL;
+    }
+    
+private:
+    void*    fPtr;
+    uint32_t fAllocatedBytes;
+    uint32_t fStorage[GrALIGN4(SIZE) >> 2];
+};
+
+/**
+ *  Variant of GrAutoMalloc with a compile-time specified byte size that is
+ *  pre-allocated in the class object, avoiding a call to to GrMalloc if
+ *  possible.
+ */
+template <int COUNT, typename T>
+class GrAutoSTMalloc : public GrAutoSMalloc<COUNT * sizeof(T)> {
+public:
+    GrAutoSTMalloc(int count) : GrAutoSMalloc<COUNT * sizeof(T)>(count * sizeof(T)) {}
+
+    operator T*() { return (T*)this->get(); }
+};
+
+
+#endif
+
diff --git a/gpu/include/GrMesh.h b/gpu/include/GrMesh.h
new file mode 100644
index 0000000..4d904e4
--- /dev/null
+++ b/gpu/include/GrMesh.h
@@ -0,0 +1,42 @@
+#ifndef GrMesh_DEFINED
+#define GrMesh_DEFINED
+
+#include "SkRect.h"
+#include "SkPoint.h"
+
+class SkCanvas;
+class SkPaint;
+
+class GrMesh {
+public:
+    GrMesh();
+    ~GrMesh();
+
+    GrMesh& operator=(const GrMesh& src);
+
+    void init(const SkRect& bounds, int rows, int cols,
+              const SkRect& texture);
+
+    const SkRect& bounds() const { return fBounds; }
+
+    int rows() const { return fRows; }
+    int cols() const { return fCols; }
+    SkPoint& pt(int row, int col) {
+        return fPts[row * (fRows + 1) + col];
+    }
+
+    void draw(SkCanvas*, const SkPaint&);
+    void drawWireframe(SkCanvas* canvas, const SkPaint& paint);
+
+private:
+    SkRect      fBounds;
+    int         fRows, fCols;
+    SkPoint*    fPts;
+    SkPoint*    fTex;   // just points into fPts, not separately allocated
+    int         fCount;
+    uint16_t*   fIndices;
+    int         fIndexCount;
+};
+
+#endif
+
diff --git a/gpu/include/GrNoncopyable.h b/gpu/include/GrNoncopyable.h
new file mode 100644
index 0000000..888e3b1
--- /dev/null
+++ b/gpu/include/GrNoncopyable.h
@@ -0,0 +1,38 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrNoncopyable_DEFINED
+#define GrNoncopyable_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ *  Base for classes that want to disallow copying themselves. It makes its
+ *  copy-constructor and assignment operators private (and unimplemented).
+ */
+class GrNoncopyable {
+public:
+    GrNoncopyable() {}
+
+private:
+    // illegal
+    GrNoncopyable(const GrNoncopyable&);
+    GrNoncopyable& operator=(const GrNoncopyable&);
+};
+
+#endif
+
diff --git a/gpu/include/GrPath.h b/gpu/include/GrPath.h
new file mode 100644
index 0000000..a9b7566
--- /dev/null
+++ b/gpu/include/GrPath.h
@@ -0,0 +1,84 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPath_DEFINED
+#define GrPath_DEFINED
+
+#include "GrPathSink.h"
+#include "GrPathIter.h"
+#include "GrTDArray.h"
+#include "GrPoint.h"
+
+class GrPath : public GrPathSink {
+public:
+    GrPath();
+    GrPath(const GrPath&);
+    explicit GrPath(GrPathIter&);
+    virtual ~GrPath();
+
+    GrPathIter::ConvexHint getConvexHint() const { return fConvexHint; }
+    void setConvexHint(GrPathIter::ConvexHint hint) { fConvexHint = hint; }
+
+    void resetFromIter(GrPathIter*);
+
+    // overrides from GrPathSink
+
+    virtual void moveTo(GrScalar x, GrScalar y);
+    virtual void lineTo(GrScalar x, GrScalar y);
+    virtual void quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1);
+    virtual void cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+                         GrScalar x2, GrScalar y2);
+    virtual void close();
+
+    class Iter : public GrPathIter {
+    public:
+        Iter(const GrPath& path);
+
+        // overrides from GrPathIter
+        virtual Command next(GrPoint points[]);
+        virtual ConvexHint hint() const;
+        virtual Command next();
+        virtual void rewind();
+    private:
+        const GrPath& fPath;
+        GrPoint       fLastPt;
+        int           fVerbIndex;
+        int           fPtIndex;
+    };
+
+private:
+    enum Verb {
+        kMove, kLine, kQuad, kCubic, kClose
+    };
+
+    GrTDArray<uint8_t>      fVerbs;
+    GrTDArray<GrPoint>      fPts;
+    GrPathIter::ConvexHint  fConvexHint;
+
+    // this ensures we have a moveTo at the start of each contour
+    inline void ensureMoveTo();
+
+    bool wasLastVerb(Verb verb) const {
+        int count = fVerbs.count();
+        return count > 0 && verb == fVerbs[count - 1];
+    }
+
+    friend class Iter;
+};
+
+#endif
+
diff --git a/gpu/include/GrPathIter.h b/gpu/include/GrPathIter.h
new file mode 100644
index 0000000..028faaa
--- /dev/null
+++ b/gpu/include/GrPathIter.h
@@ -0,0 +1,110 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPathIter_DEFINED
+#define GrPathIter_DEFINED
+
+#include "GrTypes.h"
+
+struct GrPoint;
+
+/**
+ 2D Path iterator. Porting layer creates a subclass of this. It allows Ganesh to
+ parse the top-level API's 2D paths. Supports lines, quadratics, and cubic
+ pieces and moves (multi-part paths).
+ */
+class GrPathIter {
+public:
+    /**
+     Returned by next(). Indicates the next piece of the path. 
+     */
+    enum Command {
+        kMove_Command,      //!< next() returns 1 pt
+                            //   Starts a new subpath at
+                            //   at the returned point
+        kLine_Command,      //!< next() returns 2 pts
+                            //   Adds a line segment
+        kQuadratic_Command, //!< next() returns 3 pts
+                            //   Adds a quadratic segment
+        kCubic_Command,     //!< next() returns 4 pts
+                            //   Adds a cubic segment
+        kClose_Command,     //!< next() returns 0 pts
+        kEnd_Command        //!< next() returns 0 pts
+                            //   Implictly closes the last 
+                            //   point
+    };
+    
+    enum ConvexHint {
+        kNone_ConvexHint,                         //<! No hint about convexity 
+                                                  //   of the path
+        kConvex_ConvexHint,                       //<! Path is one convex piece
+        kNonOverlappingConvexPieces_ConvexHint,   //<! Multiple convex pieces, 
+                                                  //   pieces are known to be
+                                                  //   disjoint
+        kSameWindingConvexPieces_ConvexHint,      //<! Multiple convex pieces, 
+                                                  //   may or may not intersect,
+                                                  //   either all wind cw or all 
+                                                  //   wind ccw.
+        kConcave_ConvexHint                       //<! Path is known to be 
+                                                  //   concave
+    };
+    
+    static int NumCommandPoints(Command cmd) {
+        static const int numPoints[] = {
+            1, 2, 3, 4, 0, 0
+        };
+        return numPoints[cmd];
+    }
+    
+    virtual ~GrPathIter() {};
+
+    /** 
+     Iterates through the path. Should not be called after
+     kEnd_Command has been returned once. This version retrieves the
+     points for the command.
+     @param points  The points relevant to returned commend. See Command
+                    enum for number of points valid for each command.
+     @return The next command of the path.
+     */
+    virtual Command next(GrPoint points[4]) = 0;
+
+    /**
+     * If the host API has knowledge of the convexity of the path
+     * it can be communicated by this hint. Ganesh can make these
+     * determinations itself. So it is not necessary to compute 
+     * convexity status if it isn't already determined.
+     *
+     * @return a hint about the convexity of the path.
+     */     
+    virtual ConvexHint hint() const { return kNone_ConvexHint; }
+
+     /** 
+     Iterates through the path. Should not be called after
+     kEnd_Command has been returned once. This version does not retrieve the
+     points for the command.
+     @return The next command of the path.
+     */
+     virtual Command next() = 0;
+
+    /**
+     Restarts iteration from the beginning.
+     */
+    virtual void rewind() = 0;
+
+};
+
+#endif
diff --git a/gpu/include/GrPathSink.h b/gpu/include/GrPathSink.h
new file mode 100644
index 0000000..4e8a0c2
--- /dev/null
+++ b/gpu/include/GrPathSink.h
@@ -0,0 +1,36 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPathSink_DEFINED
+#define GrPathSink_DEFINED
+
+#include "GrScalar.h"
+
+class GrPathSink {
+public:
+    virtual ~GrPathSink() {}
+
+    virtual void moveTo(GrScalar x, GrScalar y) = 0;
+    virtual void lineTo(GrScalar x, GrScalar y) = 0;
+    virtual void quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) = 0;
+    virtual void cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+                         GrScalar x2, GrScalar y2) = 0;
+    virtual void close() = 0;
+};
+
+#endif
+
diff --git a/gpu/include/GrPlotMgr.h b/gpu/include/GrPlotMgr.h
new file mode 100644
index 0000000..cd60bde
--- /dev/null
+++ b/gpu/include/GrPlotMgr.h
@@ -0,0 +1,84 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPlotMgr_DEFINED
+#define GrPlotMgr_DEFINED
+
+#include "GrTypes.h"
+#include "GrPoint.h"
+
+class GrPlotMgr : GrNoncopyable {
+public:
+    GrPlotMgr(int width, int height) {
+        fDim.set(width, height);
+        size_t needed = width * height;
+        if (needed <= sizeof(fStorage)) {
+            fBusy = fStorage;
+        } else {
+            fBusy = new char[needed];
+        }
+        this->reset();
+    }
+
+    ~GrPlotMgr() {
+        if (fBusy != fStorage) {
+            delete[] fBusy;
+        }
+    }
+    
+    void reset() {
+        Gr_bzero(fBusy, fDim.fX * fDim.fY);
+    }
+
+    bool newPlot(GrIPoint16* loc) {
+        char* busy = fBusy;
+        for (int y = 0; y < fDim.fY; y++) {
+            for (int x = 0; x < fDim.fX; x++) {
+                if (!*busy) {
+                    *busy = true;
+                    loc->set(x, y);
+                    return true;
+                }
+                busy++;
+            }
+        }
+        return false;
+    }
+
+    bool isBusy(int x, int y) const {
+        GrAssert((unsigned)x < (unsigned)fDim.fX);
+        GrAssert((unsigned)y < (unsigned)fDim.fY);
+        return fBusy[y * fDim.fX + x] != 0;
+    }
+
+    void freePlot(int x, int y) {
+        GrAssert((unsigned)x < (unsigned)fDim.fX);
+        GrAssert((unsigned)y < (unsigned)fDim.fY);
+        fBusy[y * fDim.fX + x] = false;
+    }
+
+private:
+    enum {
+        STORAGE = 64
+    };
+    char fStorage[STORAGE];
+    char* fBusy;
+    GrIPoint16  fDim;
+};
+
+#endif
+
diff --git a/gpu/include/GrPoint.h b/gpu/include/GrPoint.h
new file mode 100644
index 0000000..bb24959
--- /dev/null
+++ b/gpu/include/GrPoint.h
@@ -0,0 +1,287 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPoint_DEFINED
+#define GrPoint_DEFINED
+
+#include "GrTypes.h"
+#include "GrScalar.h"
+
+/**
+ *  2D Point struct
+ */
+struct GrPoint {
+public:
+    GrScalar fX, fY;
+
+    GrPoint() {}
+    GrPoint(GrScalar x, GrScalar y) { fX = x; fY = y; }
+    
+    GrScalar x() const { return fX; }
+    GrScalar y() const { return fY; }
+
+    void set(GrScalar x, GrScalar y) {
+        fX = x;
+        fY = y;
+    }
+    
+    void setAsMidPoint(const GrPoint& a, const GrPoint& b) {
+        fX = GrScalarAve(a.fX, b.fX);
+        fY = GrScalarAve(a.fY, b.fY);
+    }
+
+    void offset(GrScalar dx, GrScalar dy) {
+        fX += dx;
+        fY += dy;
+    }
+
+    GrScalar distanceToSqd(const GrPoint& p) const {
+        GrScalar dx = (p.fX - fX);
+        GrScalar dy = (p.fY - fY);
+        return GrMul(dx, dx) + GrMul(dy, dy);
+    }
+    
+    GrScalar distanceTo(const GrPoint& p) const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToSqd(p))));
+    }
+    
+    GrScalar distanceToOriginSqd() const {
+        return GrMul(fX, fX) + GrMul(fY, fY);
+    }
+
+    GrScalar distanceToOrigin() const {
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToOriginSqd())));
+    }
+    
+    inline GrScalar distanceToLineBetweenSqd(const GrPoint& a, 
+                                             const GrPoint& b) const;
+
+    inline GrScalar distanceToLineBetween(const GrPoint& a, 
+                                          const GrPoint& b) const;
+    
+    inline GrScalar distanceToLineSegmentBetweenSqd(const GrPoint& a, 
+                                                    const GrPoint& b) const;
+    
+    inline GrScalar distanceToLineSegmentBetween(const GrPoint& a, 
+                                                 const GrPoint& b) const;
+    
+    // counter-clockwise fan
+    void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b) {
+        GrPoint* v = this;
+        v[0].set(l, t);
+        v[1].set(l, b);
+        v[2].set(r, b);
+        v[3].set(r, t);
+    }
+    
+    void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b, size_t stride) {
+        GrAssert(stride >= sizeof(GrPoint));
+        ((GrPoint*)((intptr_t)this + 0 * stride))->set(l, t);
+        ((GrPoint*)((intptr_t)this + 1 * stride))->set(l, b);
+        ((GrPoint*)((intptr_t)this + 2 * stride))->set(r, b);
+        ((GrPoint*)((intptr_t)this + 3 * stride))->set(r, t);
+    }
+    
+    // counter-clockwise fan
+    void setIRectFan(int l, int t, int r, int b) {
+        GrPoint* v = this;
+        v[0].set(GrIntToScalar(l), GrIntToScalar(t));
+        v[1].set(GrIntToScalar(l), GrIntToScalar(b));
+        v[2].set(GrIntToScalar(r), GrIntToScalar(b));
+        v[3].set(GrIntToScalar(r), GrIntToScalar(t));
+    }
+    
+    void setIRectFan(int l, int t, int r, int b, size_t stride) {
+        GrAssert(stride >= sizeof(GrPoint));
+        ((GrPoint*)((intptr_t)this + 0 * stride))->set(GrIntToScalar(l), 
+                                                      GrIntToScalar(t));
+        ((GrPoint*)((intptr_t)this + 1 * stride))->set(GrIntToScalar(l), 
+                                                      GrIntToScalar(b));
+        ((GrPoint*)((intptr_t)this + 2 * stride))->set(GrIntToScalar(r), 
+                                                      GrIntToScalar(b));
+        ((GrPoint*)((intptr_t)this + 3 * stride))->set(GrIntToScalar(r), 
+                                                      GrIntToScalar(t));
+    }
+    
+    bool operator ==(const GrPoint& p) const {
+        return fX == p.fX && fY == p.fY;
+    }
+    
+    bool operator !=(const GrPoint& p) const {
+        return fX != p.fX || fY != p.fY;
+    }
+};
+
+struct GrIPoint16 {
+    int16_t fX, fY;
+    
+    void set(intptr_t x, intptr_t y) {
+        fX = GrToS16(x);
+        fY = GrToS16(y);
+    }
+};
+
+struct GrVec {
+public:
+    GrScalar fX, fY;
+    
+    GrVec() {}
+    GrVec(GrScalar x, GrScalar y) { fX = x; fY = y; }
+    
+    GrScalar x() const { return fX; }
+    GrScalar y() const { return fY; }
+    
+    /**
+     * set x and y length of the vector.
+     */
+    void set(GrScalar x, GrScalar y) {
+        fX = x;
+        fY = y;
+    }
+    
+    /**
+     * set vector to point from a to b.
+     */
+    void setBetween(const GrPoint& a, const GrPoint& b) {
+        fX = b.fX - a.fX;
+        fY = b.fY - a.fY;
+    }
+      
+    /**
+     * length of the vector squared.
+     */
+    GrScalar lengthSqd() const {
+        return GrMul(fX, fX) + GrMul(fY, fY);
+    }
+    
+    /**
+     * length of the vector.
+     */
+    GrScalar length() const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(lengthSqd())));
+    }
+    
+    /**
+     * normalizes the vector if it's length is not 0.
+     * @return true if normalized, otherwise false.
+     */
+    bool normalize() {
+        GrScalar l = lengthSqd();
+        if (l) {
+            // TODO: fixed point sqrt and invert
+            l = 1 / sqrtf(l);
+            fX *= l;
+            fY *= l;
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Dot product of this with vec.
+     */
+    GrScalar dot(const GrVec& vec) const {
+        return GrMul(vec.fX, fX) + GrMul(vec.fY, fY);
+    }
+   
+    /**
+     * z-value of this cross vec.
+     */
+    GrScalar cross(const GrVec& vec) const {
+        return GrMul(fX, vec.fY) - GrMul(fY, vec.fX);
+    }
+    
+    bool operator ==(const GrPoint& p) const {
+        return fX == p.fX && fY == p.fY;
+    }
+    
+    bool operator !=(const GrPoint& p) const {
+        return fX != p.fX || fY != p.fY;
+    }
+};
+
+GrScalar GrPoint::distanceToLineBetweenSqd(const GrPoint& a, 
+                                           const GrPoint& b) const {
+    // Let d be the distance between c (this) and line ab.
+    // The area of the triangle defined by a, b, and c is 
+    // A = |b-a|*d/2. Let u = b-a and v = c-a. The cross product of
+    // u and v is aligned with the z axis and its magnitude is 2A. 
+    // So d = |u x v| / |u|.
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar det = u.cross(v);
+    return (GrMul(det, det)) / u.lengthSqd();
+}
+
+GrScalar GrPoint::distanceToLineBetween(const GrPoint& a, 
+                                        const GrPoint& b) const {
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar det = u.cross(v);
+    return (GrScalarAbs(det)) / u.length();
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetweenSqd(const GrPoint& a, 
+                                                  const GrPoint& b) const {
+    // See comments to distanceToLineBetweenSqd. If the projection of c onto
+    // u is between a and b then this returns the same result as that 
+    // function. Otherwise, it returns the distance to the closer of a and
+    // b. Let the projection of v onto u be v'.  There are three cases:
+    //    1. v' points opposite to u. c is not between a and b and is closer
+    //       to a than b.
+    //    2. v' points along u and has magnitude less than y. c is between
+    //       a and b and the distance to the segment is the same as distance
+    //       to the line ab.
+    //    3. v' points along u and has greater magnitude than u. c is not
+    //       not between a and b and is closer to b than a.
+    // v' = (u dot v) * u / |u|. So if (u dot v)/|u| is less than zero we're 
+    // in case 1. If (u dot v)/|u| is > |u| we are in case 3. Otherwise
+    // we're in case 2. We actually compare (u dot v) to 0 and |u|^2 to 
+    // avoid a sqrt to compute |u|.
+    
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar uLengthSqd = u.lengthSqd();
+    GrScalar uDotV = u.dot(v);
+    
+    if (uDotV <= 0) {
+        return v.lengthSqd();
+    } else if (uDotV > uLengthSqd) {
+        return b.distanceToSqd(*this);
+    } else {
+        GrScalar det = u.cross(v);
+        return (GrMul(det, det)) / uLengthSqd;
+    }
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetween(const GrPoint& a, 
+                                               const GrPoint& b) const {
+    // TODO: fixed point sqrt
+    return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToLineSegmentBetweenSqd(a,b))));
+}
+
+
+#endif
+
diff --git a/gpu/include/GrRandom.h b/gpu/include/GrRandom.h
new file mode 100644
index 0000000..408f61d
--- /dev/null
+++ b/gpu/include/GrRandom.h
@@ -0,0 +1,62 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRandom_DEFINED
+#define GrRandom_DEFINED
+
+class GrRandom {
+public:
+    GrRandom() : fSeed(0) {}
+    GrRandom(uint32_t seed) : fSeed(seed) {}
+
+    uint32_t seed() const { return fSeed; }
+
+    uint32_t nextU() {
+        fSeed = fSeed * kMUL + kADD;
+        return fSeed;
+    }
+
+    int32_t nextS() { return (int32_t)this->nextU(); }
+
+    /**
+     *  Returns value [0...1) as a float
+     */
+    float nextF() {
+        // const is 1 / (2^32 - 1)
+        return (float)(this->nextU() * 2.32830644e-10);
+    }
+
+    /**
+     *  Returns value [min...max) as a float
+     */
+    float nextF(float min, float max) {
+        return min + this->nextF() * (max - min);
+    }
+
+private:
+    /*
+     *  These constants taken from "Numerical Recipes in C", reprinted 1999
+     */
+    enum {
+        kMUL = 1664525,
+        kADD = 1013904223
+    };
+    uint32_t    fSeed;
+};
+
+#endif
+
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
new file mode 100644
index 0000000..5192ebd
--- /dev/null
+++ b/gpu/include/GrRect.h
@@ -0,0 +1,284 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRect_DEFINED
+#define GrRect_DEFINED
+
+#include "GrPoint.h"
+
+struct GrIRect {
+    int32_t fLeft, fTop, fRight, fBottom;
+    
+    GrIRect() {}
+    GrIRect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+        fLeft = left;
+        fTop = top;
+        fRight = right;
+        fBottom = bottom;
+    }
+
+    int32_t x() const { return fLeft; }
+    int32_t y() const { return fTop; }
+    int32_t width() const { return fRight - fLeft; }
+    int32_t height() const { return fBottom - fTop; }
+
+    bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+    bool isInverted() const { return fLeft > fRight || fTop > fBottom; }
+
+    void setEmpty() { fLeft = fTop = fRight = fBottom = 0; }
+
+    void setXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
+        fLeft = x;
+        fTop = y;
+        fRight = x + w;
+        fBottom = y + h;
+    }
+    
+    void setLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
+        fLeft = l;
+        fTop = t;
+        fRight = r;
+        fBottom = b;
+    }
+    
+    /**
+     *  Make the largest representable rectangle
+
+     */
+    void setLargest() {
+        fLeft = fTop = GR_Int32Min;
+        fRight = fBottom = GR_Int32Max;
+    }
+    
+    bool quickReject(int l, int t, int r, int b) const {
+        return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
+    }
+
+    void unionWith(const GrIRect& r) {
+        if (fLeft > r.fLeft) fLeft = r.fLeft;
+        if (fTop > r.fTop) fTop = r.fTop;
+        if (fRight < r.fRight) fRight = r.fRight;
+        if (fBottom < r.fBottom) fBottom = r.fBottom;
+    }
+
+    friend bool operator==(const GrIRect& a, const GrIRect& b) {
+        return 0 == memcmp(&a, &b, sizeof(a));
+    }
+    
+    friend bool operator!=(const GrIRect& a, const GrIRect& b) {
+        return 0 != memcmp(&a, &b, sizeof(a));
+    }
+
+    bool equalsLTRB(int l, int t, int r, int b) const {
+        return fLeft == l && fTop == t &&
+               fRight == r && fBottom == b;
+    }
+    bool equalsXYWH(int x, int y, int w, int h) const {
+        return fLeft == x && fTop == y &&
+               this->width() == w && this->height() == h;
+    }
+    
+    bool contains(const GrIRect& r) const {
+        return fLeft   <= r.fLeft &&
+               fRight  >= r.fRight &&
+               fTop    <= r.fTop &&
+               fBottom >= r.fBottom;
+    }
+};
+
+struct GrIRect16 {
+    int16_t fLeft, fTop, fRight, fBottom;
+    
+    int width() const { return fRight - fLeft; }
+    int height() const { return fBottom - fTop; }
+    int area() const { return this->width() * this->height(); }
+    bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+    
+    void set(const GrIRect& r) {
+        fLeft   = GrToS16(r.fLeft);
+        fTop    = GrToS16(r.fTop);
+        fRight  = GrToS16(r.fRight);
+        fBottom = GrToS16(r.fBottom);
+    }
+};
+
+/** 
+ *  2D Rect struct
+ */
+struct GrRect {
+    GrScalar fLeft, fTop, fRight, fBottom;
+    
+    /**
+     *  Uninitialized rectangle.
+     */
+    GrRect() {}
+
+    /**
+     *  Initialize a rectangle to a point.
+     *  @param pt the point used to initialize the rectanglee.
+     */
+    GrRect(GrPoint pt) {
+        setToPoint(pt);
+    }
+
+    GrRect(GrScalar left, GrScalar top, GrScalar right, GrScalar bottom) {
+        fLeft = left;
+        fTop = top;
+        fRight = right;
+        fBottom = bottom;
+    }
+
+    explicit GrRect(const GrIRect& src) {
+        fLeft = GrIntToScalar(src.fLeft);
+        fTop = GrIntToScalar(src.fTop);
+        fRight = GrIntToScalar(src.fRight);
+        fBottom = GrIntToScalar(src.fBottom);
+    }
+
+    GrScalar x() const { return fLeft; }
+    GrScalar y() const { return fTop; }
+    GrScalar width() const { return fRight - fLeft; }
+    GrScalar height() const { return fBottom - fTop; }
+
+    GrScalar left() const { return fLeft; }
+    GrScalar top() const { return fTop; }
+    GrScalar right() const { return fRight; }
+    GrScalar bottom() const { return fBottom; }
+    
+    GrScalar diagonalLengthSqd() const {
+        GrScalar w = width();
+        GrScalar h = height();
+        return GrMul(w, w) + GrMul(h, h);
+    }
+
+    GrScalar diagonalLength() const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(diagonalLengthSqd())));
+    }
+    
+    /**
+     *  Returns true if the width or height is <= 0
+     */
+    bool isEmpty() const {
+        return fLeft >= fRight || fTop >= fBottom;
+    }
+    
+    void setEmpty() {
+        fLeft = fTop = fRight = fBottom = 0;
+    }
+    
+    /**
+     *  returns true if the rectangle is inverted either in x or y
+     */
+    bool isInverted() const {
+        return (fLeft > fRight) || (fTop > fBottom);
+    }
+    
+    /**
+     *  Initialize a rectangle to a point.
+     *  @param pt the point used to initialize the rectangle.
+     */
+    void setToPoint(const GrPoint& pt) {
+        fLeft = pt.fX;
+        fTop = pt.fY;
+        fRight = pt.fX;
+        fBottom = pt.fY;
+    }
+
+    void set(const GrIRect& r) {
+        fLeft = GrIntToScalar(r.fLeft);
+        fTop = GrIntToScalar(r.fTop);
+        fRight = GrIntToScalar(r.fRight);
+        fBottom = GrIntToScalar(r.fBottom);
+    }
+
+    void roundOut(GrIRect* r) const {
+        r->setLTRB(GrScalarFloorToInt(fLeft),
+                   GrScalarFloorToInt(fTop),
+                   GrScalarCeilToInt(fRight),
+                   GrScalarCeilToInt(fBottom));
+    }
+
+    /**
+     *  Set the rect to the union of the array of points. If the array is empty
+     *  the rect will be empty [0,0,0,0]
+     */
+    void setBounds(const GrPoint pts[], int count);
+
+    /**
+     *  Make the largest representable rectangle
+     *  Set the rect to fLeft = fTop = GR_ScalarMin and 
+     *  fRight = fBottom = GR_ScalarMax.
+     */
+    void setLargest() {
+        fLeft = fTop = GR_ScalarMin;
+        fRight = fBottom = GR_ScalarMax;
+    }
+    
+    /**
+     Set the rect to fLeft = fTop = GR_ScalarMax and 
+     fRight = fBottom = GR_ScalarMin.
+     Useful for initializing a bounding rectangle.
+     */
+    void setLargestInverted() {
+        fLeft = fTop = GR_ScalarMax;
+        fRight = fBottom = GR_ScalarMin;
+    }
+    
+    void setLTRB(GrScalar left, 
+                 GrScalar top, 
+                 GrScalar right, 
+                 GrScalar bottom) {
+        fLeft = left;
+        fTop = top;
+        fRight = right;
+        fBottom = bottom;
+    }
+    
+    void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
+        fLeft = x;
+        fTop = y;
+        fRight = x + width;
+        fBottom = y + height;
+    }
+    
+    /**
+     Expand the edges of the rectangle to include a point.
+     Useful for constructing a bounding rectangle.
+     @param pt  the point used to grow the rectangle.
+     */
+    void growToInclude(const GrPoint& pt) {
+        fLeft  = GrMin(pt.fX, fLeft);
+        fRight = GrMax(pt.fX, fRight);
+        
+        fTop    = GrMin(pt.fY, fTop);
+        fBottom = GrMax(pt.fY, fBottom);
+    }
+
+    /**
+     *  Assigns 4 sequential points in order to construct a counter-clockwise
+     *  triangle fan, given the corners of this rect. Returns the address of
+     *  the next point, treating pts as an array.
+     */
+    GrPoint* setRectFan(GrPoint pts[4]) const {
+        pts->setRectFan(fLeft, fTop, fRight, fBottom);
+        return pts + 4;
+    }
+};
+
+#endif
+
diff --git a/gpu/include/GrRectanizer.h b/gpu/include/GrRectanizer.h
new file mode 100644
index 0000000..50bb8fe
--- /dev/null
+++ b/gpu/include/GrRectanizer.h
@@ -0,0 +1,64 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRectanizer_DEFINED
+#define GrRectanizer_DEFINED
+
+#include "GrRect.h"
+#include "GrTDArray.h"
+
+class GrRectanizerPurgeListener {
+public:
+    virtual ~GrRectanizerPurgeListener() {}
+
+    virtual void notifyPurgeStrip(void*, int yCoord) = 0;
+};
+
+class GrRectanizer {
+public:
+    GrRectanizer(int width, int height) : fWidth(width), fHeight(height) {
+        GrAssert(width >= 0);
+        GrAssert(height >= 0);
+    }
+
+    virtual ~GrRectanizer() {}
+
+    int width() const { return fWidth; }
+    int height() const { return fHeight; }
+
+    virtual bool addRect(int width, int height, GrIPoint16* loc) = 0;
+    virtual float percentFull() const = 0;
+
+    // return the Y-coordinate of a strip that should be purged, given height
+    // i.e. return the oldest such strip, or some other criteria. Return -1
+    // if there is no candidate
+    virtual int stripToPurge(int height) const = 0;
+    virtual void purgeStripAtY(int yCoord) = 0;
+
+    /**
+     *  Our factory, which returns the subclass du jour
+     */
+    static GrRectanizer* Factory(int width, int height);
+
+private:
+    int fWidth;
+    int fHeight;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrRefCnt.h b/gpu/include/GrRefCnt.h
new file mode 100644
index 0000000..7204aff
--- /dev/null
+++ b/gpu/include/GrRefCnt.h
@@ -0,0 +1,125 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrRefCnt_DEFINED
+#define GrRefCnt_DEFINED
+
+#include "GrTypes.h"
+#include "GrNoncopyable.h"
+
+/**
+ *  Base class for reference counting. When an object is first instantiated,
+ *  its reference count is 1. If the object may be null, use GrSafeRef() and
+ *  GrSafeUnref().
+ *
+ *  It is an error (though only checked for in the debug build) to call unref()
+ *  such that the reference count becomes 0.
+ */
+class GrRefCnt : GrNoncopyable {
+public:
+            GrRefCnt() : fRefCnt(1) {}
+    virtual ~GrRefCnt() {
+        GrAssert(1 == fRefCnt);
+#if GR_DEBUG
+        fRefCnt = 0;    // force validate() to trigger if called afterwards
+#endif
+    }
+
+    int32_t refcnt() const { return fRefCnt; }
+
+    void ref() const {
+        GrAssert(fRefCnt > 0);
+        ++fRefCnt;
+    }
+
+    void unref() const {
+        GrAssert(fRefCnt > 0);
+        if (1 == fRefCnt) {
+            delete this;
+        } else {
+            --fRefCnt;
+        }
+    }
+
+#if GR_DEBUG
+    void validate() const {
+        GrAssert(fRefCnt > 0);
+    }
+#else
+    void validate() const {}
+#endif
+
+private:
+    mutable int32_t fRefCnt;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Call with instance/subclass of GrRefCnt. This does nothing if obj is null,
+ *  but otherwise it calls ref().
+ */
+static inline void GrSafeRef(const GrRefCnt* obj) {
+    if (obj) {
+        obj->ref();
+    }
+}
+
+/**
+ *  Call with instance/subclass of GrRefCnt. This does nothing if obj is null,
+ *  but otherwise it calls unref().
+ */
+static inline void GrSafeUnref(const GrRefCnt* obj) {
+    if (obj) {
+        obj->unref();
+    }
+}
+
+/**
+ *  Assigns src to dst, checking for NULLs in each, and correctly incrementing
+ *  the reference count of src, and decrementing the reference count of dst
+ */
+static inline void GrSafeAssign(GrRefCnt*& dst, GrRefCnt* src) {
+    if (src) {
+        src->ref();
+    }
+    if (dst) {
+        dst->unref();
+    }
+    dst = src;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class GrAutoRef : GrNoncopyable {
+public:
+    GrAutoRef(GrRefCnt* obj) : fObj(obj) { GrSafeRef(obj); }
+    ~GrAutoRef() { GrSafeUnref(fObj); }
+private:
+    GrRefCnt* fObj;
+};
+
+class GrAutoUnref : GrNoncopyable {
+public:
+    GrAutoUnref(GrRefCnt* obj) : fObj(obj) {}
+    ~GrAutoUnref() { GrSafeUnref(fObj); }
+private:
+    GrRefCnt* fObj;
+};
+
+#endif
+
diff --git a/gpu/include/GrSamplerState.h b/gpu/include/GrSamplerState.h
new file mode 100644
index 0000000..06c2346
--- /dev/null
+++ b/gpu/include/GrSamplerState.h
@@ -0,0 +1,130 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrSamplerState_DEFINED
+#define GrSamplerState_DEFINED
+
+#include "GrTypes.h"
+
+class GrSamplerState {
+public:
+    enum SampleMode {
+        kNormal_SampleMode,     //!< sample color directly
+        kAlphaMod_SampleMode,   //!< modulate with alpha only
+        kRadial_SampleMode,     //!< treat as radial gradient
+        kRadial2_SampleMode,    //!< treat as 2-point radial gradient
+        kSweep_SampleMode,      //!< treat as sweep gradient
+    };
+
+    /**
+     * Describes how a texture is sampled when coordinates are outside the
+     * texture border
+     */
+    enum WrapMode {
+        kClamp_WrapMode,
+        kRepeat_WrapMode,
+        kMirror_WrapMode
+    };
+
+    /**
+     *  Default sampler state is set to kClamp and no-filter
+     */
+    GrSamplerState() {
+        this->setClampNoFilter();
+    }
+
+    GrSamplerState(bool filter) {
+        fWrapX = kClamp_WrapMode;
+        fWrapY = kClamp_WrapMode;
+        fSampleMode = kNormal_SampleMode;
+        fFilter = filter;
+    }
+    
+    GrSamplerState(WrapMode wx, WrapMode wy, bool filter) {
+        fWrapX = wx;
+        fWrapY = wy;
+        fSampleMode = kNormal_SampleMode;
+        fFilter = filter;
+    }
+    
+    GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, bool filter) {
+        fWrapX = wx;
+        fWrapY = wy;
+        fSampleMode = sample;
+        fFilter = filter;
+    }
+    
+    WrapMode getWrapX() const { return fWrapX; }
+    WrapMode getWrapY() const { return fWrapY; }
+    SampleMode getSampleMode() const { return fSampleMode; }
+    bool isFilter() const { return fFilter; }
+
+    bool isGradient() const {
+        return  kRadial_SampleMode == fSampleMode ||
+                kRadial2_SampleMode == fSampleMode ||
+                kSweep_SampleMode == fSampleMode;
+    }
+
+    void setWrapX(WrapMode mode) { fWrapX = mode; }
+    void setWrapY(WrapMode mode) { fWrapY = mode; }
+    void setSampleMode(SampleMode mode) { fSampleMode = mode; }
+    void setFilter(bool filter) { fFilter = filter; }
+
+    void setClampNoFilter() {
+        fWrapX = kClamp_WrapMode;
+        fWrapY = kClamp_WrapMode;
+        fSampleMode = kNormal_SampleMode;
+        fFilter = false;
+    }
+
+    GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
+    GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
+    bool     isRadial2PosRoot() const { return fRadial2PosRoot; }
+
+    /**
+     * Sets the parameters for kRadial2_SampleMode. The texture 
+     * matrix must be set so that the first point is at (0,0) and the second 
+     * point lies on the x-axis. The second radius minus the first is 1 unit.
+     * The additional parameters to define the gradient are specified by this
+     * function.
+     */
+    void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) {
+        fRadial2CenterX1 = centerX1;
+        fRadial2Radius0 = radius0;
+        fRadial2PosRoot = posRoot;
+    }
+
+    static const GrSamplerState& ClampNoFilter() {
+        return gClampNoFilter;
+    }
+
+private:
+    WrapMode    fWrapX;
+    WrapMode    fWrapY;
+    SampleMode  fSampleMode;
+    bool        fFilter;
+
+    // these are undefined unless fSampleMode == kRadial2_SampleMode
+    GrScalar    fRadial2CenterX1;
+    GrScalar    fRadial2Radius0;
+    bool        fRadial2PosRoot;
+
+    static const GrSamplerState gClampNoFilter;
+};
+
+#endif
+
diff --git a/gpu/include/GrScalar.h b/gpu/include/GrScalar.h
new file mode 100644
index 0000000..1353fb2
--- /dev/null
+++ b/gpu/include/GrScalar.h
@@ -0,0 +1,116 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrScalar_DEFINED
+#define GrScalar_DEFINED
+
+#include "GrTypes.h"
+
+#include <float.h>
+#include <math.h>
+
+#define GR_Int32Max            (0x7fffffff)
+#define GR_Int32Min            (0x80000000)
+
+/**
+ *  Convert an int to fixed point 
+ */
+#if GR_DEBUG
+    inline GrFixed GrIntToFixed(int i) {
+        GrAssert(((i & 0xffff0000) == 0xffff0000) || ((i & 0xffff0000) == 0x0));
+        return i << 16;
+    }
+#else
+    #define GrIntToFixed(i) (GrFixed)((i) << 16)
+#endif
+
+#define GR_Fixed1              (1 << 16)
+#define GR_FixedHalf           (1 << 15)
+#define GR_FixedMax            GR_Int32Max
+#define GR_FixedMin            GR_Int32Min
+
+#define GrFixedFloorToFixed(x)  ((x) & ~0xFFFF)
+#define GrFixedFloorToInt(x)    ((x) >> 16)
+
+/**
+ *  Convert fixed point to floating point
+ */
+#define GrFixedToFloat(x)      ((x) * 0.0000152587890625f)
+
+/**
+ *  Convert floating point to fixed point
+ */
+#define GrFloatToFixed(x)      ((GrFixed)((x) * GR_Fixed1))
+
+inline GrFixed GrFixedAbs(GrFixed x) {
+    int32_t s = (x & 0x80000000) >> 31;
+    return (GrFixed)(((int32_t)x ^ s) - s);  
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_SCALAR_IS_FIXED
+    typedef GrFixed                 GrScalar;
+    #define GrIntToScalar(x)        GrIntToFixed(x)
+    #define GrFixedToScalar(x)      (x)
+    #define GrScalarToFloat(x)      GrFixedToFloat(x)
+    #define GrFloatToScalar(x)      GrFloatToFixed(x)
+    #define GrScalarHalf(x)         ((x) >> 1)
+    #define GrScalarAve(x,y)        (((x)+(y)) >> 1)
+    #define GrScalarAbs(x)          GrFixedAbs(x)
+    #define GR_Scalar1              GR_Fixed1
+    #define GR_ScalarHalf           GR_FixedHalf
+    #define GR_ScalarMax            GR_FixedMax
+    #define GR_ScalarMin            GR_FixedMin
+#elif GR_SCALAR_IS_FLOAT
+    typedef float                   GrScalar;
+    #define GrIntToScalar(x)        ((GrScalar)x)
+    #define GrFixedToScalar(x)      GrFixedToFloat(x)
+    #define GrScalarToFloat(x)      (x)
+    #define GrFloatToScalar(x)      (x)
+    #define GrScalarHalf(x)         ((x) * 0.5f)
+    #define GrScalarAbs(x)          fabsf(x)
+    #define GrScalarAve(x,y)        (((x) + (y)) * 0.5f)
+    #define GR_Scalar1              1.f    
+    #define GR_ScalarHalf           0.5f
+    #define GR_ScalarMax            (FLT_MAX)
+    #define GR_ScalarMin            (-FLT_MAX)
+
+    static inline int32_t GrScalarFloorToInt(float x) {
+        return (int32_t)::floorf(x);
+    }
+    static inline int32_t GrScalarCeilToInt(float x) {
+        return (int32_t)::ceilf(x);
+    }
+#else
+    #error "Scalar type not defined"
+#endif
+
+/**
+ *  Multiply two GrScalar values
+ */
+static inline GrScalar GrMul(GrScalar a, GrScalar b) {
+#if GR_SCALAR_IS_FLOAT
+    return a * b;
+#else
+    int64_t tmp = (int64_t)a * b;
+    return (tmp + GR_FixedHalf) >> 16;
+#endif
+}
+
+#endif
+
diff --git a/gpu/include/GrStopwatch.h b/gpu/include/GrStopwatch.h
new file mode 100644
index 0000000..4945897
--- /dev/null
+++ b/gpu/include/GrStopwatch.h
@@ -0,0 +1,135 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrStopwatch_DEFINED
+#define GrStopwatch_DEFINED
+
+#include "GrTypes.h"
+
+template <typename PLATFORM_TIMER>
+/**
+ * Base class for stopwatch. Relies on PLATFORM_TIMER for platform-specific
+ * timer functions. PLATFORM_TIMER provides:
+ *      - typename TIMESTAMP : a timestamp value that can be used with Diff()
+ *      - static TIMESTAMP Now() : gets current timestamp
+ *      - static double Diff(const TIMESTAMP& begin, const TIMESTAMP& end) : 
+ *           computes delta in seconds between two timestamps
+ */
+class GrStopwatchBase {
+public:
+    /**
+     * Contructor - implicit reset()
+     */
+    GrStopwatchBase() {
+        fRunning = false;
+        fTotalElapsed = 0.0;        
+    }
+
+    /**
+     * begins a new lap
+     */
+    void start() {
+        double lastLap = lapTime();
+        fTotalElapsed += lastLap;
+        fRunning = true;
+        fLastStart = PLATFORM_TIMER::Now();
+    }
+    
+    /**
+     * ends current lap (or no effect if lap not started)
+     */
+    void stop() {
+        double lastLap = lapTime();
+        fTotalElapsed += lastLap;
+        fRunning = false;
+    }
+
+    /**
+     * ends current lap, resets total time
+     */
+    void reset() {
+        fRunning = false;
+        fTotalElapsed = 0.f;
+    }
+    
+    /**
+     * Computes the time of all laps since last reset() including current lap
+     * if lap is still running.
+     *
+     * @return the sum time in seconds of all laps since last reset().
+     */
+    double totalTime() const {
+        return fTotalElapsed + lapTime();
+    }
+
+    /**
+     * Current lap time.
+     *
+     * @return time in seconds of current lap if one is running otherwise 0.
+     */
+    double lapTime() const {
+        if (fRunning) {
+            PLATFORM_TIMER::Timestamp now = PLATFORM_TIMER::Now();
+            return PLATFORM_TIMER::Elapsed(fLastStart, now);
+        }
+        return 0.0;
+    }
+
+private:
+    double fTotalElapsed;
+
+    typename PLATFORM_TIMER::Timestamp fLastStart;
+    bool                               fRunning;
+};
+
+#if GR_WIN32_BUILD
+
+    #include <Windows.h>
+
+    class GrWin32Timer {
+    public:
+        typedef LARGE_INTEGER Timestamp;  
+
+        static Timestamp Now() {
+            LARGE_INTEGER now;
+            QueryPerformanceCounter(&now);
+            return now;
+        }
+
+        static double Elapsed(const Timestamp& begin, const Timestamp& end) {
+            double diff = (double)(end.QuadPart - begin.QuadPart);
+            return diff * Scale();
+        }
+    private:
+        static double Scale() {
+            static double scale;
+            if (0.0 == scale) {
+                LARGE_INTEGER freq;
+                QueryPerformanceFrequency(&freq);
+                GrAssert(0 != freq.QuadPart);
+                scale = 1 / (double) freq.QuadPart;
+            }
+            return scale;
+        }
+    };
+    typedef GrStopwatchBase<GrWin32Timer> GrStopwatch;
+#else
+    #error "Implement platform timer for stopwatch"
+#endif
+
+
+#endif
diff --git a/gpu/include/GrStringBuilder.h b/gpu/include/GrStringBuilder.h
new file mode 100644
index 0000000..bcf124f
--- /dev/null
+++ b/gpu/include/GrStringBuilder.h
@@ -0,0 +1,182 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrStringBuilder_DEFINED
+#define GrStringBuilder_DEFINED
+
+#include <GrTArray.h>
+#include <stdio.h>
+
+// Class used to concat strings together into a single string
+// See below for GrSStringBuilder subclass that has a pool of
+// stack storage (to avoid malloc).
+class GrStringBuilder {
+public:
+    GrStringBuilder() :
+            fChars() {
+        fChars.push_back() = '\0';
+    }
+
+    GrStringBuilder(const GrStringBuilder& s) :
+            fChars(s.fChars) {
+        GrAssert('\0' == s.fChars.back());
+    }
+
+    GrStringBuilder(const char* s) :
+            fChars(s, strlen(s)+1) {
+    }
+
+    GrStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) {
+        GrAssert('\0' == a.fChars.back());
+        GrAssert('\0' == b.fChars.back());
+
+        fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
+        char* s = &fChars.front();
+        memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
+        s += a.fChars.count() - 1;
+        memcpy(s, &b.fChars.front(), b.fChars.count());
+    }
+
+    GrStringBuilder& operator =(const GrStringBuilder& s) {
+        fChars = s.fChars;
+        return *this;
+    }
+
+    GrStringBuilder& operator =(const char* s) {
+        GrAssert('\0' == fChars.back());
+
+        int l = strlen(s);
+        fChars.resize_back(l + 1);
+        memcpy(&fChars.front(), s, l + 1);
+        return *this;
+    }
+
+    GrStringBuilder& operator +=(const GrStringBuilder& s) {
+        GrAssert('\0' == fChars.back());
+        GrAssert('\0' == s.fChars.back());
+        fChars.push_back_n(s.length());
+        memcpy(&fChars.fromBack(s.length()), &s.fChars.front(), s.fChars.count());
+        return *this;
+    }
+
+    GrStringBuilder& operator +=(const char* s) {
+        GrAssert('\0' == fChars.back());
+        int l = strlen(s);
+        fChars.push_back_n(l);
+        memcpy(&fChars.fromBack(l), s, l + 1);
+        return *this;
+    }
+
+    GrStringBuilder& operator +=(char c) {
+        GrAssert('\0' == fChars.back());
+        fChars.back() = c;
+        fChars.push_back() = '\0';
+        return *this;
+    }
+
+    void appendInt(int x) {
+        GR_STATIC_ASSERT(4 == sizeof(int));
+        // -, 10 digits, null char
+        char temp[12];
+        sprintf(temp, "%d", x);
+        *this += temp;
+    }
+
+    char& operator [](int i) {
+        GrAssert(i < length());
+        return fChars[i];
+    }
+
+    char operator [](int i) const {
+        GrAssert(i < length());
+        return fChars[i];
+    }
+
+    const char* cstr() const { return &fChars.front(); }
+
+    int length() const { return fChars.count() - 1; }
+
+protected:
+    // helpers for GrSStringBuilder (with storage on the stack)
+
+    GrStringBuilder(void* stackChars, int stackCount) :
+            fChars(stackCount ? stackChars : NULL,
+                   stackCount) {
+        fChars.push_back() = '\0';
+    }
+
+    GrStringBuilder(void* stackChars,
+                    int stackCount,
+                    const GrStringBuilder& s) :
+            fChars(s.fChars,
+                   (stackCount ? stackChars : NULL),
+                   stackCount) {
+    }
+
+    GrStringBuilder(void* stackChars,
+                    int stackCount,
+                    const char* s) :
+            fChars(s,
+                   strlen(s)+1,
+                   stackCount ? stackChars : NULL,
+                   stackCount) {
+    }
+
+    GrStringBuilder(void* stackChars,
+                    int stackCount,
+                    const GrStringBuilder& a,
+                    const GrStringBuilder& b) :
+            fChars(stackCount ? stackChars : NULL,
+                   stackCount) {
+        GrAssert('\0' == a.fChars.back());
+        GrAssert('\0' == b.fChars.back());
+
+        fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
+        char* s = &fChars.front();
+        memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
+        s += a.fChars.count() - 1;
+        memcpy(s, &b.fChars.front(), b.fChars.count());
+    }
+
+private:
+    GrTArray<char, true>  fChars;
+};
+
+template <int STACK_COUNT = 128>
+class GrSStringBuilder : public GrStringBuilder {
+public:
+    GrSStringBuilder() : GrStringBuilder(fStackChars, STACK_COUNT) {}
+
+    GrSStringBuilder(const GrStringBuilder& s) : GrStringBuilder(fStackChars,
+                                                                 STACK_COUNT,
+                                                                 s) {
+    }
+
+    GrSStringBuilder(const char* s) : GrStringBuilder(fStackChars,
+                                                      STACK_COUNT,
+                                                      s) {
+    }
+
+    GrSStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) :
+            GrStringBuilder(fStackChars, STACK_COUNT, a, b) {
+    }
+private:
+    char fStackChars[STACK_COUNT];
+};
+
+#endif
+
diff --git a/gpu/include/GrTArray.h b/gpu/include/GrTArray.h
new file mode 100644
index 0000000..f0d9494
--- /dev/null
+++ b/gpu/include/GrTArray.h
@@ -0,0 +1,298 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTArray_DEFINED
+#define GrTArray_DEFINED
+
+#include <new>
+#include "GrTypes.h"
+
+// TODO: convert from uint32_t to int.
+
+// DATA_TYPE indicates that T has a trivial cons, destructor
+// and can be shallow-copied
+template <typename T, bool DATA_TYPE = false> class GrTArray {
+public:
+    GrTArray() {
+        fCount = 0;
+        fReserveCount = MIN_ALLOC_COUNT;
+        fAllocCount = 0;
+        fMemArray = NULL;
+        fPreAllocMemArray = NULL;
+    }
+
+    GrTArray(uint32_t reserveCount) {
+        fCount = 0;
+        fReserveCount = GrMax(reserveCount, (uint32_t)MIN_ALLOC_COUNT);
+        fAllocCount = fReserveCount;
+        fMemArray = GrMalloc(sizeof(T) * fReserveCount);
+        fPreAllocMemArray = NULL;
+    }
+
+    GrTArray(void* preAllocStorage, uint32_t preAllocCount) {
+        // we allow NULL,0 args and revert to the default cons. behavior
+        // this makes it possible for a owner-object to use same constructor
+        // to get either prealloc or nonprealloc behavior based using same line
+        GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+        fCount              = 0;
+        fReserveCount       = preAllocCount > 0 ? preAllocCount :
+                                                  MIN_ALLOC_COUNT;
+        fAllocCount         = preAllocCount;
+        fMemArray           = preAllocStorage;
+        fPreAllocMemArray   = preAllocStorage;
+    }
+
+    GrTArray(const GrTArray& array) {
+        fCount              = array.count();
+        fReserveCount       = MIN_ALLOC_COUNT;
+        fAllocCount         = GrMax(fReserveCount, fCount);
+        fMemArray           = GrMalloc(sizeof(T) * fAllocCount);
+        fPreAllocMemArray   = NULL;
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+        } else {
+            for (uint32_t i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray(const T* array, uint32_t count) {
+        fCount              = count;
+        fReserveCount       = MIN_ALLOC_COUNT;
+        fAllocCount         = GrMax(fReserveCount, fCount);
+        fMemArray           = GrMalloc(sizeof(T) * fAllocCount);
+        fPreAllocMemArray   = NULL;
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array, sizeof(T) * fCount);
+        } else {
+            for (uint32_t i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray(const GrTArray& array,
+             void* preAllocStorage, uint32_t preAllocCount) {
+
+        // for same reason as non-copying cons we allow NULL, 0 for prealloc
+        GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+        fCount              = array.count();
+        fReserveCount       = preAllocCount > 0 ? preAllocCount :
+                                                  MIN_ALLOC_COUNT;
+        fPreAllocMemArray   = preAllocStorage;
+
+        if (fReserveCount >= fCount && preAllocCount) {
+            fAllocCount = fReserveCount;
+            fMemArray = preAllocStorage;
+        } else {
+            fAllocCount = GrMax(fCount, fReserveCount);
+            fMemArray = GrMalloc(fAllocCount * sizeof(T));
+        }
+
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+        } else {
+            for (uint32_t i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray(const T* array, uint32_t count,
+             void* preAllocStorage, uint32_t preAllocCount) {
+
+        // for same reason as non-copying cons we allow NULL, 0 for prealloc
+        GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+        fCount              = count;
+        fReserveCount       = (preAllocCount > 0) ? preAllocCount :
+                                                    MIN_ALLOC_COUNT;
+        fPreAllocMemArray   = preAllocStorage;
+
+        if (fReserveCount >= fCount && preAllocCount) {
+            fAllocCount = fReserveCount;
+            fMemArray = preAllocStorage;
+        } else {
+            fAllocCount = GrMax(fCount, fReserveCount);
+            fMemArray = GrMalloc(fAllocCount * sizeof(T));
+        }
+
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array, sizeof(T) * fCount);
+        } else {
+            for (uint32_t i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+    }
+
+    GrTArray& operator =(const GrTArray& array) {
+        for (uint32_t i = 0; i < fCount; ++i) {
+            fItemArray[i].~T();
+        }
+        fCount = 0;
+        checkRealloc((int)array.count());
+        fCount = array.count();
+        if (DATA_TYPE) {
+            memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+        } else {
+            for (uint32_t i = 0; i < fCount; ++i) {
+                new (fItemArray + i) T(array[i]);
+            }
+        }
+        return *this;
+    }
+
+    ~GrTArray() {
+        for (uint32_t i = 0; i < fCount; ++i) {
+            fItemArray[i].~T();
+        }
+        if (fMemArray != fPreAllocMemArray) {
+            GrFree(fMemArray);
+        }
+    }
+
+    uint32_t count() const { return fCount; }
+
+    bool empty() const { return !fCount; }
+
+    T& push_back() {
+        checkRealloc(1);
+        new ((char*)fMemArray+sizeof(T)*fCount) T;
+        ++fCount;
+        return fItemArray[fCount-1];
+    }
+
+    void push_back_n(uint32_t n) {
+        checkRealloc(n);
+        for (uint32_t i = 0; i < n; ++i) {
+            new (fItemArray + fCount + i) T;
+        }
+        fCount += n;
+    }
+
+    void pop_back() {
+        GrAssert(0 != fCount);
+        --fCount;
+        fItemArray[fCount].~T();
+        checkRealloc(0);
+    }
+
+    void pop_back_n(uint32_t n) {
+        GrAssert(fCount >= n);
+        fCount -= n;
+        for (uint32_t i = 0; i < n; ++i) {
+            fItemArray[i].~T();
+        }
+        checkRealloc(0);
+    }
+
+    // pushes or pops from the back to resize
+    void resize_back(uint32_t newCount) {
+        if (newCount > fCount) {
+            push_back_n(newCount - fCount);
+        } else if (newCount < fCount) {
+            pop_back_n(fCount - newCount);
+        }
+    }
+
+    T& operator[] (uint32_t i) {
+        GrAssert(i < fCount);
+        return fItemArray[i];
+    }
+
+    const T& operator[] (uint32_t i) const {
+        GrAssert(i < fCount);
+        return fItemArray[i];
+    }
+
+    T& front() { GrAssert(fCount); return fItemArray[0];}
+
+    const T& front() const { GrAssert(fCount); return fItemArray[0];}
+
+    T& back() { GrAssert(fCount); return fItemArray[fCount - 1];}
+
+    const T& back() const { GrAssert(fCount); return fItemArray[fCount - 1];}
+
+    T& fromBack(uint32_t i) {
+        GrAssert(i < fCount);
+        return fItemArray[fCount - i - 1];
+    }
+
+    const T& fromBack(uint32_t i) const {
+        GrAssert(i < fCount);
+        return fItemArray[fCount - i - 1];
+    }
+
+private:
+    static const uint32_t MIN_ALLOC_COUNT = 8;
+
+    inline void checkRealloc(int32_t delta) {
+        GrAssert(-delta <= (int32_t)fCount);
+
+        uint32_t newCount = fCount + delta;
+        uint32_t fNewAllocCount = fAllocCount;
+
+        if (newCount > fAllocCount) {
+            fNewAllocCount = GrMax(newCount + ((newCount + 1) >> 1),
+                                   fReserveCount);
+        } else if (newCount < fAllocCount / 3) {
+            fNewAllocCount = GrMax(fAllocCount / 2, fReserveCount);
+        }
+
+        if (fNewAllocCount != fAllocCount) {
+
+            fAllocCount = fNewAllocCount;
+            char* fNewMemArray;
+
+            if (fAllocCount == fReserveCount && NULL != fPreAllocMemArray) {
+                fNewMemArray = (char*) fPreAllocMemArray;
+            } else {
+                fNewMemArray = (char*) GrMalloc(fAllocCount*sizeof(T));
+            }
+
+            if (DATA_TYPE) {
+                memcpy(fNewMemArray, fMemArray, fCount * sizeof(T));
+            } else {
+                for (uint32_t i = 0; i < fCount; ++i) {
+                    new (fNewMemArray + sizeof(T) * i) T(fItemArray[i]);
+                    fItemArray[i].~T();
+                }
+            }
+
+            if (fMemArray != fPreAllocMemArray) {
+                GrFree(fMemArray);
+            }
+            fMemArray = fNewMemArray;
+        }
+    }
+
+    uint32_t fReserveCount;
+    uint32_t fCount;
+    uint32_t fAllocCount;
+    void*    fPreAllocMemArray;
+    union {
+        T*       fItemArray;
+        void*    fMemArray;
+    };
+};
+
+#endif
+
diff --git a/gpu/include/GrTBSearch.h b/gpu/include/GrTBSearch.h
new file mode 100644
index 0000000..264ccb0
--- /dev/null
+++ b/gpu/include/GrTBSearch.h
@@ -0,0 +1,53 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTBSearch_DEFINED
+#define GrTBSearch_DEFINED
+
+template <typename ELEM, typename KEY>
+int GrTBSearch(const ELEM array[], int count, KEY target) {
+    GrAssert(count >= 0);
+    if (0 == count) {
+        // we should insert it at 0
+        return ~0;
+    }
+    
+    int high = count - 1;
+    int low = 0;
+    while (high > low) {
+        int index = (low + high) >> 1;
+        if (LT(array[index], target)) {
+            low = index + 1;
+        } else {
+            high = index;
+        }
+    }
+    
+    // check if we found it
+    if (EQ(array[high], target)) {
+        return high;
+    }
+    
+    // now return the ~ of where we should insert it
+    if (LT(array[high], target)) {
+        high += 1;
+    }
+    return ~high;
+}
+
+#endif
+
diff --git a/gpu/include/GrTDArray.h b/gpu/include/GrTDArray.h
new file mode 100644
index 0000000..092242e
--- /dev/null
+++ b/gpu/include/GrTDArray.h
@@ -0,0 +1,222 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTDArray_DEFINED
+#define GrTDArray_DEFINED
+
+#include "GrTypes.h"
+
+static int GrInitialArrayAllocationCount() {
+    return 4;
+}
+
+static int GrNextArrayAllocationCount(int count) {
+    return count + ((count + 1) >> 1);
+}
+
+template <typename T> class GrTDArray {
+public:
+    GrTDArray() : fArray(NULL), fAllocated(0), fCount(0) {}
+    GrTDArray(const GrTDArray& src) {
+        fCount = fAllocated = src.fCount;
+        fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+        memcpy(fArray, src.fArray, fCount * sizeof(T));
+    }
+    ~GrTDArray() {
+        if (fArray) {
+            GrFree(fArray);
+        }
+    }
+
+    bool isEmpty() const { return 0 == fCount; }
+    int count() const { return fCount; }
+
+    const T& at(int index) const {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        return fArray[index];
+    }
+    T& at(int index) {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        return fArray[index];
+    }
+
+    const T& operator[](int index) const { return this->at(index); }
+    T& operator[](int index) { return this->at(index); }
+
+    GrTDArray& operator=(const GrTDArray& src) {
+        if (fAllocated < src.fCount) {
+            fAllocated = src.fCount;
+            GrFree(fArray);
+            fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+        }
+        fCount = src.fCount;
+        memcpy(fArray, src.fArray, fCount * sizeof(T));
+        return *this;
+    }
+
+    void reset() {
+        if (fArray) {
+            GrFree(fArray);
+            fArray = NULL;
+        }
+        fAllocated = fCount = 0;
+    }
+
+    T* begin() const { return fArray; }
+    T* end() const { return fArray + fCount; }
+    T* back() const { GrAssert(fCount); return fArray + (fCount - 1); } 
+
+    T* prepend() {
+        this->growAt(0);
+        return fArray;
+    }
+
+    T* append() {
+        this->growAt(fCount);
+        return fArray + fCount - 1;
+    }
+
+    /**
+     *  index may be [0..count], so that you can insert at the end (like append)
+     */
+    T* insert(int index) {
+        GrAssert((unsigned)index <= (unsigned)fCount);
+        this->growAt(index);
+        return fArray + index;
+    }
+
+    void remove(int index) {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        fCount -= 1;
+        if (index < fCount) {
+            int remaining = fCount - index;
+            memmove(fArray + index, fArray + index + 1, remaining * sizeof(T));
+        }
+    }
+
+    void removeShuffle(int index) {
+        GrAssert((unsigned)index < (unsigned)fCount);
+        fCount -= 1;
+        if (index < fCount) {
+            memmove(fArray + index, fArray + fCount, sizeof(T));
+        }
+    }
+
+    // Utility iterators
+
+    /**
+     *  Calls GrFree() on each element. Assumes each is NULL or was allocated
+     *  with GrMalloc().
+     */
+    void freeAll() {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            GrFree(*curr);
+        }
+        this->reset();
+    }
+
+    /**
+     *  Calls delete on each element. Assumes each is NULL or was allocated
+     *  with new.
+     */
+    void deleteAll() {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            delete *curr;
+        }
+        this->reset();
+    }
+
+    /**
+     *  Calls GrSafeUnref() on each element. Assumes each is NULL or is a
+     *  subclass of GrRefCnt.
+     */
+    void unrefAll() {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            GrSafeUnref(*curr);
+        }
+        this->reset();
+    }
+
+    void visit(void visitor(T&)) const {
+        T* stop = this->end();
+        for (T* curr = this->begin(); curr < stop; curr++) {
+            if (*curr) {
+                visitor(*curr);
+            }
+        }
+    }
+
+    int find(const T& elem) const {
+        int count = this->count();
+        T* curr = this->begin();
+        for (int i = 0; i < count; i++) {
+            if (elem == curr[i]) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    friend bool operator==(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+        return a.count() == b.count() &&
+               (0 == a.count() ||
+                0 == memcmp(a.begin(), b.begin(), a.count() * sizeof(T)));
+    }
+    friend bool operator!=(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+        return !(a == b);
+    }
+
+private:
+    T*  fArray;
+    int fAllocated, fCount;
+
+    // growAt will increment fCount, reallocate fArray (as needed), and slide
+    // the contents of fArray to make a hole for new data at index.
+    void growAt(int index) {
+        GrAssert(fCount <= fAllocated);
+        if (0 == fAllocated) {
+            fAllocated = GrInitialArrayAllocationCount();
+            fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+        } else if (fCount == fAllocated) {
+            fAllocated = GrNextArrayAllocationCount(fAllocated);
+            T* newArray = (T*)GrMalloc(fAllocated * sizeof(T));
+            memcpy(newArray, fArray, index * sizeof(T));
+            memcpy(newArray + index + 1, fArray + index,
+                   (fCount - index) * sizeof(T));
+            GrFree(fArray);
+            fArray = newArray;
+        } else {
+            // check that we're not just appending
+            if (index < fCount) {
+                memmove(fArray + index + 1, fArray + index,
+                        (fCount - index) * sizeof(T));
+            }
+        }
+        GrAssert(fCount < fAllocated);
+        fCount += 1;
+    }
+};
+
+extern void* GrTDArray_growAt(void*, int* allocated, int& count, int index,
+                              size_t);
+
+
+#endif
+
diff --git a/gpu/include/GrTHashCache.h b/gpu/include/GrTHashCache.h
new file mode 100644
index 0000000..510f9ab
--- /dev/null
+++ b/gpu/include/GrTHashCache.h
@@ -0,0 +1,226 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTHashCache_DEFINED
+#define GrTHashCache_DEFINED
+
+#include "GrTDArray.h"
+
+/**
+ *  Key needs
+ *      static bool EQ(const Entry&, const HashKey&);
+ *      static bool LT(const Entry&, const HashKey&);
+ *      uint32_t getHash() const;
+ *
+ *  Allows duplicate key entries but on find you may get
+ *  any of the duplicate entries returned.
+ */
+template <typename T, typename Key, size_t kHashBits> class GrTHashTable {
+public:
+    GrTHashTable() { Gr_bzero(fHash, sizeof(fHash)); }
+    ~GrTHashTable() {}
+
+    int count() const { return fSorted.count(); }
+    T*  find(const Key&) const;
+    // return true if key was unique when inserted.
+    bool insert(const Key&, T*);
+    void remove(const Key&, const T*);
+    T* removeAt(int index, uint32_t hash);
+    void removeAll();
+    void deleteAll();
+    void unrefAll();
+
+    /**
+     *  Return the index for the element, using a linear search.
+     */
+    int slowFindIndex(T* elem) const { return fSorted.find(elem); }
+
+#if GR_DEBUG
+    void validate() const;
+    bool contains(T*) const;
+#endif
+
+    // testing
+    const GrTDArray<T*>& getArray() const { return fSorted; }
+private:
+    enum {
+        kHashCount = 1 << kHashBits,
+        kHashMask  = kHashCount - 1
+    };
+    static unsigned hash2Index(uint32_t hash) {
+        hash ^= hash >> 16;
+        if (kHashBits <= 8) {
+            hash ^= hash >> 8;
+        }
+        return hash & kHashMask;
+    }
+
+    mutable T* fHash[kHashCount];
+    GrTDArray<T*> fSorted;
+
+    // search fSorted, and return the found index, or ~index of where it
+    // should be inserted
+    int searchArray(const Key&) const;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename T, typename Key, size_t kHashBits>
+int GrTHashTable<T, Key, kHashBits>::searchArray(const Key& key) const {
+    int count = fSorted.count();
+    if (0 == count) {
+        // we should insert it at 0
+        return ~0;
+    }
+
+    const T* const* array = fSorted.begin();
+    int high = count - 1;
+    int low = 0;
+    while (high > low) {
+        int index = (low + high) >> 1;
+        if (Key::LT(*array[index], key)) {
+            low = index + 1;
+        } else {
+            high = index;
+        }
+    }
+
+    // check if we found it
+    if (Key::EQ(*array[high], key)) {
+        // above search should have found the first occurrence if there
+        // are multiple.
+        GrAssert(0 == high || Key::LT(*array[high - 1], key));
+        return high;
+    }
+
+    // now return the ~ of where we should insert it
+    if (Key::LT(*array[high], key)) {
+        high += 1;
+    }
+    return ~high;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+T* GrTHashTable<T, Key, kHashBits>::find(const Key& key) const {
+    int hashIndex = hash2Index(key.getHash());
+    T* elem = fHash[hashIndex];
+
+    if (NULL == elem || !Key::EQ(*elem, key)) {
+        // bsearch for the key in our sorted array
+        int index = this->searchArray(key);
+        if (index < 0) {
+            return NULL;
+        }
+        elem = fSorted[index];
+        // update the hash
+        fHash[hashIndex] = elem;
+    }
+    return elem;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+bool GrTHashTable<T, Key, kHashBits>::insert(const Key& key, T* elem) {
+    int index = this->searchArray(key);
+    bool first = index < 0;
+    if (first) {
+        // turn it into the actual index
+        index = ~index;
+    }
+    // add it to our array
+    *fSorted.insert(index) = elem;
+    // update our hash table (overwrites any dupe's position in the hash)
+    fHash[hash2Index(key.getHash())] = elem;
+    return first;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::remove(const Key& key, const T* elem) {
+    int index = hash2Index(key.getHash());
+    if (fHash[index] == elem) {
+        fHash[index] = NULL;
+    }
+
+    // remove from our sorted array
+    index = this->searchArray(key);
+    GrAssert(index >= 0);
+    // if there are multiple matches searchArray will give us the first match
+    // march forward until we find elem.
+    while (elem != fSorted[index]) {
+        ++index;
+        GrAssert(index < fSorted.count());
+    }
+    GrAssert(elem == fSorted[index]);
+    fSorted.remove(index);
+}
+
+template <typename T, typename Key, size_t kHashBits>
+T* GrTHashTable<T, Key, kHashBits>::removeAt(int elemIndex, uint32_t hash) {
+    int hashIndex = hash2Index(hash);
+    if (fHash[hashIndex] == fSorted[elemIndex]) {
+        fHash[hashIndex] = NULL;
+    }
+    // remove from our sorted array
+    T* elem = fSorted[elemIndex];
+    fSorted.remove(elemIndex);
+    return elem;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::removeAll() {
+    fSorted.reset();
+    Gr_bzero(fHash, sizeof(fHash));
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::deleteAll() {
+    fSorted.deleteAll();
+    Gr_bzero(fHash, sizeof(fHash));
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::unrefAll() {
+    fSorted.unrefAll();
+    Gr_bzero(fHash, sizeof(fHash));
+}
+
+#if GR_DEBUG
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::validate() const {
+    for (size_t i = 0; i < GR_ARRAY_COUNT(fHash); i++) {
+        if (fHash[i]) {
+            unsigned hashIndex = hash2Index(Key::GetHash(*fHash[i]));
+            GrAssert(hashIndex == i);
+        }
+    }
+
+    int count = fSorted.count();
+    for (int i = 1; i < count; i++) {
+        GrAssert(Key::LT(*fSorted[i - 1], *fSorted[i]) ||
+                 Key::EQ(*fSorted[i - 1], *fSorted[i]));
+    }
+}
+
+template <typename T, typename Key, size_t kHashBits>
+bool GrTHashTable<T, Key, kHashBits>::contains(T* elem) const {
+    int index = fSorted.find(elem);
+    return index >= 0;
+}
+
+#endif
+
+#endif
+
diff --git a/gpu/include/GrTLList.h b/gpu/include/GrTLList.h
new file mode 100644
index 0000000..1f59635
--- /dev/null
+++ b/gpu/include/GrTLList.h
@@ -0,0 +1,61 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTLList_DEFINED
+#define GrTLList_DEFINED
+
+#include "GrNoncopyable.h"
+
+template <typename T> class GrTLList : GrNoncopyable {
+public:
+    class Entry {
+        Entry*  fPrev;
+        Entry*  fNext;
+    };
+
+    GrTLList() : fHead(NULL), fTail(NULL) {}
+#if GR_DEBUG
+    ~GrTLList() {
+        GrAssert(NULL == fHead);
+        GrAssert(NULL == ftail);
+    }
+#endif
+
+    T*  head() const { return fHead; }
+    T*  tail() const { return fTail; }
+    
+    void addToHead(T*);
+    void addToTail(T*);
+    void removeFromList(T*);
+
+private:
+    Entry*  fHead;
+    Entry*  fTail;
+
+    friend class Entry;
+};
+
+
+class Parent {
+    GrTDLList<Child>    fList;
+};
+
+class Child : public GrTLList::Entry<Child> {
+};
+
+#endif
+
diff --git a/gpu/include/GrTextContext.h b/gpu/include/GrTextContext.h
new file mode 100644
index 0000000..6b7446b
--- /dev/null
+++ b/gpu/include/GrTextContext.h
@@ -0,0 +1,67 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextContext_DEFINED
+#define GrTextContext_DEFINED
+
+#include "GrGlyph.h"
+#include "GrGpuVertex.h"
+
+class GrContext;
+class GrTextStrike;
+class GrFontScaler;
+
+class GrTextContext {
+public:
+    GrTextContext(GrContext*, const GrMatrix* extMatrix = NULL);
+    ~GrTextContext();
+
+    void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
+                         GrFontScaler*);
+
+    void flush();   // optional; automatically called by destructor
+
+private:
+    GrContext*      fContext;
+    GrDrawTarget*   fDrawTarget;
+
+    GrMatrix        fExtMatrix;
+    GrFontScaler*   fScaler;
+    GrTextStrike*   fStrike;
+
+    inline void flushGlyphs();
+
+    enum {
+        kMinRequestedGlyphs      = 1,
+        kDefaultRequestedGlyphs  = 64,
+        kMinRequestedVerts       = kMinRequestedGlyphs * 4,
+        kDefaultRequestedVerts   = kDefaultRequestedGlyphs * 4,
+    };
+
+    GrGpuTextVertex* fVertices;
+    
+    int32_t     fMaxVertices;
+    GrTexture*  fCurrTexture;
+    int         fCurrVertex;
+
+    GrIRect     fClipRect;
+    GrMatrix    fOrigViewMatrix;    // restore previous viewmatrix
+};
+
+#endif
+
+
diff --git a/gpu/include/GrTextStrike.h b/gpu/include/GrTextStrike.h
new file mode 100644
index 0000000..abafa57
--- /dev/null
+++ b/gpu/include/GrTextStrike.h
@@ -0,0 +1,119 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextStrike_DEFINED
+#define GrTextStrike_DEFINED
+
+#include "GrAllocPool.h"
+#include "GrFontScaler.h"
+#include "GrTHashCache.h"
+#include "GrPoint.h"
+#include "GrGlyph.h"
+
+class GrAtlasMgr;
+class GrFontCache;
+class GrGpu;
+class GrFontPurgeListener;
+
+/**
+ *  The textcache maps a hostfontscaler instance to a dictionary of
+ *  glyphid->strike
+ */
+class GrTextStrike {
+public:
+    GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrAtlasMgr*);
+    ~GrTextStrike();
+
+    const GrKey* getFontScalerKey() const { return fFontScalerKey; }
+    GrFontCache* getFontCache() const { return fFontCache; }
+
+    inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
+    bool getGlyphAtlas(GrGlyph*, GrFontScaler*);
+
+    // testing
+    int countGlyphs() const { return fCache.getArray().count(); }
+    const GrGlyph* glyphAt(int index) const {
+        return fCache.getArray()[index];
+    }
+    GrAtlas* getAtlas() const { return fAtlas; }
+
+public:
+    // for LRU
+    GrTextStrike*   fPrev;
+    GrTextStrike*   fNext;
+
+private:
+    class Key;
+    GrTHashTable<GrGlyph, Key, 7> fCache;
+    const GrKey* fFontScalerKey;
+    GrTAllocPool<GrGlyph> fPool;
+
+    GrFontCache*    fFontCache;
+    GrAtlasMgr*     fAtlasMgr;
+    GrAtlas*        fAtlas;     // linklist
+
+    GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
+    // returns true if after the purge, the strike is empty
+    bool purgeAtlasAtY(GrAtlas* atlas, int yCoord);
+
+    friend class GrFontCache;
+};
+
+class GrFontCache {
+public:
+    GrFontCache(GrGpu*);
+    ~GrFontCache();
+
+    inline GrTextStrike* getStrike(GrFontScaler*);
+
+    void freeAll();
+    void abandonAll();
+
+    void purgeExceptFor(GrTextStrike*);
+
+    // testing
+    int countStrikes() const { return fCache.getArray().count(); }
+    const GrTextStrike* strikeAt(int index) const {
+        return fCache.getArray()[index];
+    }
+    GrTextStrike* getHeadStrike() const { return fHead; }
+
+#if GR_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+
+private:
+    friend class GrFontPurgeListener;
+
+    class Key;
+    GrTHashTable<GrTextStrike, Key, 8> fCache;
+    // for LRU
+    GrTextStrike* fHead;
+    GrTextStrike* fTail;
+
+    GrGpu*      fGpu;
+    GrAtlasMgr* fAtlasMgr;
+
+    
+    GrTextStrike* generateStrike(GrFontScaler*, const Key&);
+    inline void detachStrikeFromList(GrTextStrike*);
+};
+
+#endif
+
diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h
new file mode 100644
index 0000000..71a58e6
--- /dev/null
+++ b/gpu/include/GrTexture.h
@@ -0,0 +1,213 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTexture_DEFINED
+#define GrTexture_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrTexture;
+
+/**
+ * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
+ * A context's render target is set by setRenderTarget(). Render targets are
+ * created by a createTexture with the kRenderTarget_TextureFlag flag. 
+ * Additionally, the rendering destination set in the underlying 3D API at the
+ * time of GrContext's creation can be retrieved by calling 
+ * currentRenderTarget() after creation before any calles to setRenderTarget().
+ */
+class GrRenderTarget : public GrRefCnt {
+public:
+    /**
+     * @return the width of the rendertarget
+     */
+    virtual uint32_t width() const = 0;
+    /**
+     * @return the height of the rendertarget
+     */
+    virtual uint32_t height() const = 0;
+    
+    /**
+     * @return the texture associated with the rendertarget, may be NULL.
+     */
+    GrTexture* asTexture() {return fTexture;}
+
+protected:
+    GrRenderTarget(GrTexture* texture) : fTexture(texture) {}
+    GrTexture* fTexture;
+};
+
+class GrTexture : public GrRefCnt {
+public:
+    enum PixelConfig {
+        kUnknown_PixelConfig,
+        kAlpha_8_PixelConfig,
+        kIndex_8_PixelConfig,
+        kRGB_565_PixelConfig,
+        kRGBA_4444_PixelConfig, //!< premultiplied
+        kRGBA_8888_PixelConfig, //!< premultiplied
+        kRGBX_8888_PixelConfig, //!< treat the alpha channel as opaque
+    };
+    static size_t BytesPerPixel(PixelConfig);
+    static bool PixelConfigIsOpaque(PixelConfig);
+
+protected:
+    GrTexture(uint32_t contentWidth,
+              uint32_t contentHeight,
+              uint32_t allocWidth,
+              uint32_t allocHeight,
+              PixelConfig config) : 
+                fAllocWidth(allocWidth), 
+                fAllocHeight(allocHeight),
+                fContentWidth(contentWidth), 
+                fContentHeight(contentHeight),
+                fConfig(config) {
+                    // only make sense if alloc size is pow2
+                    fShiftFixedX = 31 - Gr_clz(allocWidth);
+                    fShiftFixedY = 31 - Gr_clz(allocHeight);
+                }
+public:
+    virtual ~GrTexture();
+    
+    /**
+     * Retrieves the width of the content area of the texture. Reflects the
+     * width passed to GrGpu::createTexture().
+     * 
+     * @return the width in texels
+     */
+    uint32_t contentWidth() const { return fContentWidth; }
+    /**
+     * Retrieves the height of the content area of the texture. Reflects the
+     * height passed to GrGpu::createTexture().
+     * 
+     * @return the height in texels
+     */
+    uint32_t contentHeight() const { return fContentHeight; }
+
+    /**
+     * Retrieves the texture width actually allocated in texels.
+     *
+     * @return the width in texels
+     */
+    uint32_t allocWidth() const { return fAllocWidth; }
+    /**
+     * Retrieves the texture height actually allocated in texels.
+     *
+     * @return the height in texels
+     */
+    uint32_t allocHeight() const { return fAllocHeight; }
+
+    /**
+     * Convert from texels to normalized texture coords for POT textures
+     * only.
+     */
+    GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fAllocWidth));
+                                               return x >> fShiftFixedX; }
+    GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fAllocHeight));
+                                               return y >> fShiftFixedY; }
+
+    /** 
+     * Retrieves the pixel config specified when the texture was created.
+     */
+    PixelConfig config() const { return fConfig; }
+
+    /**
+     *  The number of bytes used by the texture
+     */
+    size_t sizeInBytes() const {
+        return fAllocWidth * fAllocHeight * BytesPerPixel(fConfig);
+    }
+
+    /**
+     * Updates a subrectangle of texels in the texture.
+     *
+     * @param x       left edge of rectangle to update
+     * @param y       top edge of rectangle to update
+     * @param width   width of rectangle to update
+     * @param height  height of rectangle to update
+     * @param srcData width*height texels of data in same format that was used
+     *                at texture creation.
+     */
+    virtual void uploadTextureData(uint32_t x,
+                                   uint32_t y,
+                                   uint32_t width,
+                                   uint32_t height,
+                                   const void* srcData) = 0;
+    /**
+     * Indicates that GPU context in which this texture was created is destroyed
+     * and that Ganesh should not attempt to free the texture with the 
+     * underlying API.
+     */
+    virtual void abandon() = 0;
+
+    /**
+     * Queries whether the texture was created as a render target.
+     *
+     * Use asRenderTarget() to use the texture as a render target if this 
+     * returns true.
+     *
+     * @return true if the texture was created as a render target.
+     */
+    virtual bool isRenderTarget() const = 0;
+
+    /**
+     * Retrieves the render target underlying this texture that can be passed to
+     * GrGpu::setRenderTarget().
+     *
+     * If isRenderTarget() is false then the returned handle is undefined.
+     *
+     * @return    handle to render target or undefined if the texture is not a
+     *            render target
+     */
+    virtual GrRenderTarget* asRenderTarget() = 0;
+
+    /**
+     * Removes the "rendertargetness" from a texture. This may or may not
+     * actually do anything with the underlying 3D API.
+     */
+    virtual void removeRenderTarget() = 0;
+
+    /**
+     *  Return the native ID or handle to the texture, depending on the
+     *  platform. e.g. on opengl, return the texture ID.
+     */
+    virtual intptr_t getTextureHandle() = 0;
+
+#if GR_DEBUG
+    void validate() const {
+        this->INHERITED::validate();
+    }
+#else
+    void validate() const {}
+#endif
+    
+private:    
+    uint32_t fAllocWidth;
+    uint32_t fAllocHeight;
+    uint32_t fContentWidth;
+    uint32_t fContentHeight;
+    // these two shift a fixed-point value into normalized coordinates
+    // for this texture if the texture is power of two sized.
+    int      fShiftFixedX;
+    int      fShiftFixedY;
+    PixelConfig fConfig;
+
+    typedef GrRefCnt INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrTextureCache.h b/gpu/include/GrTextureCache.h
new file mode 100644
index 0000000..e3d4f0a
--- /dev/null
+++ b/gpu/include/GrTextureCache.h
@@ -0,0 +1,289 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextureCache_DEFINED
+#define GrTextureCache_DEFINED
+
+#include "GrTypes.h"
+#include "GrTHashCache.h"
+
+class GrTexture;
+
+// return true if a<b, or false if b<a
+//
+#define RET_IF_LT_OR_GT(a, b)   \
+    do {                        \
+        if ((a) < (b)) {        \
+            return true;        \
+        }                       \
+        if ((b) < (a)) {        \
+            return false;       \
+        }                       \
+    } while (0)
+
+/**
+ *  Helper class for GrTextureCache, the Key is used to identify src data for
+ *  a texture. It is identified by 2 32bit data fields which can hold any
+ *  data (uninterpreted by the cache) and a width/height.
+ */
+class GrTextureKey {
+public:
+    enum {
+        kHashBits   = 7,
+        kHashCount  = 1 << kHashBits,
+        kHashMask   = kHashCount - 1
+    };
+
+    GrTextureKey(uint32_t p0, uint32_t p1, uint16_t width, uint16_t height) {
+        fP0 = p0;
+        fP1 = p1;
+        fP2 = width | (height << 16);
+        GR_DEBUGCODE(fHashIndex = -1);
+    }
+
+    GrTextureKey(const GrTextureKey& src) {
+        fP0 = src.fP0;
+        fP1 = src.fP1;
+        fP2 = src.fP2;
+        finalize(src.fPrivateBits);
+    }
+
+    //!< returns hash value [0..kHashMask] for the key
+    int hashIndex() const { return fHashIndex; }
+
+    friend bool operator==(const GrTextureKey& a, const GrTextureKey& b) {
+        GR_DEBUGASSERT(-1 != a.fHashIndex && -1 != b.fHashIndex);
+        return a.fP0 == b.fP0 && a.fP1 == b.fP1 && a.fP2 == b.fP2 && 
+               a.fPrivateBits == b.fPrivateBits;
+    }
+
+    friend bool operator!=(const GrTextureKey& a, const GrTextureKey& b) {
+        GR_DEBUGASSERT(-1 != a.fHashIndex && -1 != b.fHashIndex);
+        return !(a == b);
+    }
+
+    friend bool operator<(const GrTextureKey& a, const GrTextureKey& b) {
+        RET_IF_LT_OR_GT(a.fP0, b.fP0);
+        RET_IF_LT_OR_GT(a.fP1, b.fP1);
+        RET_IF_LT_OR_GT(a.fP2, b.fP2);
+        return a.fPrivateBits < b.fPrivateBits;
+    }
+    
+private:
+    void finalize(uint32_t privateBits) { 
+        fPrivateBits = privateBits;
+        this->computeHashIndex();
+    }
+    
+    uint16_t width() const { return fP2 & 0xffff; }
+    uint16_t height() const { return (fP2 >> 16); }
+    
+    static uint32_t rol(uint32_t x) {
+        return (x >> 24) | (x << 8);
+    }
+    static uint32_t ror(uint32_t x) {
+        return (x >> 8) | (x << 24);
+    }
+    static uint32_t rohalf(uint32_t x) {
+        return (x >> 16) | (x << 16);
+    }
+    
+    void computeHashIndex() {
+        uint32_t hash = fP0 ^ rol(fP1) ^ ror(fP2) ^ rohalf(fPrivateBits);
+        // this way to mix and reduce hash to its index may have to change
+        // depending on how many bits we allocate to the index
+        hash ^= hash >> 16;
+        hash ^= hash >> 8;
+        fHashIndex = hash & kHashMask;
+    }
+
+    uint32_t    fP0;
+    uint32_t    fP1;
+    uint32_t    fP2;
+    uint32_t    fPrivateBits;
+
+    // this is computed from the fP... fields
+    int         fHashIndex;
+    
+    friend class GrContext;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class GrTextureEntry {
+public:
+    GrTexture* texture() const { return fTexture; }
+    const GrTextureKey& key() const { return fKey; }
+
+#if GR_DEBUG
+    GrTextureEntry* next() const { return fNext; }
+    GrTextureEntry* prev() const { return fPrev; }
+#endif
+
+#if GR_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+
+private:
+    GrTextureEntry(const GrTextureKey& key, GrTexture* texture);
+    ~GrTextureEntry();
+
+    bool isLocked() const { return fLockCount != 0; }
+    void lock() { ++fLockCount; }
+    void unlock() {
+        GrAssert(fLockCount > 0);
+        --fLockCount;
+    }
+
+    GrTextureKey    fKey;
+    GrTexture*      fTexture;
+
+    // track if we're in use, used when we need to purge
+    // we only purge unlocked entries
+    int fLockCount;
+
+    // we're a dlinklist
+    GrTextureEntry* fPrev;
+    GrTextureEntry* fNext;
+
+    friend class GrTextureCache;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "GrTHashCache.h"
+
+/**
+ *  Cache of GrTexture objects.
+ *
+ *  These have a corresponding GrTextureKey, built from 96bits identifying the
+ *  texture/bitmap.
+ *
+ *  The cache stores the entries in a double-linked list, which is its LRU.
+ *  When an entry is "locked" (i.e. given to the caller), it is moved to the
+ *  head of the list. If/when we must purge some of the entries, we walk the
+ *  list backwards from the tail, since those are the least recently used.
+ *
+ *  For fast searches, we maintain a sorted array (based on the GrTextureKey)
+ *  which we can bsearch. When a new entry is added, it is inserted into this
+ *  array.
+ *
+ *  For even faster searches, a hash is computed from the Key. If there is
+ *  a collision between two keys with the same hash, we fall back on the
+ *  bsearch, and update the hash to reflect the most recent Key requested.
+ */
+class GrTextureCache {
+public:
+    GrTextureCache(int maxCount, size_t maxBytes);
+    ~GrTextureCache();  // uses kFreeTexture_DeleteMode
+
+    /**
+     *  Search for an entry with the same Key. If found, "lock" it and return it.
+     *  If not found, return null.
+     */
+    GrTextureEntry* findAndLock(const GrTextureKey&);
+
+    /**
+     *  Create a new entry, based on the specified key and texture, and return
+     *  its "locked" entry.
+     *
+     *  Ownership of the texture is transferred to the Entry, which will unref()
+     *  it when we are purged or deleted.
+     */
+    GrTextureEntry* createAndLock(const GrTextureKey&, GrTexture*);
+    
+    /**
+     * Detach removes an entry from the cache. This prevents the entry from 
+     * being found by a subsequent findAndLock() until it is reattached. The 
+     * entry still counts against the cache's budget and should be reattached
+     * when exclusive access is no longer needed.
+     */
+    void detach(GrTextureEntry*);
+    
+    /**
+     * Reattaches a texture to the cache and unlocks it. Allows it to be found 
+     * by a subsequent findAndLock or be purged (provided its lock count is 
+     * now 0.)
+     */
+    void reattachAndUnlock(GrTextureEntry*);
+
+    /**
+     *  When done with an entry, call unlock(entry) on it, which returns it to
+     *  a purgable state.
+     */
+    void unlock(GrTextureEntry*);
+
+    enum DeleteMode {
+        kFreeTexture_DeleteMode,
+        kAbandonTexture_DeleteMode
+    };
+    void deleteAll(DeleteMode);
+
+#if GR_DEBUG
+    void validate() const;
+#else
+    void validate() const {}
+#endif
+
+private:
+    void internalDetach(GrTextureEntry*, bool);
+    void attachToHead(GrTextureEntry*, bool);
+    void purgeAsNeeded();   // uses kFreeTexture_DeleteMode
+
+    class Key;
+    GrTHashTable<GrTextureEntry, Key, 8> fCache;
+
+    // manage the dlink list
+    GrTextureEntry* fHead;
+    GrTextureEntry* fTail;
+
+    // our budget, used in purgeAsNeeded()
+    const int fMaxCount;
+    const size_t fMaxBytes;
+
+    // our current stats, related to our budget
+    int fEntryCount;
+    size_t fEntryBytes;
+    int fClientDetachedCount;
+    size_t fClientDetachedBytes;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+    class GrAutoTextureCacheValidate {
+    public:
+        GrAutoTextureCacheValidate(GrTextureCache* cache) : fCache(cache) {
+            cache->validate();
+        }
+        ~GrAutoTextureCacheValidate() {
+            fCache->validate();
+        }
+    private:
+        GrTextureCache* fCache;
+    };
+#else
+    class GrAutoTextureCacheValidate {
+    public:
+        GrAutoTextureCacheValidate(GrTextureCache*) {}
+    };
+#endif
+
+#endif
+
diff --git a/gpu/include/GrTouchGesture.h b/gpu/include/GrTouchGesture.h
new file mode 100644
index 0000000..03f970b
--- /dev/null
+++ b/gpu/include/GrTouchGesture.h
@@ -0,0 +1,56 @@
+#ifndef GrTouchGesture_DEFINED
+#define GrTouchGesture_DEFINED
+
+#include "GrTypes.h"
+#include "SkTDArray.h"
+#include "SkMatrix.h"
+
+#include "FlingState.h"
+
+class GrTouchGesture {
+public:
+    GrTouchGesture();
+    ~GrTouchGesture();
+
+    void touchBegin(void* owner, float x, float y);
+    void touchMoved(void* owner, float x, float y);
+    void touchEnd(void* owner);
+    void reset();
+
+    const SkMatrix& localM();
+    const SkMatrix& globalM() const { return fGlobalM; }
+
+private:
+    enum State {
+        kEmpty_State,
+        kTranslate_State,
+        kZoom_State,
+    };
+
+    struct Rec {
+        void*   fOwner;
+        float   fStartX, fStartY;
+        float   fPrevX, fPrevY;
+        float   fLastX, fLastY;
+        SkMSec  fPrevT, fLastT;
+    };
+    SkTDArray<Rec> fTouches;
+
+    State    fState;
+    SkMatrix fLocalM, fGlobalM;
+    FlingState  fFlinger;
+    SkMSec  fLastUpT;
+    SkPoint fLastUpP;
+
+
+    void flushLocalM();
+    int findRec(void* owner) const;
+    void appendNewRec(void* owner, float x, float y);
+    float computePinch(const Rec&, const Rec&);
+    float limitTotalZoom(float scale) const;
+    bool handleDblTap(float, float);
+};
+
+#endif
+
+
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
new file mode 100644
index 0000000..a491295
--- /dev/null
+++ b/gpu/include/GrTypes.h
@@ -0,0 +1,142 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTypes_DEFINED
+#define GrTypes_DEFINED
+
+#include "GrConfig.h"
+
+#include <memory.h>
+#include <string.h>
+
+/**
+ *  Macro to round n up to the next multiple of 4, or return it unchanged if
+ *  n is already a multiple of 4
+ */
+#define GrALIGN4(n)     (((n) + 3) >> 2 << 2)
+#define GrIsALIGN4(n)   (((n) & 3) == 0)
+
+template <typename T> const T& GrMin(const T& a, const T& b) {
+	return (a < b) ? a : b;
+}
+
+template <typename T> const T& GrMax(const T& a, const T& b) {
+	return (b < a) ? a : b;
+}
+
+// compile time versions of min/max
+#define GR_CT_MAX(a, b) (((b) < (a)) ? (a) : (b))
+#define GR_CT_MIN(a, b) (((b) < (a)) ? (b) : (a))
+
+/**
+ *  divide, rounding up
+ */
+inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
+    return (x + (y-1)) / y;
+}
+
+/**
+ *  align up
+ */
+inline uint32_t GrUIAlignUp(uint32_t x, uint32_t alignment) {
+    return GrUIDivRoundUp(x, alignment) * alignment;
+}
+
+/**
+ * amount of pad needed to align up
+ */
+inline uint32_t GrUIAlignUpPad(uint32_t x, uint32_t alignment) {
+    return (alignment - x % alignment) % alignment;
+}
+
+/**
+ *  align down
+ */
+inline uint32_t GrUIAlignDown(uint32_t x, uint32_t alignment) {
+    return (x / alignment) * alignment;
+}
+
+/**
+ *  Count elements in an array
+ */
+#define GR_ARRAY_COUNT(array)  (sizeof(array) / sizeof(array[0]))
+
+//!< allocate a block of memory, will never return NULL
+extern void* GrMalloc(size_t bytes);
+
+//!< free block allocated by GrMalloc. ptr may be NULL
+extern void GrFree(void* ptr);
+
+static inline void Gr_bzero(void* dst, size_t size) {
+    memset(dst, 0, size);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Return the number of leading zeros in n
+ */
+extern int Gr_clz(uint32_t n);
+
+/**
+ *  Return true if n is a power of 2
+ */
+static inline bool GrIsPow2(unsigned n) {
+    return n && 0 == (n & (n - 1));
+}
+
+/**
+ *  Return the next power of 2 >= n.
+ */
+static inline uint32_t GrNextPow2(uint32_t n) {
+    return n ? (1 << (32 - Gr_clz(n - 1))) : 1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  16.16 fixed point type
+ */
+typedef int32_t GrFixed;
+
+#if GR_DEBUG
+
+static inline int16_t GrToS16(intptr_t x) {
+    GrAssert((int16_t)x == x);
+    return (int16_t)x;
+}
+
+#else
+
+#define GrToS16(x)  x
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Type used to describe format of vertices in arrays
+ * Values are defined in GrDrawTarget
+ */
+typedef uint16_t GrVertexLayout;
+
+///////////////////////////////////////////////////////////////////////////////
+
+// this is included only to make it easy to use this debugging facility
+#include "GrInstanceCounter.h"
+
+#endif
diff --git a/gpu/include/GrUserConfig.h b/gpu/include/GrUserConfig.h
new file mode 100644
index 0000000..2e6f391
--- /dev/null
+++ b/gpu/include/GrUserConfig.h
@@ -0,0 +1,57 @@
+#ifndef GrUserConfig_DEFINED
+#define GrUserConfig_DEFINED
+
+#if defined(GR_USER_CONFIG_FILE)
+    #error "default user config pulled in but GR_USER_CONFIG_FILE is defined."
+#endif
+
+#if 0
+    #undef GR_RELEASE
+    #undef GR_DEBUG
+    #define GR_RELEASE  0
+    #define GR_DEBUG    1
+#endif
+
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+//#define GR_FORCE_GLCHECKERR   1
+
+/*
+ *  The default 32bit pixel config for texture upload is GL_RGBA. If your
+ *  bitmaps map to a different GL enum, specify that with this define.
+ */
+//#define SK_GL_32BPP_COLOR_FORMAT  GL_RGBA
+
+/*
+ *  To diagnose texture cache performance, define this to 1 if you want to see
+ *  a log statement everytime we upload an image to create a texture.
+ */
+//#define GR_DUMP_TEXTURE_UPLOAD    1
+
+////////////////////////////////////////////////////////////////////////////////
+// Decide Ganesh types
+
+#define GR_SCALAR_IS_FIXED          0
+#define GR_SCALAR_IS_FLOAT          1
+
+#define GR_TEXT_SCALAR_IS_USHORT    0
+#define GR_TEXT_SCALAR_IS_FIXED     0
+#define GR_TEXT_SCALAR_IS_FLOAT     1
+
+#endif
+
+
diff --git a/gpu/include/GrVertexBuffer.h b/gpu/include/GrVertexBuffer.h
new file mode 100644
index 0000000..5e83de9
--- /dev/null
+++ b/gpu/include/GrVertexBuffer.h
@@ -0,0 +1,92 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrVertexBuffer_DEFINED
+#define GrVertexBuffer_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrVertexBuffer : public GrRefCnt {
+protected:
+    GrVertexBuffer(uint32_t sizeInBytes, bool dynamic) : 
+             fSizeInBytes(sizeInBytes),
+             fDynamic(dynamic) {}
+public:
+    virtual ~GrVertexBuffer() {}
+    
+    /**
+     Retrieves the size of the vertex buffer
+
+     @return the size of the vertex buffer in bytes
+     */
+    uint32_t size() { return fSizeInBytes; }
+
+    /**
+     Retrieves whether the vertex buffer was created with the dynamic flag
+
+     @return true if the vertex buffer was created with the dynamic flag
+     */
+    bool dynamic() const { return fDynamic; }
+
+    /**
+     Indicates that GPU context in which this veretx buffer was created is 
+     destroyed and that Ganesh should not attempt to free the texture with the
+     underlying API.
+     */
+    virtual void abandon() = 0;
+
+    /**
+     Locks the vertex buffer to be written by the CPU.
+     
+     The previous content of the vertex buffer is invalidated. It is an error to
+     draw whil the buffer is locked.  It is an error to call lock on an already
+     locked vertex buffer.
+     
+     @return a pointer to the vertex data or NULL if the lock fails.
+     */
+    virtual void* lock() = 0;
+
+    /** 
+     Unlocks the vertex buffer. 
+     
+     The pointer returned by the previous lock call will no longer be valid.
+     */
+    virtual void unlock() = 0;
+
+    /** 
+     Queries whether the vertex buffer has been locked.
+     
+     @return true if the vertex buffer is locked, false otherwise.
+     */
+    virtual bool isLocked() const = 0;
+
+    /**
+     Updates the vertex buffer data. 
+     
+     The size of the vertex buffer will be preserved. However, only the updated
+     region will have defined contents.
+
+     @return returns true if the update succeeds, false otherwise.
+     */
+    virtual bool updateData(const void* src, uint32_t srcSizeInBytes) = 0;
+
+private:
+    uint32_t fSizeInBytes;
+    bool     fDynamic;
+};
+
+#endif
diff --git a/gpu/include/GrVertexBufferAllocPool.h b/gpu/include/GrVertexBufferAllocPool.h
new file mode 100644
index 0000000..6a781aa
--- /dev/null
+++ b/gpu/include/GrVertexBufferAllocPool.h
@@ -0,0 +1,141 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrVertexBufferAllocPool_DEFINED
+#define GrVertexBufferAllocPool_DEFINED
+
+#include "GrNoncopyable.h"
+#include "GrTDArray.h"
+#include "GrTArray.h"
+
+class GrVertexBuffer;
+class GrGpu;
+
+/**
+ * A pool of vertices in vertex buffers tied to a GrGpu.
+ *
+ * The pool has an alloc() function that returns a pointer into a locked
+ * vertex buffer. A client can release() if it has over-allocated.
+ *
+ * At creation time a minimum VB size can be specified. Additionally,
+ * a number of vertex buffers to preallocate can be specified. These will
+ * be allocated at the min size and kept until the pool is destroyed.
+ */
+class GrVertexBufferAllocPool : GrNoncopyable {
+public:
+    /**
+     * Constructor
+     *
+     * @param gpu               The GrGpu used to create the vertex buffers.
+     * @param bufferSize        The size of created VBs (unless an alloc request
+     *                          exceeds this size in which case a larger VB is
+     *                          created). This value is clamped to some
+     *                          reasonable minimum.
+     * @param preallocBufferCnt The pool will allocate this number of VBs at
+     *                          bufferSize and keep them until it is destroyed.
+     */
+     GrVertexBufferAllocPool(GrGpu* gpu,
+                             size_t   bufferSize = 0,
+                             int preallocBufferCnt = 0);
+    ~GrVertexBufferAllocPool();
+
+    /**
+     * Ensures all VBs are unlocked. Call before using to draw.
+     */
+    void unlock();
+
+    /**
+     *  Frees all vertex data that has been allocated with alloc().
+     */
+    void reset();
+
+    /**
+     * Returns a block of memory bytes size big. The vertex buffer
+     * containing the memory is returned in buffer.
+     *
+     * @param layout       specifies type of vertices to allocate space for
+     * @param vertexCount  number of vertices to allocate space for
+     * @param buffer       returns the vertex buffer that will hold the
+     *                     vertices.
+     * @param startVertex  returns the offset into buffer of the first vertex.
+     *                     In units of the size of a vertex using layout param.
+     * @return pointer to first vertex.
+     */
+    void* alloc(GrVertexLayout layout,
+                uint32_t vertexCount,
+                GrVertexBuffer** buffer,
+                uint32_t* startVertex);
+
+    /**
+     * Gets the number of vertices that can be allocated without changing VBs.
+     * This means either the last VB returned by alloc() if the last alloc did
+     * not exhaust it. If that VB was exhausted by the last alloc or alloc hasn't
+     * been called since reset() then it will be the number of vertices that
+     * would fit in an available preallocated VB. If no preallocated VB
+     * is available then it returns 0 since the next alloc would force a new
+     * VB to be created.
+     */
+    int currentBufferVertices(GrVertexLayout layout) const;
+
+    /**
+     * Gets the number of preallocated buffers that are yet to be used.
+     */
+    int preallocatedBuffersRemaining() const;
+
+    /**
+     * Gets the number of vertices that can fit in a  preallocated vertex buffer.
+     * Zero if no preallocated buffers.
+     */
+    int preallocatedBufferVertices(GrVertexLayout layout) const;
+
+    /**
+     * gets the number of preallocated vertex buffers
+     */
+    int preallocatedBufferCount() const;
+
+
+    /**
+     * Releases the most recently allocated bytes back to the pool.
+     */
+    void release(size_t bytes);
+
+    /**
+     * Gets the GrGpu that this pool is associated with.
+     */
+    GrGpu* getGpu() { return fGpu; }
+
+
+private:
+    struct BufferBlock {
+        size_t              fBytesFree;
+        GrVertexBuffer*     fVertexBuffer;
+    };
+
+    bool createBlock(size_t size);
+    void destroyBlock();
+
+    GrTArray<BufferBlock>       fBlocks;
+    GrTDArray<GrVertexBuffer*>  fPreallocBuffers;
+    int                         fPreallocBuffersInUse;
+    int                         fFirstPreallocBuffer;
+
+    size_t              fMinBlockSize;
+    GrGpu*              fGpu;
+    void*               fBufferPtr;
+};
+
+#endif
diff --git a/gpu/include/SkGpuCanvas.h b/gpu/include/SkGpuCanvas.h
new file mode 100644
index 0000000..e8e6e7a
--- /dev/null
+++ b/gpu/include/SkGpuCanvas.h
@@ -0,0 +1,72 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGpuCanvas_DEFINED
+#define SkGpuCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+class GrContext;
+
+/**
+ *  Subclass of canvas that creates devices compatible with the GrContext pass
+ *  to the canvas' constructor.
+ */
+class SkGpuCanvas : public SkCanvas {
+public:
+    /**
+     *  The GrContext object is reference counted. When passed to our 
+     *  constructor, its reference count is incremented. In our destructor, the 
+     *  GrGpu's reference count will be decremented.
+     */
+    explicit SkGpuCanvas(GrContext*);
+    virtual ~SkGpuCanvas();
+
+    /**
+     *  Return our GrContext instance
+     */
+    GrContext* context() const { return fContext; }
+
+    /**
+     *  Override from SkCanvas. Returns true, and if not-null, sets size to
+     *  be the width/height of our viewport.
+     */
+    virtual bool getViewport(SkIPoint* size) const;
+
+    /**
+     *  Override from SkCanvas. Returns a new device of the correct subclass,
+     *  as determined by the GrGpu passed to our constructor.
+     */
+    virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
+                                   bool isOpaque, bool isLayer);
+
+#if 0
+    virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
+                          SaveFlags flags = kARGB_ClipLayer_SaveFlag) {
+        return this->save(flags);
+    }
+#endif
+    
+private:
+    GrContext* fContext;
+
+    typedef SkCanvas INHERITED;
+};
+
+#endif
+
+
diff --git a/gpu/include/SkGr.h b/gpu/include/SkGr.h
new file mode 100644
index 0000000..4e9801f
--- /dev/null
+++ b/gpu/include/SkGr.h
@@ -0,0 +1,238 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGr_DEFINED
+#define SkGr_DEFINED
+
+#include <stddef.h>
+
+// tetrark headers
+#include "GrConfig.h"
+#include "GrContext.h"
+#include "GrFontScaler.h"
+#include "GrPathIter.h"
+#include "GrClipIterator.h"
+
+// skia headers
+#include "SkBitmap.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRegion.h"
+#include "SkShader.h"
+
+#if (GR_DEBUG && defined(SK_RELEASE)) || (GR_RELEASE && defined(SK_DEBUG))
+//    #error "inconsistent GR_DEBUG and SK_DEBUG"
+#endif
+
+#if GR_SCALAR_IS_FIXED
+    #ifdef SK_SCALAR_IS_FIXED
+        #define SK_SCALAR_IS_GR_SCALAR  1
+    #else
+        #define SK_SCALAR_IS_GR_SCALAR  0
+    #endif
+    #define SkScalarToGrScalar(x)       SkScalarToFixed(x)
+
+#elif GR_SCALAR_IS_FLOAT
+
+    #ifdef SK_SCALAR_IS_FLOAT
+        #define SK_SCALAR_IS_GR_SCALAR  1
+    #else
+        #define SK_SCALAR_IS_GR_SCALAR  0
+    #endif
+    #define SkScalarToGrScalar(x)       SkScalarToFloat(x)
+
+#else 
+    #error "Ganesh scalar type not defined"
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Sk to Gr Type conversions
+
+// Verify that SkPoint and GrPoint are compatible if using the same scalar type
+#if 0/*SK_SCALAR_IS_GR_SCALAR*/
+    GR_STATIC_ASSERT(sizeof(SkPoint) == sizeof(GrPoint));
+    GR_STATIC_ASSERT(offsetof(SkPoint,fX) == offsetof(GrPoint,fX)));
+    GR_STATIC_ASSERT(offsetof(SkPoint,fY) == offsetof(GrPoint,fY)));
+#endif
+
+GR_STATIC_ASSERT((int)GrSamplerState::kClamp_WrapMode == (int)SkShader::kClamp_TileMode);
+GR_STATIC_ASSERT((int)GrSamplerState::kRepeat_WrapMode ==(
+                 int)SkShader::kRepeat_TileMode);
+GR_STATIC_ASSERT((int)GrSamplerState::kMirror_WrapMode == 
+                 (int)SkShader::kMirror_TileMode);
+
+#define sk_tile_mode_to_grwrap(X) ((GrSamplerState::WrapMode)(X))
+
+GR_STATIC_ASSERT((int)GrGpu::kZero_BlendCoeff == (int)SkXfermode::kZero_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kOne_BlendCoeff  == (int)SkXfermode::kOne_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kSC_BlendCoeff   == (int)SkXfermode::kSC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kISC_BlendCoeff  == (int)SkXfermode::kISC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kDC_BlendCoeff   == (int)SkXfermode::kDC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kIDC_BlendCoeff  == (int)SkXfermode::kIDC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kSA_BlendCoeff   == (int)SkXfermode::kSA_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kISA_BlendCoeff  == (int)SkXfermode::kISA_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kDA_BlendCoeff   == (int)SkXfermode::kDA_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kIDA_BlendCoeff  == (int)SkXfermode::kIDA_Coeff);
+
+#define sk_blend_to_grblend(X) ((GrGpu::BlendCoeff)(X))
+
+GR_STATIC_ASSERT((int)SkPath::kMove_Verb  == (int)GrPathIter::kMove_Command);
+GR_STATIC_ASSERT((int)SkPath::kLine_Verb  == (int)GrPathIter::kLine_Command);
+GR_STATIC_ASSERT((int)SkPath::kQuad_Verb  == (int)GrPathIter::kQuadratic_Command);
+GR_STATIC_ASSERT((int)SkPath::kCubic_Verb == (int)GrPathIter::kCubic_Command);
+GR_STATIC_ASSERT((int)SkPath::kClose_Verb == (int)GrPathIter::kClose_Command);
+GR_STATIC_ASSERT((int)SkPath::kDone_Verb  == (int)GrPathIter::kEnd_Command);
+
+#define sk_path_verb_to_gr_path_command(X) ((GrPathIter::Command)(X))
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkColorPriv.h"
+
+static inline GrRect Sk2Gr(const SkRect& src) {
+    return GrRect(SkScalarToGrScalar(src.fLeft),
+                  SkScalarToGrScalar(src.fTop),
+                  SkScalarToGrScalar(src.fRight),
+                  SkScalarToGrScalar(src.fBottom));
+}
+
+class SkGr {
+public:
+    static inline SkIRect& SetIRect(SkIRect* dst, const GrIRect& src) {
+        GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
+        memcpy(dst, &src, sizeof(*dst));
+        return *dst;
+    }
+    
+    static inline GrIRect& SetIRect(GrIRect* dst, const SkIRect& src) {
+        GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
+        memcpy(dst, &src, sizeof(*dst));
+        return *dst;
+    }
+    
+    /**
+     *  Convert the SkBitmap::Config to the corresponding PixelConfig, or
+     *  kUnknown_PixelConfig if the conversion cannot be done.
+     */
+    static GrTexture::PixelConfig BitmapConfig2PixelConfig(SkBitmap::Config,
+                                                        bool isOpaque);
+
+    static GrTexture::PixelConfig Bitmap2PixelConfig(const SkBitmap& bm) {
+        return BitmapConfig2PixelConfig(bm.config(), bm.isOpaque());
+    }
+
+    static void SkMatrix2GrMatrix(const SkMatrix& m, GrMatrix* g) {
+        g->setAll(SkScalarToGrScalar(m[0]),
+                  SkScalarToGrScalar(m[1]),
+                  SkScalarToGrScalar(m[2]),
+                  SkScalarToGrScalar(m[3]),
+                  SkScalarToGrScalar(m[4]),
+                  SkScalarToGrScalar(m[5]),
+                  SkScalarToGrScalar(m[6]),
+                  SkScalarToGrScalar(m[7]),
+                  SkScalarToGrScalar(m[8]));
+    }
+    
+    static GrColor SkColor2GrColor(SkColor c) {
+        SkPMColor pm = SkPreMultiplyColor(c);
+        unsigned r = SkGetPackedR32(pm);
+        unsigned g = SkGetPackedG32(pm);
+        unsigned b = SkGetPackedB32(pm);
+        unsigned a = SkGetPackedA32(pm);
+        return GrColorPackRGBA(r, g, b, a);
+    }
+
+    /**
+     *  This abandons all texture caches (for bitmaps and text) associated with
+     *  the gpu, and frees any associated skia caches. It differs from
+     *  deleteAllTextures in that it assumes that the gpu has lots its context,
+     *  and thus the associated HW textures are no longer valid
+     */
+    static void AbandonAllTextures(GrContext*);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Classes
+
+class SkGrPathIter : public GrPathIter {
+public:
+    SkGrPathIter(const SkPath& path) : fIter(path, false), fPath(path) {}
+    virtual Command next(GrPoint pts[]);
+    virtual Command next();
+    virtual void rewind();
+    virtual ConvexHint hint() const;
+private:
+    
+#if !SK_SCALAR_IS_GR_SCALAR
+    SkPoint             fPoints[4];
+#endif
+    SkPath::Iter        fIter;
+    const SkPath&       fPath;
+};
+
+class SkGrClipIterator : public GrClipIterator {
+public:
+    void reset(const SkRegion& clip) {
+        fIter.reset(clip);
+        this->invalidateBoundsCache();
+    }
+    
+    // overrides
+    
+    virtual bool isDone() { return fIter.done(); }
+    virtual void getRect(GrIRect* rect) {
+        SkGr::SetIRect(rect, fIter.rect());
+    }
+    virtual void next() { fIter.next(); }
+    virtual void rewind() { fIter.rewind(); }
+    virtual void computeBounds(GrIRect* bounds);
+
+private:
+    SkRegion::Iterator fIter;
+};
+
+class SkGlyphCache;
+
+class SkGrFontScaler : public GrFontScaler {
+public:
+    explicit SkGrFontScaler(SkGlyphCache* strike);
+    virtual ~SkGrFontScaler();
+
+    // overrides
+    virtual const GrKey* getKey();
+    virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds);
+    virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+                                     int rowBytes, void* image);
+    virtual bool getGlyphPath(uint16_t glyphID, GrPath*);
+
+private:
+    SkGlyphCache* fStrike;
+    GrKey*  fKey;
+//    DECLARE_INSTANCE_COUNTER(SkGrFontScaler);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper functions
+
+GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx, 
+                                            GrTextureKey* key,
+                                            const GrSamplerState& sampler,
+                                            const SkBitmap& bitmap);
+
+void sk_gr_set_paint(GrContext* ctx, const SkPaint& paint, bool justAlpha = false);
+
+#endif
diff --git a/gpu/include/SkGrTexturePixelRef.h b/gpu/include/SkGrTexturePixelRef.h
new file mode 100644
index 0000000..1f5133f
--- /dev/null
+++ b/gpu/include/SkGrTexturePixelRef.h
@@ -0,0 +1,50 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGrTexturePixelRef_DEFINED
+#define SkGrTexturePixelRef_DEFINED
+
+#include "SkPixelRef.h"
+#include "GrGpu.h"
+
+class SkGrTexturePixelRef : public SkPixelRef {
+public:
+            SkGrTexturePixelRef(GrTexture*);
+    virtual ~SkGrTexturePixelRef();
+
+    // override from SkPixelRef
+    virtual SkGpuTexture* getTexture() { return (SkGpuTexture*)fTexture; }
+
+protected:
+    // override from SkPixelRef
+    virtual void* onLockPixels(SkColorTable** ptr) {
+        if (ptr) {
+            *ptr = NULL;
+        }
+        return NULL;
+    }
+
+    // override from SkPixelRef
+    virtual void onUnlockPixels() {}
+
+private:
+    GrTexture*  fTexture;
+    typedef SkPixelRef INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/SkUIView.h b/gpu/include/SkUIView.h
new file mode 100644
index 0000000..5e12e00
--- /dev/null
+++ b/gpu/include/SkUIView.h
@@ -0,0 +1,64 @@
+#import <UIKit/UIKit.h>
+
+#include "SkMatrix.h"
+#include "FlingState.h"
+
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+
+class SkOSWindow;
+class SkEvent;
+
+@interface SkUIView : UIView <UIAccelerometerDelegate> {
+    BOOL fRedrawRequestPending;
+    SkOSWindow* fWind;
+    SkMatrix    fMatrix, fLocalMatrix;
+    bool        fNeedGestureEnded;
+
+    SkMatrix    fRotateMatrix;
+
+    float       fFirstPinchX, fFirstPinchY;
+    bool        fNeedFirstPinch;
+
+    float       fZoomAroundX, fZoomAroundY;
+    bool        fZoomAround;
+
+    FlingState  fFlingState;
+
+    GrAnimateFloat  fWarpState;
+    bool            fUseWarp;
+
+    struct {
+        EAGLContext*    fContext;
+        GLuint          fRenderbuffer;
+        GLuint          fStencilbuffer;
+        GLuint          fFramebuffer;
+        GLint           fWidth;
+        GLint           fHeight;
+    } fGL;
+    
+    UILabel* fTitleLabel;
+
+    enum Backend {
+        kGL_Backend,
+        kRaster_Backend,
+    };
+
+    // these are visible to DetailViewController
+    Backend fBackend;
+    bool    fComplexClip;
+}
+
+@property (nonatomic, assign) SkOSWindow *fWind;
+@property (nonatomic, retain) UILabel* fTitleLabel;
+@property (nonatomic, assign) Backend fBackend;
+@property (nonatomic, assign) bool fComplexClip;
+@property (nonatomic, assign, setter=setWarpState) bool fUseWarp;
+
+- (void)setSkTitle:(const char*)title;
+- (void)postInvalWithRect:(const SkIRect*)rectOrNil;
+- (BOOL)onHandleEvent:(const SkEvent&)event;
+
+@end
+