diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 9df7105..caba6ef 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -1,498 +1,498 @@
-/*
-    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 "GrTextureCache.h"
-#include "GrPaint.h"
-
-class GrFontCache;
-class GrPathIter;
-class GrVertexBufferAllocPool;
-class GrIndexBufferAllocPool;
-class GrInOrderDrawBuffer;
-class GrPathRenderer;
-
-class GrContext : public GrRefCnt {
-public:
-    /**
-     * Creates a GrContext from within a 3D context.
-     */
-    static GrContext* Create(GrGpu::Engine engine,
-                             GrGpu::Platform3DContext context3D);
-
-    /**
-     *  Helper to create a opengl-shader based context
-     */
-    static GrContext* CreateGLShaderContext();
-
-    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();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Textures
-
-    /**
-     *  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);
-
-    /**
-     *  Returns true if the specified use of an indexed texture is supported.
-     */
-    bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);
-
-    /**
-     *  Return the current texture cache limits.
-     *
-     *  @param maxTextures If non-null, returns maximum number of textures that
-     *                     can be held in the cache.
-     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
-     *                         texture memory that can be held in the cache.
-     */
-    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
-
-    /**
-     *  Specify the texture cache limits. If the current cache exceeds either
-     *  of these, it will be purged (LRU) to keep the cache within these limits.
-     *
-     *  @param maxTextures The maximum number of textures that can be held in
-     *                     the cache.
-     *  @param maxTextureBytes The maximum number of bytes of texture memory
-     *                         that can be held in the cache.
-     */
-    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
-
-    /**
-     *  Return the max width or height of a texture supported by the current gpu
-     */
-    int getMaxTextureDimension();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Render targets
-
-    /**
-     * Wraps an externally-created rendertarget in a GrRenderTarget.
-     * @param platformRenderTarget  3D API-specific render target identifier
-     *                              e.g. in GL platforamRenderTarget is an FBO 
-     *                              id.
-     * @param stencilBits           the number of stencil bits that the render
-     *                              target has.
-     * @param width                 width of the render target.
-     * @param height                height of the render target.
-     */
-    GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
-                                               int stencilBits,
-                                               int width, int height);
-
-    /**
-     * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
-     * viewport state from the underlying 3D API and wraps it in a
-     * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
-     * underlying object in its destructor and it is up to caller to guarantee
-     * that it remains valid while the GrRenderTarget is used.
-     *
-     * @return the newly created GrRenderTarget
-     */
-    GrRenderTarget* createRenderTargetFrom3DApiState() {
-        return fGpu->createRenderTargetFrom3DApiState();
-    }
-
-    /**
-     * Sets the render target.
-     * @param target    the render target to set. (should not be NULL.)
-     */
-    void setRenderTarget(GrRenderTarget* target);
-
-    /**
-     * Gets the current render target.
-     * @return the currently bound render target. Should never be NULL.
-     */
-    const GrRenderTarget* getRenderTarget() const;
-    GrRenderTarget* getRenderTarget();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Matrix state
-
-    /**
-     * Gets the current transformation matrix.
-     * @return the current matrix.
-     */
-    const GrMatrix& getMatrix() const;
-
-    /**
-     * Sets the transformation matrix.
-     * @param m the matrix to set.
-     */
-    void setMatrix(const GrMatrix& m);
-
-    /**
-     * Concats the current matrix. The passed matrix is applied before the
-     * current matrix.
-     * @param m the matrix to concat.
-     */
-    void concatMatrix(const GrMatrix& m) const;
-
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Clip state
-    /**
-     * Gets the current clip.
-     * @return the current clip.
-     */
-    const GrClip& getClip() const { return fGpu->getClip(); }
-
-    /**
-     * Sets the clip.
-     * @param clip  the clip to set.
-     */
-    void setClip(const GrClip& clip);
-
-    /**
-     * Convenience method for setting the clip to a rect.
-     * @param rect  the rect to set as the new clip.
-     */
-    void setClip(const GrIRect& rect);
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Draws
-
-    /**
-     *  Erase the entire render target, ignoring any clips
-     */
-    void eraseColor(GrColor color);
-
-    /**
-     *  Draw everywhere (respecting the clip) with the paint.
-     */
-    void drawPaint(const GrPaint& paint);
-
-    /**
-     *  Draw the rect using a paint.
-     *  @param paint        describes how to color pixels.
-     *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
-     *                      the rect is mitered stroked based on strokeWidth. If
-     *                      strokeWidth == 0, then the stroke is always a single
-     *                      pixel thick.
-     *  @param matrix       Optional matrix applied to the rect. Applied before
-     *                      context's matrix or the paint's matrix.
-     *  The rects coords are used to access the paint (through texture matrix)
-     */
-    void drawRect(const GrPaint& paint,
-                  const GrRect&,
-                  GrScalar strokeWidth = -1,
-                  const GrMatrix* matrix = NULL);
-
-    /**
-     * Maps a rect of paint coordinates onto the a rect of destination
-     * coordinates. Each rect can optionally be transformed. The srcRect
-     * is stretched over the dstRect. The dstRect is transformed by the
-     * context's matrix and the srcRect is transformed by the paint's matrix.
-     * Additional optional matrices can be provided by parameters.
-     *
-     * @param paint     describes how to color pixels.
-     * @param dstRect   the destination rect to draw.
-     * @param srcRect   rect of paint coordinates to be mapped onto dstRect
-     * @param dstMatrix Optional matrix to transform dstRect. Applied before
-     *                  context's matrix.
-     * @param srcMatrix Optional matrix to transform srcRect Applied before
-     *                  paint's matrix.
-     */
-    void drawRectToRect(const GrPaint& paint,
-                        const GrRect& dstRect,
-                        const GrRect& srcRect,
-                        const GrMatrix* dstMatrix = NULL,
-                        const GrMatrix* srcMatrix = NULL);
-
-    /**
-     * Tessellates and draws a path.
-     *
-     * @param paint         describes how to color pixels.
-     * @param path          the path to draw
-     * @param fill          the path filling rule to use.
-     * @param translate     optional additional translation applied to the
-     *                      path.
-     */
-    void drawPath(const GrPaint& paint,
-                  GrPathIter* path,
-                  GrPathFill fill,
-                  const GrPoint* translate = NULL);
-    /**
-     * Draws vertices with a paint.
-     *
-     * @param   paint           describes how to color pixels.
-     * @param   primitiveType   primitives type to draw.
-     * @param   vertexCount     number of vertices.
-     * @param   positions       array of vertex positions, required.
-     * @param   texCoords       optional array of texture coordinates used
-     *                          to access the paint.
-     * @param   colors          optional array of per-vertex colors, supercedes
-     *                          the paint's color field.
-     * @param   indices         optional array of indices. If NULL vertices
-     *                          are drawn non-indexed.
-     * @param   indexCount      if indices is non-null then this is the
-     *                          number of indices.
-     */
-    void drawVertices(const GrPaint& paint,
-                      GrPrimitiveType primitiveType,
-                      int vertexCount,
-                      const GrPoint positions[],
-                      const GrPoint texs[],
-                      const GrColor colors[],
-                      const uint16_t indices[],
-                      int indexCount);
-
-    /**
-     * Similar to drawVertices but caller provides objects that convert to Gr
-     * types. The count of vertices is given by posSrc.
-     *
-     * @param   paint           describes how to color pixels.
-     * @param   primitiveType   primitives type to draw.
-     * @param   posSrc          Source of vertex positions. Must implement
-     *                              int count() const;
-     *                              void writeValue(int i, GrPoint* point) const;
-     *                          count returns the total number of vertices and
-     *                          writeValue writes a vertex position to point.
-     * @param   texSrc          optional, pass NULL to not use explicit tex
-     *                          coords. If present provides tex coords with
-     *                          method:
-     *                              void writeValue(int i, GrPoint* point) const;
-     * @param   texSrc          optional, pass NULL to not use per-vertex colors
-     *                          If present provides colors with method:
-     *                              void writeValue(int i, GrColor* point) const;
-     * @param   indices         optional, pass NULL for non-indexed drawing. If
-     *                          present supplies indices for indexed drawing
-     *                          with following methods:
-     *                              int count() const;
-     *                              void writeValue(int i, uint16_t* point) const;
-     *                          count returns the number of indices and
-     *                          writeValue supplies each index.
-     */
-    template <typename POS_SRC,
-              typename TEX_SRC,
-              typename COL_SRC,
-              typename IDX_SRC>
-    void drawCustomVertices(const GrPaint& paint,
-                            GrPrimitiveType primitiveType,
-                            const POS_SRC& posSrc,
-                            const TEX_SRC* texCoordSrc,
-                            const COL_SRC* colorSrc,
-                            const IDX_SRC* idxSrc);
-    /**
-     * To avoid the problem of having to create a typename for NULL parameters,
-     * these reduced versions of drawCustomVertices are provided.
-     */
-    template <typename POS_SRC>
-    void drawCustomVertices(const GrPaint& paint,
-                            GrPrimitiveType primitiveType,
-                            const POS_SRC& posSrc);
-    template <typename POS_SRC, typename TEX_SRC>
-    void drawCustomVertices(const GrPaint& paint,
-                            GrPrimitiveType primitiveType,
-                            const POS_SRC& posSrc,
-                            const TEX_SRC* texCoordSrc);
-    template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
-    void drawCustomVertices(const GrPaint& paint,
-                            GrPrimitiveType primitiveType,
-                            const POS_SRC& posSrc,
-                            const TEX_SRC* texCoordSrc,
-                            const COL_SRC* colorSrc);
-
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Misc.
-
-    /**
-     * 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);
-
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Statistics
-
-    void resetStats();
-
-    const GrGpu::Stats& getStats() const;
-
-    void printStats() const;
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Helpers
-
-    class AutoRenderTarget : ::GrNoncopyable {
-    public:
-        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
-            fContext = NULL;
-            fPrevTarget = context->getRenderTarget();
-            if (fPrevTarget != target) {
-                context->setRenderTarget(target);
-                fContext = context;
-            }
-        }
-        ~AutoRenderTarget() {
-            if (fContext) {
-                fContext->setRenderTarget(fPrevTarget);
-            }
-        }
-    private:
-        GrContext*      fContext;
-        GrRenderTarget* fPrevTarget;
-    };
-
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Functions intended for internal use only.
-    GrGpu* getGpu() { return fGpu; }
-    GrFontCache* getFontCache() { return fFontCache; }
-    GrDrawTarget* getTextTarget(const GrPaint& paint);
-    void flushText();
-    const GrIndexBuffer* getQuadIndexBuffer() const;
-
-private:
-    // used to keep track of when we need to flush the draw buffer
-    enum DrawCategory {
-        kBuffered_DrawCategory,      // last draw was inserted in draw buffer
-        kUnbuffered_DrawCategory,    // last draw was not inserted in the draw buffer
-        kText_DrawCategory           // text context was last to draw
-    };
-    DrawCategory fLastDrawCategory;
-
-    GrGpu*          fGpu;
-    GrTextureCache* fTextureCache;
-    GrFontCache*    fFontCache;
-    GrPathRenderer* fPathRenderer;
-
-    GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
-    GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
-    GrInOrderDrawBuffer*        fDrawBuffer;
-
-    GrContext(GrGpu* gpu);
-    void flushDrawBuffer();
-
-    static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
-
-    bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
-    
-    GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
-
-    void drawClipIntoStencil();
-};
-
-/**
- *  Save/restore the view-matrix in the context.
- */
-class GrAutoMatrix : GrNoncopyable {
-public:
-    GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
-        fMatrix = ctx->getMatrix();
-    }
-    GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
-        fMatrix = ctx->getMatrix();
-        ctx->setMatrix(matrix);
-    }
-    ~GrAutoMatrix() {
-        fContext->setMatrix(fMatrix);
-    }
-
-private:
-    GrContext*  fContext;
-    GrMatrix    fMatrix;
-};
-
-#endif
-
-#include "GrContext_impl.h"
+/*
+    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 "GrTextureCache.h"
+#include "GrPaint.h"
+
+class GrFontCache;
+class GrPathIter;
+class GrVertexBufferAllocPool;
+class GrIndexBufferAllocPool;
+class GrInOrderDrawBuffer;
+class GrPathRenderer;
+
+class GrContext : public GrRefCnt {
+public:
+    /**
+     * Creates a GrContext from within a 3D context.
+     */
+    static GrContext* Create(GrGpu::Engine engine,
+                             GrGpu::Platform3DContext context3D);
+
+    /**
+     *  Helper to create a opengl-shader based context
+     */
+    static GrContext* CreateGLShaderContext();
+
+    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();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Textures
+
+    /**
+     *  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);
+
+    /**
+     *  Returns true if the specified use of an indexed texture is supported.
+     */
+    bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);
+
+    /**
+     *  Return the current texture cache limits.
+     *
+     *  @param maxTextures If non-null, returns maximum number of textures that
+     *                     can be held in the cache.
+     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
+     *                         texture memory that can be held in the cache.
+     */
+    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
+
+    /**
+     *  Specify the texture cache limits. If the current cache exceeds either
+     *  of these, it will be purged (LRU) to keep the cache within these limits.
+     *
+     *  @param maxTextures The maximum number of textures that can be held in
+     *                     the cache.
+     *  @param maxTextureBytes The maximum number of bytes of texture memory
+     *                         that can be held in the cache.
+     */
+    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
+
+    /**
+     *  Return the max width or height of a texture supported by the current gpu
+     */
+    int getMaxTextureDimension();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Render targets
+
+    /**
+     * Wraps an externally-created rendertarget in a GrRenderTarget.
+     * @param platformRenderTarget  3D API-specific render target identifier
+     *                              e.g. in GL platforamRenderTarget is an FBO 
+     *                              id.
+     * @param stencilBits           the number of stencil bits that the render
+     *                              target has.
+     * @param width                 width of the render target.
+     * @param height                height of the render target.
+     */
+    GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
+                                               int stencilBits,
+                                               int width, int height);
+
+    /**
+     * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
+     * viewport state from the underlying 3D API and wraps it in a
+     * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
+     * underlying object in its destructor and it is up to caller to guarantee
+     * that it remains valid while the GrRenderTarget is used.
+     *
+     * @return the newly created GrRenderTarget
+     */
+    GrRenderTarget* createRenderTargetFrom3DApiState() {
+        return fGpu->createRenderTargetFrom3DApiState();
+    }
+
+    /**
+     * Sets the render target.
+     * @param target    the render target to set. (should not be NULL.)
+     */
+    void setRenderTarget(GrRenderTarget* target);
+
+    /**
+     * Gets the current render target.
+     * @return the currently bound render target. Should never be NULL.
+     */
+    const GrRenderTarget* getRenderTarget() const;
+    GrRenderTarget* getRenderTarget();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Matrix state
+
+    /**
+     * Gets the current transformation matrix.
+     * @return the current matrix.
+     */
+    const GrMatrix& getMatrix() const;
+
+    /**
+     * Sets the transformation matrix.
+     * @param m the matrix to set.
+     */
+    void setMatrix(const GrMatrix& m);
+
+    /**
+     * Concats the current matrix. The passed matrix is applied before the
+     * current matrix.
+     * @param m the matrix to concat.
+     */
+    void concatMatrix(const GrMatrix& m) const;
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Clip state
+    /**
+     * Gets the current clip.
+     * @return the current clip.
+     */
+    const GrClip& getClip() const { return fGpu->getClip(); }
+
+    /**
+     * Sets the clip.
+     * @param clip  the clip to set.
+     */
+    void setClip(const GrClip& clip);
+
+    /**
+     * Convenience method for setting the clip to a rect.
+     * @param rect  the rect to set as the new clip.
+     */
+    void setClip(const GrIRect& rect);
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Draws
+
+    /**
+     *  Erase the entire render target, ignoring any clips
+     */
+    void eraseColor(GrColor color);
+
+    /**
+     *  Draw everywhere (respecting the clip) with the paint.
+     */
+    void drawPaint(const GrPaint& paint);
+
+    /**
+     *  Draw the rect using a paint.
+     *  @param paint        describes how to color pixels.
+     *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
+     *                      the rect is mitered stroked based on strokeWidth. If
+     *                      strokeWidth == 0, then the stroke is always a single
+     *                      pixel thick.
+     *  @param matrix       Optional matrix applied to the rect. Applied before
+     *                      context's matrix or the paint's matrix.
+     *  The rects coords are used to access the paint (through texture matrix)
+     */
+    void drawRect(const GrPaint& paint,
+                  const GrRect&,
+                  GrScalar strokeWidth = -1,
+                  const GrMatrix* matrix = NULL);
+
+    /**
+     * Maps a rect of paint coordinates onto the a rect of destination
+     * coordinates. Each rect can optionally be transformed. The srcRect
+     * is stretched over the dstRect. The dstRect is transformed by the
+     * context's matrix and the srcRect is transformed by the paint's matrix.
+     * Additional optional matrices can be provided by parameters.
+     *
+     * @param paint     describes how to color pixels.
+     * @param dstRect   the destination rect to draw.
+     * @param srcRect   rect of paint coordinates to be mapped onto dstRect
+     * @param dstMatrix Optional matrix to transform dstRect. Applied before
+     *                  context's matrix.
+     * @param srcMatrix Optional matrix to transform srcRect Applied before
+     *                  paint's matrix.
+     */
+    void drawRectToRect(const GrPaint& paint,
+                        const GrRect& dstRect,
+                        const GrRect& srcRect,
+                        const GrMatrix* dstMatrix = NULL,
+                        const GrMatrix* srcMatrix = NULL);
+
+    /**
+     * Tessellates and draws a path.
+     *
+     * @param paint         describes how to color pixels.
+     * @param path          the path to draw
+     * @param fill          the path filling rule to use.
+     * @param translate     optional additional translation applied to the
+     *                      path.
+     */
+    void drawPath(const GrPaint& paint,
+                  GrPathIter* path,
+                  GrPathFill fill,
+                  const GrPoint* translate = NULL);
+    /**
+     * Draws vertices with a paint.
+     *
+     * @param   paint           describes how to color pixels.
+     * @param   primitiveType   primitives type to draw.
+     * @param   vertexCount     number of vertices.
+     * @param   positions       array of vertex positions, required.
+     * @param   texCoords       optional array of texture coordinates used
+     *                          to access the paint.
+     * @param   colors          optional array of per-vertex colors, supercedes
+     *                          the paint's color field.
+     * @param   indices         optional array of indices. If NULL vertices
+     *                          are drawn non-indexed.
+     * @param   indexCount      if indices is non-null then this is the
+     *                          number of indices.
+     */
+    void drawVertices(const GrPaint& paint,
+                      GrPrimitiveType primitiveType,
+                      int vertexCount,
+                      const GrPoint positions[],
+                      const GrPoint texs[],
+                      const GrColor colors[],
+                      const uint16_t indices[],
+                      int indexCount);
+
+    /**
+     * Similar to drawVertices but caller provides objects that convert to Gr
+     * types. The count of vertices is given by posSrc.
+     *
+     * @param   paint           describes how to color pixels.
+     * @param   primitiveType   primitives type to draw.
+     * @param   posSrc          Source of vertex positions. Must implement
+     *                              int count() const;
+     *                              void writeValue(int i, GrPoint* point) const;
+     *                          count returns the total number of vertices and
+     *                          writeValue writes a vertex position to point.
+     * @param   texSrc          optional, pass NULL to not use explicit tex
+     *                          coords. If present provides tex coords with
+     *                          method:
+     *                              void writeValue(int i, GrPoint* point) const;
+     * @param   texSrc          optional, pass NULL to not use per-vertex colors
+     *                          If present provides colors with method:
+     *                              void writeValue(int i, GrColor* point) const;
+     * @param   indices         optional, pass NULL for non-indexed drawing. If
+     *                          present supplies indices for indexed drawing
+     *                          with following methods:
+     *                              int count() const;
+     *                              void writeValue(int i, uint16_t* point) const;
+     *                          count returns the number of indices and
+     *                          writeValue supplies each index.
+     */
+    template <typename POS_SRC,
+              typename TEX_SRC,
+              typename COL_SRC,
+              typename IDX_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc,
+                            const TEX_SRC* texCoordSrc,
+                            const COL_SRC* colorSrc,
+                            const IDX_SRC* idxSrc);
+    /**
+     * To avoid the problem of having to create a typename for NULL parameters,
+     * these reduced versions of drawCustomVertices are provided.
+     */
+    template <typename POS_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc);
+    template <typename POS_SRC, typename TEX_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc,
+                            const TEX_SRC* texCoordSrc);
+    template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
+    void drawCustomVertices(const GrPaint& paint,
+                            GrPrimitiveType primitiveType,
+                            const POS_SRC& posSrc,
+                            const TEX_SRC* texCoordSrc,
+                            const COL_SRC* colorSrc);
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Misc.
+
+    /**
+     * 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);
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Statistics
+
+    void resetStats();
+
+    const GrGpu::Stats& getStats() const;
+
+    void printStats() const;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Helpers
+
+    class AutoRenderTarget : ::GrNoncopyable {
+    public:
+        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
+            fContext = NULL;
+            fPrevTarget = context->getRenderTarget();
+            if (fPrevTarget != target) {
+                context->setRenderTarget(target);
+                fContext = context;
+            }
+        }
+        ~AutoRenderTarget() {
+            if (fContext) {
+                fContext->setRenderTarget(fPrevTarget);
+            }
+        }
+    private:
+        GrContext*      fContext;
+        GrRenderTarget* fPrevTarget;
+    };
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Functions intended for internal use only.
+    GrGpu* getGpu() { return fGpu; }
+    GrFontCache* getFontCache() { return fFontCache; }
+    GrDrawTarget* getTextTarget(const GrPaint& paint);
+    void flushText();
+    const GrIndexBuffer* getQuadIndexBuffer() const;
+
+private:
+    // used to keep track of when we need to flush the draw buffer
+    enum DrawCategory {
+        kBuffered_DrawCategory,      // last draw was inserted in draw buffer
+        kUnbuffered_DrawCategory,    // last draw was not inserted in the draw buffer
+        kText_DrawCategory           // text context was last to draw
+    };
+    DrawCategory fLastDrawCategory;
+
+    GrGpu*          fGpu;
+    GrTextureCache* fTextureCache;
+    GrFontCache*    fFontCache;
+    GrPathRenderer* fPathRenderer;
+
+    GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
+    GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
+    GrInOrderDrawBuffer*        fDrawBuffer;
+
+    GrContext(GrGpu* gpu);
+    void flushDrawBuffer();
+
+    static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
+
+    bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
+    
+    GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
+
+    void drawClipIntoStencil();
+};
+
+/**
+ *  Save/restore the view-matrix in the context.
+ */
+class GrAutoMatrix : GrNoncopyable {
+public:
+    GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
+        fMatrix = ctx->getMatrix();
+    }
+    GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
+        fMatrix = ctx->getMatrix();
+        ctx->setMatrix(matrix);
+    }
+    ~GrAutoMatrix() {
+        fContext->setMatrix(fMatrix);
+    }
+
+private:
+    GrContext*  fContext;
+    GrMatrix    fMatrix;
+};
+
+#endif
+
+#include "GrContext_impl.h"
diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h
index c0a2107..fdcb2b1 100644
--- a/gpu/include/GrContext_impl.h
+++ b/gpu/include/GrContext_impl.h
@@ -1,135 +1,135 @@
-/*
-    Copyright 2011 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_impl_DEFINED
-#define GrContext_impl_DEFINED
-
-template <typename POS_SRC, typename TEX_SRC,
-          typename COL_SRC, typename IDX_SRC>
-inline void GrContext::drawCustomVertices(const GrPaint& paint,
-                                          GrPrimitiveType primitiveType,
-                                          const POS_SRC& posSrc,
-                                          const TEX_SRC* texCoordSrc,
-                                          const COL_SRC* colorSrc,
-                                          const IDX_SRC* idxSrc) {
-
-    GrVertexLayout layout = 0;
-
-    GrDrawTarget::AutoReleaseGeometry geo;
-
-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-
-    if (NULL != paint.getTexture()) {
-        if (NULL != texCoordSrc) {
-            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
-        } else {
-            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
-        }
-    }
-
-    if (NULL != colorSrc) {
-        layout |= GrDrawTarget::kColor_VertexLayoutBit;
-    }
-
-    int vertexCount = posSrc.count();
-    int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0;
-
-    if (!geo.set(target, layout, vertexCount, indexCount)) {
-        GrPrintf("Failed to get space for vertices!");
-        return;
-    }
-
-    int texOffsets[GrDrawTarget::kMaxTexCoords];
-    int colorOffset;
-    int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
-                                                        texOffsets,
-                                                        &colorOffset);
-    void* curVertex = geo.vertices();
-
-    for (int i = 0; i < vertexCount; ++i) {
-        posSrc.writeValue(i, (GrPoint*)curVertex);
-
-        if (texOffsets[0] > 0) {
-            texCoordSrc->writeValue(i, (GrPoint*)((intptr_t)curVertex + texOffsets[0]));
-        }
-        if (colorOffset > 0) {
-            colorSrc->writeValue(i, (GrColor*)((intptr_t)curVertex + colorOffset));
-        }
-        curVertex = (void*)((intptr_t)curVertex + vsize);
-    }
-
-    uint16_t* indices = (uint16_t*) geo.indices();
-    for (int i = 0; i < indexCount; ++i) {
-        idxSrc->writeValue(i, indices + i);
-    }
-
-    if (NULL == idxSrc) {
-        target->drawNonIndexed(primitiveType, 0, vertexCount);
-    } else {
-        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
-    }
-}
-
-class GrNullTexCoordSource {
-public:
-    void writeValue(int i, GrPoint* dstCoord) const { GrAssert(false); }
-};
-
-class GrNullColorSource {
-public:
-    void writeValue(int i, GrColor* dstColor) const { GrAssert(false); }
-};
-
-class GrNullIndexSource {
-public:
-    void writeValue(int i, uint16_t* dstIndex) const { GrAssert(false); }
-    int count() const { GrAssert(false); return 0; }
-};
-
-template <typename POS_SRC>
-inline void GrContext::drawCustomVertices(const GrPaint& paint,
-                                          GrPrimitiveType primitiveType,
-                                          const POS_SRC& posSrc) {
-    this->drawCustomVertices<POS_SRC,
-                             GrNullTexCoordSource,
-                             GrNullColorSource,
-                             GrNullIndexSource>(paint, primitiveType, posSrc,
-                                                NULL, NULL, NULL);
-}
-
-template <typename POS_SRC, typename TEX_SRC>
-inline void GrContext::drawCustomVertices(const GrPaint& paint,
-                                          GrPrimitiveType primitiveType,
-                                          const POS_SRC& posSrc,
-                                          const TEX_SRC* texCoordSrc) {
-    this->drawCustomVertices<POS_SRC, TEX_SRC,
-                             GrNullColorSource,
-                             GrNullIndexSource>(paint, primitiveType, posSrc,
-                                                texCoordSrc, NULL, NULL);
-}
-
-template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
-inline void GrContext::drawCustomVertices(const GrPaint& paint,
-                                          GrPrimitiveType primitiveType,
-                                          const POS_SRC& posSrc,
-                                          const TEX_SRC* texCoordSrc,
-                                          const COL_SRC* colorSrc) {
-    drawCustomVertices<POS_SRC, TEX_SRC, COL_SRC,
-                       GrNullIndexSource>(paint, primitiveType, posSrc, 
-                                          texCoordSrc, colorSrc, NULL);
-}
-
-#endif
+/*
+    Copyright 2011 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_impl_DEFINED
+#define GrContext_impl_DEFINED
+
+template <typename POS_SRC, typename TEX_SRC,
+          typename COL_SRC, typename IDX_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc,
+                                          const TEX_SRC* texCoordSrc,
+                                          const COL_SRC* colorSrc,
+                                          const IDX_SRC* idxSrc) {
+
+    GrVertexLayout layout = 0;
+
+    GrDrawTarget::AutoReleaseGeometry geo;
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (NULL != paint.getTexture()) {
+        if (NULL != texCoordSrc) {
+            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+        } else {
+            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+        }
+    }
+
+    if (NULL != colorSrc) {
+        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+    }
+
+    int vertexCount = posSrc.count();
+    int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0;
+
+    if (!geo.set(target, layout, vertexCount, indexCount)) {
+        GrPrintf("Failed to get space for vertices!");
+        return;
+    }
+
+    int texOffsets[GrDrawTarget::kMaxTexCoords];
+    int colorOffset;
+    int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+                                                        texOffsets,
+                                                        &colorOffset);
+    void* curVertex = geo.vertices();
+
+    for (int i = 0; i < vertexCount; ++i) {
+        posSrc.writeValue(i, (GrPoint*)curVertex);
+
+        if (texOffsets[0] > 0) {
+            texCoordSrc->writeValue(i, (GrPoint*)((intptr_t)curVertex + texOffsets[0]));
+        }
+        if (colorOffset > 0) {
+            colorSrc->writeValue(i, (GrColor*)((intptr_t)curVertex + colorOffset));
+        }
+        curVertex = (void*)((intptr_t)curVertex + vsize);
+    }
+
+    uint16_t* indices = (uint16_t*) geo.indices();
+    for (int i = 0; i < indexCount; ++i) {
+        idxSrc->writeValue(i, indices + i);
+    }
+
+    if (NULL == idxSrc) {
+        target->drawNonIndexed(primitiveType, 0, vertexCount);
+    } else {
+        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+    }
+}
+
+class GrNullTexCoordSource {
+public:
+    void writeValue(int i, GrPoint* dstCoord) const { GrAssert(false); }
+};
+
+class GrNullColorSource {
+public:
+    void writeValue(int i, GrColor* dstColor) const { GrAssert(false); }
+};
+
+class GrNullIndexSource {
+public:
+    void writeValue(int i, uint16_t* dstIndex) const { GrAssert(false); }
+    int count() const { GrAssert(false); return 0; }
+};
+
+template <typename POS_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc) {
+    this->drawCustomVertices<POS_SRC,
+                             GrNullTexCoordSource,
+                             GrNullColorSource,
+                             GrNullIndexSource>(paint, primitiveType, posSrc,
+                                                NULL, NULL, NULL);
+}
+
+template <typename POS_SRC, typename TEX_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc,
+                                          const TEX_SRC* texCoordSrc) {
+    this->drawCustomVertices<POS_SRC, TEX_SRC,
+                             GrNullColorSource,
+                             GrNullIndexSource>(paint, primitiveType, posSrc,
+                                                texCoordSrc, NULL, NULL);
+}
+
+template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
+inline void GrContext::drawCustomVertices(const GrPaint& paint,
+                                          GrPrimitiveType primitiveType,
+                                          const POS_SRC& posSrc,
+                                          const TEX_SRC* texCoordSrc,
+                                          const COL_SRC* colorSrc) {
+    drawCustomVertices<POS_SRC, TEX_SRC, COL_SRC,
+                       GrNullIndexSource>(paint, primitiveType, posSrc, 
+                                          texCoordSrc, colorSrc, NULL);
+}
+
+#endif
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
index 929b9ff..10c6d48 100644
--- a/gpu/include/GrDrawTarget.h
+++ b/gpu/include/GrDrawTarget.h
@@ -210,9 +210,9 @@
      * @param stage   the stage of the sampler to set
      * @param matrix  the matrix to concat
      */
-    void preConcatSamplerMatrix(int stage, const GrMatrix& matrix)  {
-        GrAssert(stage >= 0 && stage < kNumStages);
-        fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
+    void preConcatSamplerMatrix(int stage, const GrMatrix& matrix)  {
+        GrAssert(stage >= 0 && stage < kNumStages);
+        fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
     }
 
     /**
diff --git a/gpu/include/GrGeometryBuffer.h b/gpu/include/GrGeometryBuffer.h
index af6eed5..1447e73 100644
--- a/gpu/include/GrGeometryBuffer.h
+++ b/gpu/include/GrGeometryBuffer.h
@@ -1,116 +1,116 @@
-/*
- Copyright 2011 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 GrGeometryBuffer_DEFINED
-#define GrGeometryBuffer_DEFINED
-
-#include "GrRefCnt.h"
-
-/**
- * Parent class for vertex and index buffers
- */
-class GrGeometryBuffer : public GrRefCnt {
-public:
-    virtual ~GrGeometryBuffer() {}
-    
-    /**
-     * Retrieves the size of the buffer
-     *
-     * @return the size of the buffer in bytes
-     */
-    size_t size() const { return fSizeInBytes; }
-    
-    /**
-     *Retrieves whether the buffer was created with the dynamic flag
-     *
-     * @return true if the 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 buffer in the
-     * underlying API.
-     */
-    virtual void abandon() = 0;
-    
-    /**
-     * Locks the buffer to be written by the CPU.
-     * 
-     * The previous content of the buffer is invalidated. It is an error
-     * to draw from the buffer while it is locked. It is an error to call lock
-     * on an already locked buffer.
-     * 
-     * @return a pointer to the data or NULL if the lock fails.
-     */
-    virtual void* lock() = 0;
-    
-    /**
-     * Returns the same ptr that lock() returned at time of lock or NULL if the
-     * is not locked.
-     *
-     * @return ptr to locked buffer data or undefined if buffer is not locked.
-     */
-    virtual void* lockPtr() const = 0;
-    
-    /** 
-     * Unlocks the buffer. 
-     * 
-     * The pointer returned by the previous lock call will no longer be valid.
-     */
-    virtual void unlock() = 0;
-    
-    /** 
-     Queries whether the buffer has been locked.
-     
-     @return true if the buffer is locked, false otherwise.
-     */
-    virtual bool isLocked() const = 0;
-    
-    /**
-     * Updates the buffer data. 
-     *  
-     * The size of the buffer will be preserved. The src data will be 
-     * placed at the begining of the buffer and any remaining contents will
-     * be undefined.
-     * 
-     * @return returns true if the update succeeds, false otherwise.
-     */
-    virtual bool updateData(const void* src, size_t srcSizeInBytes) = 0;
-    
-    /**
-     * Updates a portion of the buffer data. 
-     * 
-     * The contents of the buffer outside the update region are preserved.
-     * 
-     * @return returns true if the update succeeds, false otherwise.
-     */
-    virtual bool updateSubData(const void* src, 
-                               size_t srcSizeInBytes, 
-                               size_t offset) = 0;
-protected:
-    GrGeometryBuffer(size_t sizeInBytes, bool dynamic) : 
-        fSizeInBytes(sizeInBytes),
-        fDynamic(dynamic) {}
-
-private:
-    size_t   fSizeInBytes;
-    bool     fDynamic;
-
-    typedef GrRefCnt INHERITED;
-};
-
-#endif
+/*
+ Copyright 2011 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 GrGeometryBuffer_DEFINED
+#define GrGeometryBuffer_DEFINED
+
+#include "GrRefCnt.h"
+
+/**
+ * Parent class for vertex and index buffers
+ */
+class GrGeometryBuffer : public GrRefCnt {
+public:
+    virtual ~GrGeometryBuffer() {}
+    
+    /**
+     * Retrieves the size of the buffer
+     *
+     * @return the size of the buffer in bytes
+     */
+    size_t size() const { return fSizeInBytes; }
+    
+    /**
+     *Retrieves whether the buffer was created with the dynamic flag
+     *
+     * @return true if the 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 buffer in the
+     * underlying API.
+     */
+    virtual void abandon() = 0;
+    
+    /**
+     * Locks the buffer to be written by the CPU.
+     * 
+     * The previous content of the buffer is invalidated. It is an error
+     * to draw from the buffer while it is locked. It is an error to call lock
+     * on an already locked buffer.
+     * 
+     * @return a pointer to the data or NULL if the lock fails.
+     */
+    virtual void* lock() = 0;
+    
+    /**
+     * Returns the same ptr that lock() returned at time of lock or NULL if the
+     * is not locked.
+     *
+     * @return ptr to locked buffer data or undefined if buffer is not locked.
+     */
+    virtual void* lockPtr() const = 0;
+    
+    /** 
+     * Unlocks the buffer. 
+     * 
+     * The pointer returned by the previous lock call will no longer be valid.
+     */
+    virtual void unlock() = 0;
+    
+    /** 
+     Queries whether the buffer has been locked.
+     
+     @return true if the buffer is locked, false otherwise.
+     */
+    virtual bool isLocked() const = 0;
+    
+    /**
+     * Updates the buffer data. 
+     *  
+     * The size of the buffer will be preserved. The src data will be 
+     * placed at the begining of the buffer and any remaining contents will
+     * be undefined.
+     * 
+     * @return returns true if the update succeeds, false otherwise.
+     */
+    virtual bool updateData(const void* src, size_t srcSizeInBytes) = 0;
+    
+    /**
+     * Updates a portion of the buffer data. 
+     * 
+     * The contents of the buffer outside the update region are preserved.
+     * 
+     * @return returns true if the update succeeds, false otherwise.
+     */
+    virtual bool updateSubData(const void* src, 
+                               size_t srcSizeInBytes, 
+                               size_t offset) = 0;
+protected:
+    GrGeometryBuffer(size_t sizeInBytes, bool dynamic) : 
+        fSizeInBytes(sizeInBytes),
+        fDynamic(dynamic) {}
+
+private:
+    size_t   fSizeInBytes;
+    bool     fDynamic;
+
+    typedef GrRefCnt INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrPaint.h b/gpu/include/GrPaint.h
index a34cbaf..9402209 100644
--- a/gpu/include/GrPaint.h
+++ b/gpu/include/GrPaint.h
@@ -1,103 +1,103 @@
-/*
-    Copyright 2011 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 GrPaint_DEFINED
-#define GrPaint_DEFINED
-
-#include "GrTexture.h"
-#include "GrColor.h"
-#include "GrSamplerState.h"
-
-/**
- * The paint describes how pixels are colored when the context draws to
- * them.
- */
-class GrPaint {
-public:
-
-    // All the paint fields are public except texture (it's ref-counted)
-    GrBlendCoeff                fSrcBlendCoeff;
-    GrBlendCoeff                fDstBlendCoeff;
-    bool                        fAntiAlias;
-    bool                        fDither;
-
-    GrColor                     fColor;
-
-    GrSamplerState              fSampler;
-
-    void setTexture(GrTexture* texture) {
-        GrSafeRef(texture);
-        GrSafeUnref(fTexture);
-        fTexture = texture;
-    }
-
-    GrTexture* getTexture() const { return fTexture; }
-
-    // uninitialized
-    GrPaint() {
-        fTexture = NULL;
-    }
-
-    GrPaint(const GrPaint& paint) {
-        fSrcBlendCoeff = paint.fSrcBlendCoeff;
-        fDstBlendCoeff = paint.fDstBlendCoeff;
-        fAntiAlias = paint.fAntiAlias;
-        fDither = paint.fDither;
-
-        fColor = paint.fColor;
-
-        fSampler = paint.fSampler;
-        fTexture = paint.fTexture;
-        GrSafeRef(fTexture);
-    }
-
-    ~GrPaint() {
-        GrSafeUnref(fTexture);
-    }
-
-    // sets paint to src-over, solid white, no texture
-    void reset() {
-        resetBlend();
-        resetOptions();
-        resetColor();
-        resetTexture();
-    }
-
-private:
-    GrTexture*      fTexture;
-
-    void resetBlend() {
-        fSrcBlendCoeff = kOne_BlendCoeff;
-        fDstBlendCoeff = kZero_BlendCoeff;
-    }
-
-    void resetOptions() {
-        fAntiAlias = false;
-        fDither = false;
-    }
-
-    void resetColor() {
-        fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
-    }
-
-    void resetTexture() {
-        setTexture(NULL);
-        fSampler.setClampNoFilter();
-    }
-
-};
-
-#endif
+/*
+    Copyright 2011 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 GrPaint_DEFINED
+#define GrPaint_DEFINED
+
+#include "GrTexture.h"
+#include "GrColor.h"
+#include "GrSamplerState.h"
+
+/**
+ * The paint describes how pixels are colored when the context draws to
+ * them.
+ */
+class GrPaint {
+public:
+
+    // All the paint fields are public except texture (it's ref-counted)
+    GrBlendCoeff                fSrcBlendCoeff;
+    GrBlendCoeff                fDstBlendCoeff;
+    bool                        fAntiAlias;
+    bool                        fDither;
+
+    GrColor                     fColor;
+
+    GrSamplerState              fSampler;
+
+    void setTexture(GrTexture* texture) {
+        GrSafeRef(texture);
+        GrSafeUnref(fTexture);
+        fTexture = texture;
+    }
+
+    GrTexture* getTexture() const { return fTexture; }
+
+    // uninitialized
+    GrPaint() {
+        fTexture = NULL;
+    }
+
+    GrPaint(const GrPaint& paint) {
+        fSrcBlendCoeff = paint.fSrcBlendCoeff;
+        fDstBlendCoeff = paint.fDstBlendCoeff;
+        fAntiAlias = paint.fAntiAlias;
+        fDither = paint.fDither;
+
+        fColor = paint.fColor;
+
+        fSampler = paint.fSampler;
+        fTexture = paint.fTexture;
+        GrSafeRef(fTexture);
+    }
+
+    ~GrPaint() {
+        GrSafeUnref(fTexture);
+    }
+
+    // sets paint to src-over, solid white, no texture
+    void reset() {
+        resetBlend();
+        resetOptions();
+        resetColor();
+        resetTexture();
+    }
+
+private:
+    GrTexture*      fTexture;
+
+    void resetBlend() {
+        fSrcBlendCoeff = kOne_BlendCoeff;
+        fDstBlendCoeff = kZero_BlendCoeff;
+    }
+
+    void resetOptions() {
+        fAntiAlias = false;
+        fDither = false;
+    }
+
+    void resetColor() {
+        fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
+    }
+
+    void resetTexture() {
+        setTexture(NULL);
+        fSampler.setClampNoFilter();
+    }
+
+};
+
+#endif
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index dbc7f6c..d14f374 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -1,792 +1,792 @@
-/*
-    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.
- */
-
-#include "GrContext.h"
-#include "GrTypes.h"
-#include "GrTextureCache.h"
-#include "GrTextStrike.h"
-#include "GrMemory.h"
-#include "GrPathIter.h"
-#include "GrClipIterator.h"
-#include "GrIndexBuffer.h"
-#include "GrInOrderDrawBuffer.h"
-#include "GrBufferAllocPool.h"
-#include "GrPathRenderer.h"
-
-#define DEFER_TEXT_RENDERING 1
-
-#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB)
-
-static const size_t MAX_TEXTURE_CACHE_COUNT = 128;
-static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;
-
-static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18;
-static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
-
-// We are currently only batching Text and drawRectToRect, both
-// of which use the quad index buffer.
-static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0;
-static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0;
-
-GrContext* GrContext::Create(GrGpu::Engine engine,
-                             GrGpu::Platform3DContext context3D) {
-    GrContext* ctx = NULL;
-    GrGpu* fGpu = GrGpu::Create(engine, context3D);
-    if (NULL != fGpu) {
-        ctx = new GrContext(fGpu);
-        fGpu->unref();
-    }
-    return ctx;
-}
-
-GrContext* GrContext::CreateGLShaderContext() {
-    return GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
-}
-
-GrContext::~GrContext() {
-    fGpu->unref();
-    delete fTextureCache;
-    delete fFontCache;
-    delete fDrawBuffer;
-    delete fDrawBufferVBAllocPool;
-    delete fDrawBufferVBAllocPool;
-    delete fPathRenderer;
-}
-
-void GrContext::abandonAllTextures() {
-    fTextureCache->deleteAll(GrTextureCache::kAbandonTexture_DeleteMode);
-    fFontCache->abandonAll();
-}
-
-GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key,
-                                              const GrSamplerState& sampler) {
-    finalizeTextureKey(key, sampler);
-    return fTextureCache->findAndLock(*key);
-}
-
-static void stretchImage(void* dst,
-                         int dstW,
-                         int dstH,
-                         void* src,
-                         int srcW,
-                         int srcH,
-                         int bpp) {
-    GrFixed dx = (srcW << 16) / dstW;
-    GrFixed dy = (srcH << 16) / dstH;
-
-    GrFixed y = dy >> 1;
-
-    int dstXLimit = dstW*bpp;
-    for (int j = 0; j < dstH; ++j) {
-        GrFixed x = dx >> 1;
-        void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp;
-        void* dstRow = (uint8_t*)dst + j*dstW*bpp;
-        for (int i = 0; i < dstXLimit; i += bpp) {
-            memcpy((uint8_t*) dstRow + i,
-                   (uint8_t*) srcRow + (x>>16)*bpp,
-                   bpp);
-            x += dx;
-        }
-        y += dy;
-    }
-}
-
-GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
-                                                const GrSamplerState& sampler,
-                                                const GrGpu::TextureDesc& desc,
-                                                void* srcData, size_t rowBytes) {
-    GrAssert(key->width() == desc.fWidth);
-    GrAssert(key->height() == desc.fHeight);
-
-#if GR_DUMP_TEXTURE_UPLOAD
-    GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight);
-#endif
-
-    GrTextureEntry* entry = NULL;
-    bool special = finalizeTextureKey(key, sampler);
-    if (special) {
-        GrTextureEntry* clampEntry;
-        GrTextureKey clampKey(*key);
-        clampEntry = findAndLockTexture(&clampKey, GrSamplerState::ClampNoFilter());
-
-        if (NULL == clampEntry) {
-            clampEntry = createAndLockTexture(&clampKey,
-                                              GrSamplerState::ClampNoFilter(),
-                                              desc, srcData, rowBytes);
-            GrAssert(NULL != clampEntry);
-            if (NULL == clampEntry) {
-                return NULL;
-            }
-        }
-        GrGpu::TextureDesc rtDesc = desc;
-        rtDesc.fFlags |= GrGpu::kRenderTarget_TextureFlag |
-                         GrGpu::kNoPathRendering_TextureFlag;
-        rtDesc.fWidth  = GrNextPow2(GrMax<int>(desc.fWidth,
-                                               fGpu->minRenderTargetWidth()));
-        rtDesc.fHeight = GrNextPow2(GrMax<int>(desc.fHeight,
-                                               fGpu->minRenderTargetHeight()));
-
-        GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
-
-        if (NULL != texture) {
-            GrDrawTarget::AutoStateRestore asr(fGpu);
-            fGpu->setRenderTarget(texture->asRenderTarget());
-            fGpu->setTexture(0, clampEntry->texture());
-            fGpu->setStencilPass(GrDrawTarget::kNone_StencilPass);
-            fGpu->setViewMatrix(GrMatrix::I());
-            fGpu->setAlpha(0xff);
-            fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
-            fGpu->disableState(GrDrawTarget::kDither_StateBit |
-                               GrDrawTarget::kClip_StateBit   |
-                               GrDrawTarget::kAntialias_StateBit);
-            GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
-                                          GrSamplerState::kClamp_WrapMode,
-                                          sampler.isFilter());
-            fGpu->setSamplerState(0, stretchSampler);
-
-            static const GrVertexLayout layout =
-                                GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
-            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
-
-            if (arg.succeeded()) {
-                GrPoint* verts = (GrPoint*) arg.vertices();
-                verts[0].setIRectFan(0, 0,
-                                     texture->width(),
-                                     texture->height(),
-                                     2*sizeof(GrPoint));
-                verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));
-                fGpu->drawNonIndexed(kTriangleFan_PrimitiveType,
-                                     0, 4);
-                entry = fTextureCache->createAndLock(*key, texture);
-            }
-            texture->removeRenderTarget();
-        } else {
-            // TODO: Our CPU stretch doesn't filter. But we create separate
-            // stretched textures when the sampler state is either filtered or
-            // not. Either implement filtered stretch blit on CPU or just create
-            // one when FBO case fails.
-
-            rtDesc.fFlags = 0;
-            // no longer need to clamp at min RT size.
-            rtDesc.fWidth  = GrNextPow2(desc.fWidth);
-            rtDesc.fHeight = GrNextPow2(desc.fHeight);
-            int bpp = GrTexture::BytesPerPixel(desc.fFormat);
-            GrAutoSMalloc<128*128*4> stretchedPixels(bpp *
-                                                     rtDesc.fWidth *
-                                                     rtDesc.fHeight);
-            stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
-                         srcData, desc.fWidth, desc.fHeight, bpp);
-
-            size_t stretchedRowBytes = rtDesc.fWidth * bpp;
-
-            GrTexture* texture = fGpu->createTexture(rtDesc,
-                                                     stretchedPixels.get(),
-                                                     stretchedRowBytes);
-            GrAssert(NULL != texture);
-            entry = fTextureCache->createAndLock(*key, texture);
-        }
-        fTextureCache->unlock(clampEntry);
-
-    } else {
-        GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes);
-        if (NULL != texture) {
-            entry = fTextureCache->createAndLock(*key, texture);
-        } else {
-            entry = NULL;
-        }
-    }
-    return entry;
-}
-
-void GrContext::unlockTexture(GrTextureEntry* entry) {
-    fTextureCache->unlock(entry);
-}
-
-void GrContext::detachCachedTexture(GrTextureEntry* entry) {
-    fTextureCache->detach(entry);
-}
-
-void GrContext::reattachAndUnlockCachedTexture(GrTextureEntry* entry) {
-    fTextureCache->reattachAndUnlock(entry);
-}
-
-GrTexture* GrContext::createUncachedTexture(const GrGpu::TextureDesc& desc,
-                                            void* srcData,
-                                            size_t rowBytes) {
-    return fGpu->createTexture(desc, srcData, rowBytes);
-}
-
-void GrContext::getTextureCacheLimits(int* maxTextures,
-                                      size_t* maxTextureBytes) const {
-    fTextureCache->getLimits(maxTextures, maxTextureBytes);
-}
-
-void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
-    fTextureCache->setLimits(maxTextures, maxTextureBytes);
-}
-
-int GrContext::getMaxTextureDimension() {
-    return fGpu->maxTextureDimension();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrRenderTarget* GrContext::createPlatformRenderTarget(
-                                                intptr_t platformRenderTarget,
-                                                int stencilBits,
-                                                int width, int height) {
-    return fGpu->createPlatformRenderTarget(platformRenderTarget, stencilBits,
-                                            width, height);
-}
-
-bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
-                                          int width, int height) {
-    if (!fGpu->supports8BitPalette()) {
-        return false;
-    }
-
-
-    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
-
-    if (!isPow2) {
-        if (!fGpu->npotTextureSupport()) {
-            return false;
-        }
-
-        bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
-                     sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
-        if (tiled && !fGpu->npotTextureTileSupport()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::setClip(const GrClip& clip) {
-    fGpu->setClip(clip);
-    fGpu->enableState(GrDrawTarget::kClip_StateBit);
-}
-
-void GrContext::setClip(const GrIRect& rect) {
-    GrClip clip;
-    clip.setRect(rect);
-    fGpu->setClip(clip);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::eraseColor(GrColor color) {
-    fGpu->eraseColor(color);
-}
-
-void GrContext::drawPaint(const GrPaint& paint) {
-    // set rect to be big enough to fill the space, but not super-huge, so we
-    // don't overflow fixed-point implementations
-    GrRect r(fGpu->getClip().getBounds());
-    GrMatrix inverse;
-    if (fGpu->getViewInverse(&inverse)) {
-        inverse.mapRect(&r);
-    } else {
-        GrPrintf("---- fGpu->getViewInverse failed\n");
-    }
-    this->drawRect(paint, r);
-}
-
-/*  create a triangle strip that strokes the specified triangle. There are 8
- unique vertices, but we repreat the last 2 to close up. Alternatively we
- could use an indices array, and then only send 8 verts, but not sure that
- would be faster.
- */
-static void setStrokeRectStrip(GrPoint verts[10], const GrRect& rect,
-                               GrScalar width) {
-    const GrScalar rad = GrScalarHalf(width);
-
-    verts[0].set(rect.fLeft + rad, rect.fTop + rad);
-    verts[1].set(rect.fLeft - rad, rect.fTop - rad);
-    verts[2].set(rect.fRight - rad, rect.fTop + rad);
-    verts[3].set(rect.fRight + rad, rect.fTop - rad);
-    verts[4].set(rect.fRight - rad, rect.fBottom - rad);
-    verts[5].set(rect.fRight + rad, rect.fBottom + rad);
-    verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
-    verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
-    verts[8] = verts[0];
-    verts[9] = verts[1];
-}
-
-void GrContext::drawRect(const GrPaint& paint,
-                         const GrRect& rect,
-                         GrScalar width,
-                         const GrMatrix* matrix) {
-
-    bool textured = NULL != paint.getTexture();
-
-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-
-    if (width >= 0) {
-        // TODO: consider making static vertex buffers for these cases.
-        // Hairline could be done by just adding closing vertex to
-        // unitSquareVertexBuffer()
-        GrVertexLayout layout = (textured) ?
-                                 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
-                                 0;
-        static const int worstCaseVertCount = 10;
-        GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
-
-        if (!geo.succeeded()) {
-            return;
-        }
-
-        GrPrimitiveType primType;
-        int vertCount;
-        GrPoint* vertex = geo.positions();
-
-        if (width > 0) {
-            vertCount = 10;
-            primType = kTriangleStrip_PrimitiveType;
-            setStrokeRectStrip(vertex, rect, width);
-        } else {
-            // hairline
-            vertCount = 5;
-            primType = kLineStrip_PrimitiveType;
-            vertex[0].set(rect.fLeft, rect.fTop);
-            vertex[1].set(rect.fRight, rect.fTop);
-            vertex[2].set(rect.fRight, rect.fBottom);
-            vertex[3].set(rect.fLeft, rect.fBottom);
-            vertex[4].set(rect.fLeft, rect.fTop);
-        }
-
-        GrDrawTarget::AutoViewMatrixRestore avmr;
-        if (NULL != matrix) {
-            avmr.set(target);
-            target->preConcatViewMatrix(*matrix);
-            target->preConcatSamplerMatrix(0, *matrix);
-        }
-
-        target->drawNonIndexed(primType, 0, vertCount);
-    } else {
-        #if GR_STATIC_RECT_VB
-            GrVertexLayout layout = (textured) ?
-                            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
-                            0;
-            target->setVertexSourceToBuffer(layout, 
-                                            fGpu->getUnitSquareVertexBuffer());
-            GrDrawTarget::AutoViewMatrixRestore avmr(target);
-            GrMatrix m;
-            m.setAll(rect.width(), 0,             rect.fLeft,
-                     0,            rect.height(), rect.fTop,
-                     0,            0,             GrMatrix::I()[8]);
-
-            if (NULL != matrix) {
-                m.postConcat(*matrix);
-            }
-
-            target->preConcatViewMatrix(m);
-
-            if (textured) {
-                target->preConcatSamplerMatrix(0, m);
-            }
-            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
-        #else
-            target->drawSimpleRect(rect, matrix, textured ? 1 : 0);
-        #endif
-    }
-}
-
-void GrContext::drawRectToRect(const GrPaint& paint,
-                               const GrRect& dstRect,
-                               const GrRect& srcRect,
-                               const GrMatrix* dstMatrix,
-                               const GrMatrix* srcMatrix) {
-
-    if (NULL == paint.getTexture()) {
-        drawRect(paint, dstRect, -1, dstMatrix);
-        return;
-    }
-    
-    GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB);
-
-#if GR_STATIC_RECT_VB
-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-
-    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
-    GrDrawTarget::AutoViewMatrixRestore avmr(target);
-
-    GrMatrix m;
-
-    m.setAll(dstRect.width(), 0,                dstRect.fLeft,
-             0,               dstRect.height(), dstRect.fTop,
-             0,               0,                GrMatrix::I()[8]);
-    if (NULL != dstMatrix) {
-        m.postConcat(*dstMatrix);
-    }
-    target->preConcatViewMatrix(m);
-
-    m.setAll(srcRect.width(), 0,                srcRect.fLeft,
-             0,               srcRect.height(), srcRect.fTop,
-             0,               0,                GrMatrix::I()[8]);
-    if (NULL != srcMatrix) {
-        m.postConcat(*srcMatrix);
-    }
-    target->preConcatSamplerMatrix(0, m);
-
-    target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer());
-    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
-#else
-
-    GrDrawTarget* target;
-#if BATCH_RECT_TO_RECT 
-    target = this->prepareToDraw(paint, kBuffered_DrawCategory);
-#else 
-    target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-#endif
-
-    const GrRect* srcRects[GrDrawTarget::kNumStages] = {NULL};
-    const GrMatrix* srcMatrices[GrDrawTarget::kNumStages] = {NULL};
-    srcRects[0] = &srcRect;
-    srcMatrices[0] = srcMatrix;
-
-    target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);
-#endif
-}
-
-void GrContext::drawVertices(const GrPaint& paint,
-                             GrPrimitiveType primitiveType,
-                             int vertexCount,
-                             const GrPoint positions[],
-                             const GrPoint texCoords[],
-                             const GrColor colors[],
-                             const uint16_t indices[],
-                             int indexCount) {
-    GrVertexLayout layout = 0;
-    int vertexSize = sizeof(GrPoint);
-
-    GrDrawTarget::AutoReleaseGeometry geo;
-
-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-
-    if (NULL != paint.getTexture()) {
-        if (NULL == texCoords) {
-            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
-        } else {
-            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
-            vertexSize += sizeof(GrPoint);
-        }
-    }
-
-    if (NULL != colors) {
-        layout |= GrDrawTarget::kColor_VertexLayoutBit;
-        vertexSize += sizeof(GrColor);
-    }
-
-    if (sizeof(GrPoint) != vertexSize) {
-        if (!geo.set(target, layout, vertexCount, 0)) {
-            GrPrintf("Failed to get space for vertices!");
-            return;
-        }
-        int texOffsets[GrDrawTarget::kMaxTexCoords];
-        int colorOffset;
-        int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
-                                                            texOffsets,
-                                                            &colorOffset);
-        void* curVertex = geo.vertices();
-
-        for (int i = 0; i < vertexCount; ++i) {
-            *((GrPoint*)curVertex) = positions[i];
-
-            if (texOffsets[0] > 0) {
-                *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i];
-            }
-            if (colorOffset > 0) {
-                *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
-            }
-            curVertex = (void*)((intptr_t)curVertex + vsize);
-        }
-    } else {
-        target->setVertexSourceToArray(layout, positions, vertexCount);
-    }
-
-    if (NULL != indices) {
-        target->setIndexSourceToArray(indices, indexCount);
-        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
-    } else {
-        target->drawNonIndexed(primitiveType, 0, vertexCount);
-    }
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::drawPath(const GrPaint& paint,
-                         GrPathIter* path,
-                         GrPathFill fill,
-                         const GrPoint* translate) {
-
-
-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-
-    GrDrawTarget::StageBitfield enabledStages = 0;
-    if (NULL != paint.getTexture()) {
-        enabledStages |= 1;
-    }
-    fPathRenderer->drawPath(target, enabledStages, path, fill, translate);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::flush(bool flushRenderTarget) {
-    flushDrawBuffer();
-    if (flushRenderTarget) {
-        fGpu->forceRenderTargetFlush();
-    }
-}
-
-void GrContext::flushText() {
-    if (kText_DrawCategory == fLastDrawCategory) {
-        flushDrawBuffer();
-    }
-}
-
-void GrContext::flushDrawBuffer() {
-#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING
-    fDrawBuffer->playback(fGpu);
-    fDrawBuffer->reset();
-#endif
-}
-
-bool GrContext::readPixels(int left, int top, int width, int height,
-                           GrTexture::PixelConfig config, void* buffer) {
-    this->flush(true);
-    return fGpu->readPixels(left, top, width, height, config, buffer);
-}
-
-void GrContext::writePixels(int left, int top, int width, int height,
-                            GrTexture::PixelConfig config, const void* buffer,
-                            size_t stride) {
-
-    // TODO: when underlying api has a direct way to do this we should use it
-    // (e.g. glDrawPixels on desktop GL).
-
-    const GrGpu::TextureDesc desc = {
-        0, GrGpu::kNone_AALevel, width, height, config
-    };
-    GrTexture* texture = fGpu->createTexture(desc, buffer, stride);
-    if (NULL == texture) {
-        return;
-    }
-
-    this->flush(true);
-
-    GrAutoUnref                     aur(texture);
-    GrDrawTarget::AutoStateRestore  asr(fGpu);
-
-    GrMatrix matrix;
-    matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
-    fGpu->setViewMatrix(matrix);
-
-    fGpu->disableState(GrDrawTarget::kClip_StateBit);
-    fGpu->setAlpha(0xFF);
-    fGpu->setBlendFunc(kOne_BlendCoeff,
-                       kZero_BlendCoeff);
-    fGpu->setTexture(0, texture);
-
-    GrSamplerState sampler;
-    sampler.setClampNoFilter();
-    matrix.setScale(GR_Scalar1 / width, GR_Scalar1 / height);
-    sampler.setMatrix(matrix);
-    fGpu->setSamplerState(0, sampler);
-
-    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
-    static const int VCOUNT = 4;
-
-    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);
-    if (!geo.succeeded()) {
-        return;
-    }
-    ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height);
-    fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT);
-}
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) {
-    target->setTexture(0, paint.getTexture());
-    target->setSamplerState(0, paint.fSampler);
-    target->setColor(paint.fColor);
-
-    if (paint.fDither) {
-        target->enableState(GrDrawTarget::kDither_StateBit);
-    } else {
-        target->disableState(GrDrawTarget::kDither_StateBit);
-    }
-    if (paint.fAntiAlias) {
-        target->enableState(GrDrawTarget::kAntialias_StateBit);
-    } else {
-        target->disableState(GrDrawTarget::kAntialias_StateBit);
-    }
-    target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
-}
-
-GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 
-                                       DrawCategory category) {
-    if (category != fLastDrawCategory) {
-        flushDrawBuffer();
-        fLastDrawCategory = category;
-    }
-    SetPaint(paint, fGpu);
-    GrDrawTarget* target = fGpu;
-    switch (category) {
-    case kText_DrawCategory:
-#if DEFER_TEXT_RENDERING
-        target = fDrawBuffer;
-        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
-#else
-        target = fGpu;
-#endif
-        break;
-    case kUnbuffered_DrawCategory:
-        target = fGpu;
-        break;
-    case kBuffered_DrawCategory:
-        target = fDrawBuffer;
-        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
-        break;
-    }
-    return target;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::resetContext() {
-    fGpu->resetContext();
-}
-
-void GrContext::setRenderTarget(GrRenderTarget* target) {
-    flush(false);
-    fGpu->setRenderTarget(target);
-}
-
-GrRenderTarget* GrContext::getRenderTarget() {
-    return fGpu->getRenderTarget();
-}
-
-const GrRenderTarget* GrContext::getRenderTarget() const {
-    return fGpu->getRenderTarget();
-}
-
-const GrMatrix& GrContext::getMatrix() const {
-    return fGpu->getViewMatrix();
-}
-
-void GrContext::setMatrix(const GrMatrix& m) {
-    fGpu->setViewMatrix(m);
-}
-
-void GrContext::concatMatrix(const GrMatrix& m) const {
-    fGpu->preConcatViewMatrix(m);
-}
-
-static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
-    intptr_t mask = 1 << shift;
-    if (pred) {
-        bits |= mask;
-    } else {
-        bits &= ~mask;
-    }
-    return bits;
-}
-
-void GrContext::resetStats() {
-    fGpu->resetStats();
-}
-
-const GrGpu::Stats& GrContext::getStats() const {
-    return fGpu->getStats();
-}
-
-void GrContext::printStats() const {
-    fGpu->printStats();
-}
-
-GrContext::GrContext(GrGpu* gpu) {
-    fGpu = gpu;
-    fGpu->ref();
-    fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT,
-                                       MAX_TEXTURE_CACHE_BYTES);
-    fFontCache = new GrFontCache(fGpu);
-
-    fLastDrawCategory = kUnbuffered_DrawCategory;
-
-#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
-    fDrawBufferVBAllocPool = 
-        new GrVertexBufferAllocPool(gpu, false,
-                                    DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
-                                    DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
-    fDrawBufferIBAllocPool = 
-        new GrIndexBufferAllocPool(gpu, false,
-                                   DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 
-                                   DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
-
-    fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
-                                          fDrawBufferIBAllocPool);
-#else
-    fDrawBuffer = NULL;
-    fDrawBufferVBAllocPool = NULL;
-    fDrawBufferIBAllocPool = NULL;
-#endif
-
-#if BATCH_RECT_TO_RECT
-    fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer());
-#endif
-    fPathRenderer = new GrDefaultPathRenderer(fGpu->supportsSingleStencilPassWinding());
-}
-
-bool GrContext::finalizeTextureKey(GrTextureKey* key,
-                                   const GrSamplerState& sampler) const {
-    uint32_t bits = 0;
-    uint16_t width = key->width();
-    uint16_t height = key->height();
-
-
-    if (!fGpu->npotTextureTileSupport()) {
-        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
-
-        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
-                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
-
-        if (tiled && !isPow2) {
-            bits |= 1;
-            bits |= sampler.isFilter() ? 2 : 0;
-        }
-    }
-    key->finalize(bits);
-    return 0 != bits;
-}
-
-GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
-    GrDrawTarget* target;
-#if DEFER_TEXT_RENDERING
-    target = prepareToDraw(paint, kText_DrawCategory);
-#else
-    target = prepareToDraw(paint, kUnbuffered_DrawCategory);
-#endif
-    SetPaint(paint, target);
-    return target;
-}
-
-const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
-    return fGpu->getQuadIndexBuffer();
-}
+/*
+    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.
+ */
+
+#include "GrContext.h"
+#include "GrTypes.h"
+#include "GrTextureCache.h"
+#include "GrTextStrike.h"
+#include "GrMemory.h"
+#include "GrPathIter.h"
+#include "GrClipIterator.h"
+#include "GrIndexBuffer.h"
+#include "GrInOrderDrawBuffer.h"
+#include "GrBufferAllocPool.h"
+#include "GrPathRenderer.h"
+
+#define DEFER_TEXT_RENDERING 1
+
+#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB)
+
+static const size_t MAX_TEXTURE_CACHE_COUNT = 128;
+static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;
+
+static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18;
+static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
+
+// We are currently only batching Text and drawRectToRect, both
+// of which use the quad index buffer.
+static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0;
+static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0;
+
+GrContext* GrContext::Create(GrGpu::Engine engine,
+                             GrGpu::Platform3DContext context3D) {
+    GrContext* ctx = NULL;
+    GrGpu* fGpu = GrGpu::Create(engine, context3D);
+    if (NULL != fGpu) {
+        ctx = new GrContext(fGpu);
+        fGpu->unref();
+    }
+    return ctx;
+}
+
+GrContext* GrContext::CreateGLShaderContext() {
+    return GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+}
+
+GrContext::~GrContext() {
+    fGpu->unref();
+    delete fTextureCache;
+    delete fFontCache;
+    delete fDrawBuffer;
+    delete fDrawBufferVBAllocPool;
+    delete fDrawBufferVBAllocPool;
+    delete fPathRenderer;
+}
+
+void GrContext::abandonAllTextures() {
+    fTextureCache->deleteAll(GrTextureCache::kAbandonTexture_DeleteMode);
+    fFontCache->abandonAll();
+}
+
+GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key,
+                                              const GrSamplerState& sampler) {
+    finalizeTextureKey(key, sampler);
+    return fTextureCache->findAndLock(*key);
+}
+
+static void stretchImage(void* dst,
+                         int dstW,
+                         int dstH,
+                         void* src,
+                         int srcW,
+                         int srcH,
+                         int bpp) {
+    GrFixed dx = (srcW << 16) / dstW;
+    GrFixed dy = (srcH << 16) / dstH;
+
+    GrFixed y = dy >> 1;
+
+    int dstXLimit = dstW*bpp;
+    for (int j = 0; j < dstH; ++j) {
+        GrFixed x = dx >> 1;
+        void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp;
+        void* dstRow = (uint8_t*)dst + j*dstW*bpp;
+        for (int i = 0; i < dstXLimit; i += bpp) {
+            memcpy((uint8_t*) dstRow + i,
+                   (uint8_t*) srcRow + (x>>16)*bpp,
+                   bpp);
+            x += dx;
+        }
+        y += dy;
+    }
+}
+
+GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
+                                                const GrSamplerState& sampler,
+                                                const GrGpu::TextureDesc& desc,
+                                                void* srcData, size_t rowBytes) {
+    GrAssert(key->width() == desc.fWidth);
+    GrAssert(key->height() == desc.fHeight);
+
+#if GR_DUMP_TEXTURE_UPLOAD
+    GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight);
+#endif
+
+    GrTextureEntry* entry = NULL;
+    bool special = finalizeTextureKey(key, sampler);
+    if (special) {
+        GrTextureEntry* clampEntry;
+        GrTextureKey clampKey(*key);
+        clampEntry = findAndLockTexture(&clampKey, GrSamplerState::ClampNoFilter());
+
+        if (NULL == clampEntry) {
+            clampEntry = createAndLockTexture(&clampKey,
+                                              GrSamplerState::ClampNoFilter(),
+                                              desc, srcData, rowBytes);
+            GrAssert(NULL != clampEntry);
+            if (NULL == clampEntry) {
+                return NULL;
+            }
+        }
+        GrGpu::TextureDesc rtDesc = desc;
+        rtDesc.fFlags |= GrGpu::kRenderTarget_TextureFlag |
+                         GrGpu::kNoPathRendering_TextureFlag;
+        rtDesc.fWidth  = GrNextPow2(GrMax<int>(desc.fWidth,
+                                               fGpu->minRenderTargetWidth()));
+        rtDesc.fHeight = GrNextPow2(GrMax<int>(desc.fHeight,
+                                               fGpu->minRenderTargetHeight()));
+
+        GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
+
+        if (NULL != texture) {
+            GrDrawTarget::AutoStateRestore asr(fGpu);
+            fGpu->setRenderTarget(texture->asRenderTarget());
+            fGpu->setTexture(0, clampEntry->texture());
+            fGpu->setStencilPass(GrDrawTarget::kNone_StencilPass);
+            fGpu->setViewMatrix(GrMatrix::I());
+            fGpu->setAlpha(0xff);
+            fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
+            fGpu->disableState(GrDrawTarget::kDither_StateBit |
+                               GrDrawTarget::kClip_StateBit   |
+                               GrDrawTarget::kAntialias_StateBit);
+            GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
+                                          GrSamplerState::kClamp_WrapMode,
+                                          sampler.isFilter());
+            fGpu->setSamplerState(0, stretchSampler);
+
+            static const GrVertexLayout layout =
+                                GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
+
+            if (arg.succeeded()) {
+                GrPoint* verts = (GrPoint*) arg.vertices();
+                verts[0].setIRectFan(0, 0,
+                                     texture->width(),
+                                     texture->height(),
+                                     2*sizeof(GrPoint));
+                verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));
+                fGpu->drawNonIndexed(kTriangleFan_PrimitiveType,
+                                     0, 4);
+                entry = fTextureCache->createAndLock(*key, texture);
+            }
+            texture->removeRenderTarget();
+        } else {
+            // TODO: Our CPU stretch doesn't filter. But we create separate
+            // stretched textures when the sampler state is either filtered or
+            // not. Either implement filtered stretch blit on CPU or just create
+            // one when FBO case fails.
+
+            rtDesc.fFlags = 0;
+            // no longer need to clamp at min RT size.
+            rtDesc.fWidth  = GrNextPow2(desc.fWidth);
+            rtDesc.fHeight = GrNextPow2(desc.fHeight);
+            int bpp = GrTexture::BytesPerPixel(desc.fFormat);
+            GrAutoSMalloc<128*128*4> stretchedPixels(bpp *
+                                                     rtDesc.fWidth *
+                                                     rtDesc.fHeight);
+            stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
+                         srcData, desc.fWidth, desc.fHeight, bpp);
+
+            size_t stretchedRowBytes = rtDesc.fWidth * bpp;
+
+            GrTexture* texture = fGpu->createTexture(rtDesc,
+                                                     stretchedPixels.get(),
+                                                     stretchedRowBytes);
+            GrAssert(NULL != texture);
+            entry = fTextureCache->createAndLock(*key, texture);
+        }
+        fTextureCache->unlock(clampEntry);
+
+    } else {
+        GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes);
+        if (NULL != texture) {
+            entry = fTextureCache->createAndLock(*key, texture);
+        } else {
+            entry = NULL;
+        }
+    }
+    return entry;
+}
+
+void GrContext::unlockTexture(GrTextureEntry* entry) {
+    fTextureCache->unlock(entry);
+}
+
+void GrContext::detachCachedTexture(GrTextureEntry* entry) {
+    fTextureCache->detach(entry);
+}
+
+void GrContext::reattachAndUnlockCachedTexture(GrTextureEntry* entry) {
+    fTextureCache->reattachAndUnlock(entry);
+}
+
+GrTexture* GrContext::createUncachedTexture(const GrGpu::TextureDesc& desc,
+                                            void* srcData,
+                                            size_t rowBytes) {
+    return fGpu->createTexture(desc, srcData, rowBytes);
+}
+
+void GrContext::getTextureCacheLimits(int* maxTextures,
+                                      size_t* maxTextureBytes) const {
+    fTextureCache->getLimits(maxTextures, maxTextureBytes);
+}
+
+void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
+    fTextureCache->setLimits(maxTextures, maxTextureBytes);
+}
+
+int GrContext::getMaxTextureDimension() {
+    return fGpu->maxTextureDimension();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRenderTarget* GrContext::createPlatformRenderTarget(
+                                                intptr_t platformRenderTarget,
+                                                int stencilBits,
+                                                int width, int height) {
+    return fGpu->createPlatformRenderTarget(platformRenderTarget, stencilBits,
+                                            width, height);
+}
+
+bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
+                                          int width, int height) {
+    if (!fGpu->supports8BitPalette()) {
+        return false;
+    }
+
+
+    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+    if (!isPow2) {
+        if (!fGpu->npotTextureSupport()) {
+            return false;
+        }
+
+        bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
+                     sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
+        if (tiled && !fGpu->npotTextureTileSupport()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::setClip(const GrClip& clip) {
+    fGpu->setClip(clip);
+    fGpu->enableState(GrDrawTarget::kClip_StateBit);
+}
+
+void GrContext::setClip(const GrIRect& rect) {
+    GrClip clip;
+    clip.setRect(rect);
+    fGpu->setClip(clip);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::eraseColor(GrColor color) {
+    fGpu->eraseColor(color);
+}
+
+void GrContext::drawPaint(const GrPaint& paint) {
+    // set rect to be big enough to fill the space, but not super-huge, so we
+    // don't overflow fixed-point implementations
+    GrRect r(fGpu->getClip().getBounds());
+    GrMatrix inverse;
+    if (fGpu->getViewInverse(&inverse)) {
+        inverse.mapRect(&r);
+    } else {
+        GrPrintf("---- fGpu->getViewInverse failed\n");
+    }
+    this->drawRect(paint, r);
+}
+
+/*  create a triangle strip that strokes the specified triangle. There are 8
+ unique vertices, but we repreat the last 2 to close up. Alternatively we
+ could use an indices array, and then only send 8 verts, but not sure that
+ would be faster.
+ */
+static void setStrokeRectStrip(GrPoint verts[10], const GrRect& rect,
+                               GrScalar width) {
+    const GrScalar rad = GrScalarHalf(width);
+
+    verts[0].set(rect.fLeft + rad, rect.fTop + rad);
+    verts[1].set(rect.fLeft - rad, rect.fTop - rad);
+    verts[2].set(rect.fRight - rad, rect.fTop + rad);
+    verts[3].set(rect.fRight + rad, rect.fTop - rad);
+    verts[4].set(rect.fRight - rad, rect.fBottom - rad);
+    verts[5].set(rect.fRight + rad, rect.fBottom + rad);
+    verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
+    verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
+    verts[8] = verts[0];
+    verts[9] = verts[1];
+}
+
+void GrContext::drawRect(const GrPaint& paint,
+                         const GrRect& rect,
+                         GrScalar width,
+                         const GrMatrix* matrix) {
+
+    bool textured = NULL != paint.getTexture();
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (width >= 0) {
+        // TODO: consider making static vertex buffers for these cases.
+        // Hairline could be done by just adding closing vertex to
+        // unitSquareVertexBuffer()
+        GrVertexLayout layout = (textured) ?
+                                 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
+                                 0;
+        static const int worstCaseVertCount = 10;
+        GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
+
+        if (!geo.succeeded()) {
+            return;
+        }
+
+        GrPrimitiveType primType;
+        int vertCount;
+        GrPoint* vertex = geo.positions();
+
+        if (width > 0) {
+            vertCount = 10;
+            primType = kTriangleStrip_PrimitiveType;
+            setStrokeRectStrip(vertex, rect, width);
+        } else {
+            // hairline
+            vertCount = 5;
+            primType = kLineStrip_PrimitiveType;
+            vertex[0].set(rect.fLeft, rect.fTop);
+            vertex[1].set(rect.fRight, rect.fTop);
+            vertex[2].set(rect.fRight, rect.fBottom);
+            vertex[3].set(rect.fLeft, rect.fBottom);
+            vertex[4].set(rect.fLeft, rect.fTop);
+        }
+
+        GrDrawTarget::AutoViewMatrixRestore avmr;
+        if (NULL != matrix) {
+            avmr.set(target);
+            target->preConcatViewMatrix(*matrix);
+            target->preConcatSamplerMatrix(0, *matrix);
+        }
+
+        target->drawNonIndexed(primType, 0, vertCount);
+    } else {
+        #if GR_STATIC_RECT_VB
+            GrVertexLayout layout = (textured) ?
+                            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
+                            0;
+            target->setVertexSourceToBuffer(layout, 
+                                            fGpu->getUnitSquareVertexBuffer());
+            GrDrawTarget::AutoViewMatrixRestore avmr(target);
+            GrMatrix m;
+            m.setAll(rect.width(), 0,             rect.fLeft,
+                     0,            rect.height(), rect.fTop,
+                     0,            0,             GrMatrix::I()[8]);
+
+            if (NULL != matrix) {
+                m.postConcat(*matrix);
+            }
+
+            target->preConcatViewMatrix(m);
+
+            if (textured) {
+                target->preConcatSamplerMatrix(0, m);
+            }
+            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
+        #else
+            target->drawSimpleRect(rect, matrix, textured ? 1 : 0);
+        #endif
+    }
+}
+
+void GrContext::drawRectToRect(const GrPaint& paint,
+                               const GrRect& dstRect,
+                               const GrRect& srcRect,
+                               const GrMatrix* dstMatrix,
+                               const GrMatrix* srcMatrix) {
+
+    if (NULL == paint.getTexture()) {
+        drawRect(paint, dstRect, -1, dstMatrix);
+        return;
+    }
+    
+    GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB);
+
+#if GR_STATIC_RECT_VB
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+    GrDrawTarget::AutoViewMatrixRestore avmr(target);
+
+    GrMatrix m;
+
+    m.setAll(dstRect.width(), 0,                dstRect.fLeft,
+             0,               dstRect.height(), dstRect.fTop,
+             0,               0,                GrMatrix::I()[8]);
+    if (NULL != dstMatrix) {
+        m.postConcat(*dstMatrix);
+    }
+    target->preConcatViewMatrix(m);
+
+    m.setAll(srcRect.width(), 0,                srcRect.fLeft,
+             0,               srcRect.height(), srcRect.fTop,
+             0,               0,                GrMatrix::I()[8]);
+    if (NULL != srcMatrix) {
+        m.postConcat(*srcMatrix);
+    }
+    target->preConcatSamplerMatrix(0, m);
+
+    target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer());
+    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
+#else
+
+    GrDrawTarget* target;
+#if BATCH_RECT_TO_RECT 
+    target = this->prepareToDraw(paint, kBuffered_DrawCategory);
+#else 
+    target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+#endif
+
+    const GrRect* srcRects[GrDrawTarget::kNumStages] = {NULL};
+    const GrMatrix* srcMatrices[GrDrawTarget::kNumStages] = {NULL};
+    srcRects[0] = &srcRect;
+    srcMatrices[0] = srcMatrix;
+
+    target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);
+#endif
+}
+
+void GrContext::drawVertices(const GrPaint& paint,
+                             GrPrimitiveType primitiveType,
+                             int vertexCount,
+                             const GrPoint positions[],
+                             const GrPoint texCoords[],
+                             const GrColor colors[],
+                             const uint16_t indices[],
+                             int indexCount) {
+    GrVertexLayout layout = 0;
+    int vertexSize = sizeof(GrPoint);
+
+    GrDrawTarget::AutoReleaseGeometry geo;
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (NULL != paint.getTexture()) {
+        if (NULL == texCoords) {
+            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+        } else {
+            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+            vertexSize += sizeof(GrPoint);
+        }
+    }
+
+    if (NULL != colors) {
+        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+        vertexSize += sizeof(GrColor);
+    }
+
+    if (sizeof(GrPoint) != vertexSize) {
+        if (!geo.set(target, layout, vertexCount, 0)) {
+            GrPrintf("Failed to get space for vertices!");
+            return;
+        }
+        int texOffsets[GrDrawTarget::kMaxTexCoords];
+        int colorOffset;
+        int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+                                                            texOffsets,
+                                                            &colorOffset);
+        void* curVertex = geo.vertices();
+
+        for (int i = 0; i < vertexCount; ++i) {
+            *((GrPoint*)curVertex) = positions[i];
+
+            if (texOffsets[0] > 0) {
+                *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i];
+            }
+            if (colorOffset > 0) {
+                *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
+            }
+            curVertex = (void*)((intptr_t)curVertex + vsize);
+        }
+    } else {
+        target->setVertexSourceToArray(layout, positions, vertexCount);
+    }
+
+    if (NULL != indices) {
+        target->setIndexSourceToArray(indices, indexCount);
+        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+    } else {
+        target->drawNonIndexed(primitiveType, 0, vertexCount);
+    }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::drawPath(const GrPaint& paint,
+                         GrPathIter* path,
+                         GrPathFill fill,
+                         const GrPoint* translate) {
+
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    GrDrawTarget::StageBitfield enabledStages = 0;
+    if (NULL != paint.getTexture()) {
+        enabledStages |= 1;
+    }
+    fPathRenderer->drawPath(target, enabledStages, path, fill, translate);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::flush(bool flushRenderTarget) {
+    flushDrawBuffer();
+    if (flushRenderTarget) {
+        fGpu->forceRenderTargetFlush();
+    }
+}
+
+void GrContext::flushText() {
+    if (kText_DrawCategory == fLastDrawCategory) {
+        flushDrawBuffer();
+    }
+}
+
+void GrContext::flushDrawBuffer() {
+#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING
+    fDrawBuffer->playback(fGpu);
+    fDrawBuffer->reset();
+#endif
+}
+
+bool GrContext::readPixels(int left, int top, int width, int height,
+                           GrTexture::PixelConfig config, void* buffer) {
+    this->flush(true);
+    return fGpu->readPixels(left, top, width, height, config, buffer);
+}
+
+void GrContext::writePixels(int left, int top, int width, int height,
+                            GrTexture::PixelConfig config, const void* buffer,
+                            size_t stride) {
+
+    // TODO: when underlying api has a direct way to do this we should use it
+    // (e.g. glDrawPixels on desktop GL).
+
+    const GrGpu::TextureDesc desc = {
+        0, GrGpu::kNone_AALevel, width, height, config
+    };
+    GrTexture* texture = fGpu->createTexture(desc, buffer, stride);
+    if (NULL == texture) {
+        return;
+    }
+
+    this->flush(true);
+
+    GrAutoUnref                     aur(texture);
+    GrDrawTarget::AutoStateRestore  asr(fGpu);
+
+    GrMatrix matrix;
+    matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
+    fGpu->setViewMatrix(matrix);
+
+    fGpu->disableState(GrDrawTarget::kClip_StateBit);
+    fGpu->setAlpha(0xFF);
+    fGpu->setBlendFunc(kOne_BlendCoeff,
+                       kZero_BlendCoeff);
+    fGpu->setTexture(0, texture);
+
+    GrSamplerState sampler;
+    sampler.setClampNoFilter();
+    matrix.setScale(GR_Scalar1 / width, GR_Scalar1 / height);
+    sampler.setMatrix(matrix);
+    fGpu->setSamplerState(0, sampler);
+
+    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+    static const int VCOUNT = 4;
+
+    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);
+    if (!geo.succeeded()) {
+        return;
+    }
+    ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height);
+    fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT);
+}
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) {
+    target->setTexture(0, paint.getTexture());
+    target->setSamplerState(0, paint.fSampler);
+    target->setColor(paint.fColor);
+
+    if (paint.fDither) {
+        target->enableState(GrDrawTarget::kDither_StateBit);
+    } else {
+        target->disableState(GrDrawTarget::kDither_StateBit);
+    }
+    if (paint.fAntiAlias) {
+        target->enableState(GrDrawTarget::kAntialias_StateBit);
+    } else {
+        target->disableState(GrDrawTarget::kAntialias_StateBit);
+    }
+    target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
+}
+
+GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 
+                                       DrawCategory category) {
+    if (category != fLastDrawCategory) {
+        flushDrawBuffer();
+        fLastDrawCategory = category;
+    }
+    SetPaint(paint, fGpu);
+    GrDrawTarget* target = fGpu;
+    switch (category) {
+    case kText_DrawCategory:
+#if DEFER_TEXT_RENDERING
+        target = fDrawBuffer;
+        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
+#else
+        target = fGpu;
+#endif
+        break;
+    case kUnbuffered_DrawCategory:
+        target = fGpu;
+        break;
+    case kBuffered_DrawCategory:
+        target = fDrawBuffer;
+        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
+        break;
+    }
+    return target;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::resetContext() {
+    fGpu->resetContext();
+}
+
+void GrContext::setRenderTarget(GrRenderTarget* target) {
+    flush(false);
+    fGpu->setRenderTarget(target);
+}
+
+GrRenderTarget* GrContext::getRenderTarget() {
+    return fGpu->getRenderTarget();
+}
+
+const GrRenderTarget* GrContext::getRenderTarget() const {
+    return fGpu->getRenderTarget();
+}
+
+const GrMatrix& GrContext::getMatrix() const {
+    return fGpu->getViewMatrix();
+}
+
+void GrContext::setMatrix(const GrMatrix& m) {
+    fGpu->setViewMatrix(m);
+}
+
+void GrContext::concatMatrix(const GrMatrix& m) const {
+    fGpu->preConcatViewMatrix(m);
+}
+
+static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
+    intptr_t mask = 1 << shift;
+    if (pred) {
+        bits |= mask;
+    } else {
+        bits &= ~mask;
+    }
+    return bits;
+}
+
+void GrContext::resetStats() {
+    fGpu->resetStats();
+}
+
+const GrGpu::Stats& GrContext::getStats() const {
+    return fGpu->getStats();
+}
+
+void GrContext::printStats() const {
+    fGpu->printStats();
+}
+
+GrContext::GrContext(GrGpu* gpu) {
+    fGpu = gpu;
+    fGpu->ref();
+    fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT,
+                                       MAX_TEXTURE_CACHE_BYTES);
+    fFontCache = new GrFontCache(fGpu);
+
+    fLastDrawCategory = kUnbuffered_DrawCategory;
+
+#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
+    fDrawBufferVBAllocPool = 
+        new GrVertexBufferAllocPool(gpu, false,
+                                    DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
+                                    DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
+    fDrawBufferIBAllocPool = 
+        new GrIndexBufferAllocPool(gpu, false,
+                                   DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 
+                                   DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
+
+    fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
+                                          fDrawBufferIBAllocPool);
+#else
+    fDrawBuffer = NULL;
+    fDrawBufferVBAllocPool = NULL;
+    fDrawBufferIBAllocPool = NULL;
+#endif
+
+#if BATCH_RECT_TO_RECT
+    fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer());
+#endif
+    fPathRenderer = new GrDefaultPathRenderer(fGpu->supportsSingleStencilPassWinding());
+}
+
+bool GrContext::finalizeTextureKey(GrTextureKey* key,
+                                   const GrSamplerState& sampler) const {
+    uint32_t bits = 0;
+    uint16_t width = key->width();
+    uint16_t height = key->height();
+
+
+    if (!fGpu->npotTextureTileSupport()) {
+        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
+                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
+
+        if (tiled && !isPow2) {
+            bits |= 1;
+            bits |= sampler.isFilter() ? 2 : 0;
+        }
+    }
+    key->finalize(bits);
+    return 0 != bits;
+}
+
+GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
+    GrDrawTarget* target;
+#if DEFER_TEXT_RENDERING
+    target = prepareToDraw(paint, kText_DrawCategory);
+#else
+    target = prepareToDraw(paint, kUnbuffered_DrawCategory);
+#endif
+    SetPaint(paint, target);
+    return target;
+}
+
+const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
+    return fGpu->getQuadIndexBuffer();
+}
diff --git a/gpu/src/GrGLUtil.cpp b/gpu/src/GrGLUtil.cpp
index f531a6b..e128d35 100644
--- a/gpu/src/GrGLUtil.cpp
+++ b/gpu/src/GrGLUtil.cpp
@@ -1,255 +1,255 @@
-/*
- 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.
- */
-
-#include "GrGLConfig.h"
-#include "GrTypes.h"
-#include <stdio.h>
-
-bool has_gl_extension(const char* ext) {
-    const char* glstr = (const char*) glGetString(GL_EXTENSIONS);
-
-    int extLength = strlen(ext);
-
-    while (true) {
-        int n = strcspn(glstr, " ");
-        if (n == extLength && 0 == strncmp(ext, glstr, n)) {
-            return true;
-        }
-        if (0 == glstr[n]) {
-            return false;
-        }
-        glstr += n+1;
-    }
-}
-
-void gl_version(int* major, int* minor) {
-    const char* v = (const char*) glGetString(GL_VERSION);
-    if (NULL == v) {
-        GrAssert(0);
-        *major = 0;
-        *minor = 0;
-        return;
-    }
-#if GR_SUPPORT_GLDESKTOP
-    int n = sscanf(v, "%d.%d", major, minor);
-    if (n != 2) {
-        GrAssert(0);
-        *major = 0;
-        *minor = 0;
-        return;
-    }
-#else
-    char profile[2];
-    int n = sscanf(v, "OpenGL ES-%c%c %d.%d", profile, profile+1, major, minor);
-    bool ok = 4 == n;
-    if (!ok) {
-        int n = sscanf(v, "OpenGL ES %d.%d", major, minor);
-        ok = 2 == n;
-    }
-    if (!ok) {
-        GrAssert(0);
-        *major = 0;
-        *minor = 0;
-        return;
-    }
-#endif
-}
-
-#if defined(GR_GL_PROC_ADDRESS_HEADER)
-    #include GR_GL_PROC_ADDRESS_HEADER
-#endif
-
-typedef void (*glProc)(void);
-
-#define GET_PROC(EXT_STRUCT, PROC_NAME) \
-    *(GrTCast<glProc*>(&(EXT_STRUCT-> PROC_NAME))) = (glProc)GR_GL_PROC_ADDRESS((gl ## PROC_NAME)); \
-    GrAssert(NULL != EXT_STRUCT-> PROC_NAME)
-
-#define GET_SUFFIX_PROC(EXT_STRUCT, PROC_NAME, SUFFIX) \
-    *(GrTCast<glProc*>(&(EXT_STRUCT-> PROC_NAME))) = (glProc)GR_GL_PROC_ADDRESS((gl ## PROC_NAME ## SUFFIX)); \
-    GrAssert(NULL != EXT_STRUCT-> PROC_NAME)
-
-extern void GrGLInitExtensions(GrGLExts* exts) {
-    exts->GenFramebuffers                   = NULL;
-    exts->BindFramebuffer                   = NULL;
-    exts->FramebufferTexture2D              = NULL;
-    exts->CheckFramebufferStatus            = NULL;
-    exts->DeleteFramebuffers                = NULL;
-    exts->RenderbufferStorage               = NULL;
-    exts->GenRenderbuffers                  = NULL;
-    exts->DeleteRenderbuffers               = NULL;
-    exts->FramebufferRenderbuffer           = NULL;
-    exts->BindRenderbuffer                  = NULL;
-    exts->RenderbufferStorageMultisample    = NULL;
-    exts->BlitFramebuffer                   = NULL;
-    exts->ResolveMultisampleFramebuffer     = NULL;
-    exts->FramebufferTexture2DMultisample   = NULL;
-    exts->MapBuffer                         = NULL;
-    exts->UnmapBuffer                       = NULL;
-
-    GLint major, minor;
-    gl_version(&major, &minor);
-
-    bool fboFound = false;
-#if GR_SUPPORT_GLDESKTOP
-    #if defined(GL_VERSION_3_0) && GL_VERSION_3_0
-    if (!fboFound && major >= 3) { // all of ARB_fbo is in 3.x
-        exts->GenFramebuffers                   = glGenFramebuffers;
-        exts->BindFramebuffer                   = glBindFramebuffer;
-        exts->FramebufferTexture2D              = glFramebufferTexture2D;
-        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
-        exts->DeleteFramebuffers                = glDeleteFramebuffers;
-        exts->RenderbufferStorage               = glRenderbufferStorage;
-        exts->GenRenderbuffers                  = glGenRenderbuffers;
-        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
-        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
-        exts->BindRenderbuffer                  = glBindRenderbuffer;
-        exts->RenderbufferStorageMultisample    = glRenderbufferStorageMultisample;
-        exts->BlitFramebuffer                   = glBlitFramebuffer;
-        fboFound = true;
-    }
-    #endif
-    #if GL_ARB_framebuffer_object
-    if (!fboFound && has_gl_extension("GL_ARB_framebuffer_object")) {
-        // GL_ARB_framebuffer_object doesn't use ARB suffix.
-        GET_PROC(exts, GenFramebuffers);
-        GET_PROC(exts, BindFramebuffer);
-        GET_PROC(exts, FramebufferTexture2D);
-        GET_PROC(exts, CheckFramebufferStatus);
-        GET_PROC(exts, DeleteFramebuffers);
-        GET_PROC(exts, RenderbufferStorage);
-        GET_PROC(exts, GenRenderbuffers);
-        GET_PROC(exts, DeleteRenderbuffers);
-        GET_PROC(exts, FramebufferRenderbuffer);
-        GET_PROC(exts, BindRenderbuffer);
-        GET_PROC(exts, RenderbufferStorageMultisample);
-        GET_PROC(exts, BlitFramebuffer);
-        fboFound = true;
-    }
-    #endif
-    // Mac doesn't declare prototypes for EXT FBO extensions
-    #if GL_EXT_framebuffer_object && !GR_MAC_BUILD
-    if (!fboFound && has_gl_extension("GL_EXT_framebuffer_object")) {
-        GET_SUFFIX_PROC(exts, GenFramebuffers, EXT);
-        GET_SUFFIX_PROC(exts, BindFramebuffer, EXT);
-        GET_SUFFIX_PROC(exts, FramebufferTexture2D, EXT);
-        GET_SUFFIX_PROC(exts, CheckFramebufferStatus, EXT);
-        GET_SUFFIX_PROC(exts, DeleteFramebuffers, EXT);
-        GET_SUFFIX_PROC(exts, RenderbufferStorage, EXT);
-        GET_SUFFIX_PROC(exts, GenRenderbuffers, EXT);
-        GET_SUFFIX_PROC(exts, DeleteRenderbuffers, EXT);
-        GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, EXT);
-        GET_SUFFIX_PROC(exts, BindRenderbuffer, EXT);
-        fboFound = true;
-        // check for fbo ms and fbo blit
-        #if GL_EXT_framebuffer_multisample
-        if (has_gl_extension("GL_EXT_framebuffer_multisample")) {
-            GET_SUFFIX_PROC(exts, RenderbufferStorageMultisample, EXT);
-        }
-        #endif
-        #if GL_EXT_framebuffer_blit
-        if (has_gl_extension("GL_EXT_framebuffer_blit")) {
-            GET_SUFFIX_PROC(exts, BlitFramebuffer, EXT);
-        }
-        #endif
-    }
-    #endif
-    if (!fboFound) {
-        // we require some form of FBO
-        GrAssert(!"No FBOs supported?");
-    }
-    // we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)
-    exts->MapBuffer     = glMapBuffer;
-    exts->UnmapBuffer   = glUnmapBuffer;
-#else // !GR_SUPPORT_GLDESKTOP
-    #if GR_SUPPORT_GLES2
-    if (!fboFound && major >= 2) {// ES 2.0 supports FBO
-        exts->GenFramebuffers                   = glGenFramebuffers;
-        exts->BindFramebuffer                   = glBindFramebuffer;
-        exts->FramebufferTexture2D              = glFramebufferTexture2D;
-        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
-        exts->DeleteFramebuffers                = glDeleteFramebuffers;
-        exts->RenderbufferStorage               = glRenderbufferStorage;
-        exts->GenRenderbuffers                  = glGenRenderbuffers;
-        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
-        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
-        exts->BindRenderbuffer                  = glBindRenderbuffer;
-        fboFound = true;
-    }
-    #endif
-    #if GL_OES_framebuffer_object
-    if (!fboFound && has_gl_extension("GL_OES_framebuffer_object")) {
-        GET_SUFFIX_PROC(exts, GenFramebuffers, OES);
-        GET_SUFFIX_PROC(exts, BindFramebuffer, OES);
-        GET_SUFFIX_PROC(exts, FramebufferTexture2D, OES);
-        GET_SUFFIX_PROC(exts, CheckFramebufferStatus, OES);
-        GET_SUFFIX_PROC(exts, DeleteFramebuffers, OES);
-        GET_SUFFIX_PROC(exts, RenderbufferStorage, OES);
-        GET_SUFFIX_PROC(exts, GenRenderbuffers, OES);
-        GET_SUFFIX_PROC(exts, DeleteRenderbuffers, OES);
-        GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, OES);
-        GET_SUFFIX_PROC(exts, BindRenderbuffer, OES);
-    }
-    #endif
-
-    if (!fboFound) {
-        // we require some form of FBO
-        GrAssert(!"No FBOs supported?");
-    }
-
-    #if GL_APPLE_framebuffer_multisample
-    if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
-        GET_SUFFIX_PROC(exts, ResolveMultisampleFramebuffer, APPLE);
-    }
-    #endif
-
-    #if GL_IMG_multisampled_render_to_texture
-    if (has_gl_extension("GL_IMG_multisampled_render_to_texture")) {
-        GET_SUFFIX_PROC(exts, FramebufferTexture2DMultisample, IMG);
-    }
-    #endif
-
-    #if GL_OES_mapbuffer
-    if (has_gl_extension("GL_OES_mapbuffer")) {
-        GET_SUFFIX_PROC(exts, MapBuffer, OES);
-        GET_SUFFIX_PROC(exts, UnmapBuffer, OES);
-    }
-    #endif
-#endif // !GR_SUPPORT_GLDESKTOP
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrGLCheckErr(const char* location, const char* call) {
-    uint32_t err =  glGetError();
-    if (GL_NO_ERROR != err) {
-        GrPrintf("---- glGetError %x", err);
-        if (NULL != location) {
-            GrPrintf(" at\n\t%s", location);
-        }
-        if (NULL != call) {
-            GrPrintf("\n\t\t%s", call);
-        }
-        GrPrintf("\n");
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
-
-bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
+/*
+ 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.
+ */
+
+#include "GrGLConfig.h"
+#include "GrTypes.h"
+#include <stdio.h>
+
+bool has_gl_extension(const char* ext) {
+    const char* glstr = (const char*) glGetString(GL_EXTENSIONS);
+
+    int extLength = strlen(ext);
+
+    while (true) {
+        int n = strcspn(glstr, " ");
+        if (n == extLength && 0 == strncmp(ext, glstr, n)) {
+            return true;
+        }
+        if (0 == glstr[n]) {
+            return false;
+        }
+        glstr += n+1;
+    }
+}
+
+void gl_version(int* major, int* minor) {
+    const char* v = (const char*) glGetString(GL_VERSION);
+    if (NULL == v) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#if GR_SUPPORT_GLDESKTOP
+    int n = sscanf(v, "%d.%d", major, minor);
+    if (n != 2) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#else
+    char profile[2];
+    int n = sscanf(v, "OpenGL ES-%c%c %d.%d", profile, profile+1, major, minor);
+    bool ok = 4 == n;
+    if (!ok) {
+        int n = sscanf(v, "OpenGL ES %d.%d", major, minor);
+        ok = 2 == n;
+    }
+    if (!ok) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#endif
+}
+
+#if defined(GR_GL_PROC_ADDRESS_HEADER)
+    #include GR_GL_PROC_ADDRESS_HEADER
+#endif
+
+typedef void (*glProc)(void);
+
+#define GET_PROC(EXT_STRUCT, PROC_NAME) \
+    *(GrTCast<glProc*>(&(EXT_STRUCT-> PROC_NAME))) = (glProc)GR_GL_PROC_ADDRESS((gl ## PROC_NAME)); \
+    GrAssert(NULL != EXT_STRUCT-> PROC_NAME)
+
+#define GET_SUFFIX_PROC(EXT_STRUCT, PROC_NAME, SUFFIX) \
+    *(GrTCast<glProc*>(&(EXT_STRUCT-> PROC_NAME))) = (glProc)GR_GL_PROC_ADDRESS((gl ## PROC_NAME ## SUFFIX)); \
+    GrAssert(NULL != EXT_STRUCT-> PROC_NAME)
+
+extern void GrGLInitExtensions(GrGLExts* exts) {
+    exts->GenFramebuffers                   = NULL;
+    exts->BindFramebuffer                   = NULL;
+    exts->FramebufferTexture2D              = NULL;
+    exts->CheckFramebufferStatus            = NULL;
+    exts->DeleteFramebuffers                = NULL;
+    exts->RenderbufferStorage               = NULL;
+    exts->GenRenderbuffers                  = NULL;
+    exts->DeleteRenderbuffers               = NULL;
+    exts->FramebufferRenderbuffer           = NULL;
+    exts->BindRenderbuffer                  = NULL;
+    exts->RenderbufferStorageMultisample    = NULL;
+    exts->BlitFramebuffer                   = NULL;
+    exts->ResolveMultisampleFramebuffer     = NULL;
+    exts->FramebufferTexture2DMultisample   = NULL;
+    exts->MapBuffer                         = NULL;
+    exts->UnmapBuffer                       = NULL;
+
+    GLint major, minor;
+    gl_version(&major, &minor);
+
+    bool fboFound = false;
+#if GR_SUPPORT_GLDESKTOP
+    #if defined(GL_VERSION_3_0) && GL_VERSION_3_0
+    if (!fboFound && major >= 3) { // all of ARB_fbo is in 3.x
+        exts->GenFramebuffers                   = glGenFramebuffers;
+        exts->BindFramebuffer                   = glBindFramebuffer;
+        exts->FramebufferTexture2D              = glFramebufferTexture2D;
+        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
+        exts->DeleteFramebuffers                = glDeleteFramebuffers;
+        exts->RenderbufferStorage               = glRenderbufferStorage;
+        exts->GenRenderbuffers                  = glGenRenderbuffers;
+        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
+        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
+        exts->BindRenderbuffer                  = glBindRenderbuffer;
+        exts->RenderbufferStorageMultisample    = glRenderbufferStorageMultisample;
+        exts->BlitFramebuffer                   = glBlitFramebuffer;
+        fboFound = true;
+    }
+    #endif
+    #if GL_ARB_framebuffer_object
+    if (!fboFound && has_gl_extension("GL_ARB_framebuffer_object")) {
+        // GL_ARB_framebuffer_object doesn't use ARB suffix.
+        GET_PROC(exts, GenFramebuffers);
+        GET_PROC(exts, BindFramebuffer);
+        GET_PROC(exts, FramebufferTexture2D);
+        GET_PROC(exts, CheckFramebufferStatus);
+        GET_PROC(exts, DeleteFramebuffers);
+        GET_PROC(exts, RenderbufferStorage);
+        GET_PROC(exts, GenRenderbuffers);
+        GET_PROC(exts, DeleteRenderbuffers);
+        GET_PROC(exts, FramebufferRenderbuffer);
+        GET_PROC(exts, BindRenderbuffer);
+        GET_PROC(exts, RenderbufferStorageMultisample);
+        GET_PROC(exts, BlitFramebuffer);
+        fboFound = true;
+    }
+    #endif
+    // Mac doesn't declare prototypes for EXT FBO extensions
+    #if GL_EXT_framebuffer_object && !GR_MAC_BUILD
+    if (!fboFound && has_gl_extension("GL_EXT_framebuffer_object")) {
+        GET_SUFFIX_PROC(exts, GenFramebuffers, EXT);
+        GET_SUFFIX_PROC(exts, BindFramebuffer, EXT);
+        GET_SUFFIX_PROC(exts, FramebufferTexture2D, EXT);
+        GET_SUFFIX_PROC(exts, CheckFramebufferStatus, EXT);
+        GET_SUFFIX_PROC(exts, DeleteFramebuffers, EXT);
+        GET_SUFFIX_PROC(exts, RenderbufferStorage, EXT);
+        GET_SUFFIX_PROC(exts, GenRenderbuffers, EXT);
+        GET_SUFFIX_PROC(exts, DeleteRenderbuffers, EXT);
+        GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, EXT);
+        GET_SUFFIX_PROC(exts, BindRenderbuffer, EXT);
+        fboFound = true;
+        // check for fbo ms and fbo blit
+        #if GL_EXT_framebuffer_multisample
+        if (has_gl_extension("GL_EXT_framebuffer_multisample")) {
+            GET_SUFFIX_PROC(exts, RenderbufferStorageMultisample, EXT);
+        }
+        #endif
+        #if GL_EXT_framebuffer_blit
+        if (has_gl_extension("GL_EXT_framebuffer_blit")) {
+            GET_SUFFIX_PROC(exts, BlitFramebuffer, EXT);
+        }
+        #endif
+    }
+    #endif
+    if (!fboFound) {
+        // we require some form of FBO
+        GrAssert(!"No FBOs supported?");
+    }
+    // we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)
+    exts->MapBuffer     = glMapBuffer;
+    exts->UnmapBuffer   = glUnmapBuffer;
+#else // !GR_SUPPORT_GLDESKTOP
+    #if GR_SUPPORT_GLES2
+    if (!fboFound && major >= 2) {// ES 2.0 supports FBO
+        exts->GenFramebuffers                   = glGenFramebuffers;
+        exts->BindFramebuffer                   = glBindFramebuffer;
+        exts->FramebufferTexture2D              = glFramebufferTexture2D;
+        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
+        exts->DeleteFramebuffers                = glDeleteFramebuffers;
+        exts->RenderbufferStorage               = glRenderbufferStorage;
+        exts->GenRenderbuffers                  = glGenRenderbuffers;
+        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
+        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
+        exts->BindRenderbuffer                  = glBindRenderbuffer;
+        fboFound = true;
+    }
+    #endif
+    #if GL_OES_framebuffer_object
+    if (!fboFound && has_gl_extension("GL_OES_framebuffer_object")) {
+        GET_SUFFIX_PROC(exts, GenFramebuffers, OES);
+        GET_SUFFIX_PROC(exts, BindFramebuffer, OES);
+        GET_SUFFIX_PROC(exts, FramebufferTexture2D, OES);
+        GET_SUFFIX_PROC(exts, CheckFramebufferStatus, OES);
+        GET_SUFFIX_PROC(exts, DeleteFramebuffers, OES);
+        GET_SUFFIX_PROC(exts, RenderbufferStorage, OES);
+        GET_SUFFIX_PROC(exts, GenRenderbuffers, OES);
+        GET_SUFFIX_PROC(exts, DeleteRenderbuffers, OES);
+        GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, OES);
+        GET_SUFFIX_PROC(exts, BindRenderbuffer, OES);
+    }
+    #endif
+
+    if (!fboFound) {
+        // we require some form of FBO
+        GrAssert(!"No FBOs supported?");
+    }
+
+    #if GL_APPLE_framebuffer_multisample
+    if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
+        GET_SUFFIX_PROC(exts, ResolveMultisampleFramebuffer, APPLE);
+    }
+    #endif
+
+    #if GL_IMG_multisampled_render_to_texture
+    if (has_gl_extension("GL_IMG_multisampled_render_to_texture")) {
+        GET_SUFFIX_PROC(exts, FramebufferTexture2DMultisample, IMG);
+    }
+    #endif
+
+    #if GL_OES_mapbuffer
+    if (has_gl_extension("GL_OES_mapbuffer")) {
+        GET_SUFFIX_PROC(exts, MapBuffer, OES);
+        GET_SUFFIX_PROC(exts, UnmapBuffer, OES);
+    }
+    #endif
+#endif // !GR_SUPPORT_GLDESKTOP
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrGLCheckErr(const char* location, const char* call) {
+    uint32_t err =  glGetError();
+    if (GL_NO_ERROR != err) {
+        GrPrintf("---- glGetError %x", err);
+        if (NULL != location) {
+            GrPrintf(" at\n\t%s", location);
+        }
+        if (NULL != call) {
+            GrPrintf("\n\t\t%s", call);
+        }
+        GrPrintf("\n");
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
+
+bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
diff --git a/gpu/src/GrMatrix.cpp b/gpu/src/GrMatrix.cpp
index ee20679..0a2d1b2 100644
--- a/gpu/src/GrMatrix.cpp
+++ b/gpu/src/GrMatrix.cpp
@@ -1,729 +1,729 @@
-/*
-    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.
- */
-
-
-#include "GrMatrix.h"
-#include "GrRect.h"
-#include <stddef.h>
-
-#if GR_SCALAR_IS_FLOAT
-    const GrScalar GrMatrix::gRESCALE(GR_Scalar1);
-#else
-    GR_STATIC_ASSERT(GR_SCALAR_IS_FIXED);
-    // fixed point isn't supported right now
-    GR_STATIC_ASSERT(false);
-const GrScalar GrMatrix::gRESCALE(1 << 30);
-#endif
-
-const GrMatrix::MapProc GrMatrix::gMapProcs[] = {
-// Scales are not both zero
-    &GrMatrix::mapIdentity,
-    &GrMatrix::mapScale,
-    &GrMatrix::mapTranslate,
-    &GrMatrix::mapScaleAndTranslate,
-    &GrMatrix::mapSkew,
-    &GrMatrix::mapScaleAndSkew,
-    &GrMatrix::mapSkewAndTranslate,
-    &GrMatrix::mapNonPerspective,
-    // no optimizations for perspective matrices
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapPerspective,
-
-// Scales are zero (every other is invalid because kScale_TypeBit must be set if
-// kZeroScale_TypeBit is set)
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapZero,
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapSetToTranslate,
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapSwappedScale,
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapSwappedScaleAndTranslate,
-
-    // no optimizations for perspective matrices
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapZero,
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapPerspective,
-    &GrMatrix::mapInvalid,
-    &GrMatrix::mapPerspective,
-};
-
-void GrMatrix::setIdentity() {
-    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = 0;
-    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = 0;
-    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
-    fTypeMask = 0;
-}
-
-void GrMatrix::setTranslate(GrScalar dx, GrScalar dy) {
-    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = dx;
-    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = dy;
-    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
-    fTypeMask = (0 != dx || 0 != dy) ? kTranslate_TypeBit : 0;
-}
-
-void GrMatrix::setScale(GrScalar sx, GrScalar sy) {
-    fM[0] = sx; fM[1] = 0;  fM[2] = 0;
-    fM[3] = 0;  fM[4] = sy; fM[5] = 0;
-    fM[6] = 0;  fM[7] = 0;  fM[8] = gRESCALE;
-    fTypeMask = (GR_Scalar1 != sx || GR_Scalar1 != sy) ? kScale_TypeBit : 0;
-}
-
-void GrMatrix::setSkew(GrScalar skx, GrScalar sky) {
-    fM[0] = GR_Scalar1; fM[1] = skx;        fM[2] = 0;
-    fM[3] = sky;        fM[4] = GR_Scalar1; fM[5] = 0;
-    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
-    fTypeMask = (0 != skx || 0 != sky) ? kSkew_TypeBit : 0;
-}
-
-void GrMatrix::setConcat(const GrMatrix& a, const GrMatrix& b) {
-    if (a.isIdentity()) {
-        if (this != &b) {
-            for (int i = 0; i < 9; ++i) {
-                fM[i] = b.fM[i];
-            }
-            fTypeMask = b.fTypeMask;
-        }
-        return;
-    }
-
-    if (b.isIdentity()) {
-        GrAssert(!a.isIdentity());
-        if (this != &a) {
-            for (int i = 0; i < 9; ++i) {
-                    fM[i] = a.fM[i];
-            }
-            fTypeMask = a.fTypeMask;
-        }
-        return;
-    }
-
-    // a and/or b could be this
-    GrMatrix tmp;
-
-    // could do more optimizations based on type bits. Hopefully this call is
-    // low frequency.
-    // TODO: make this work for fixed point
-    if (!((b.fTypeMask | a.fTypeMask) & kPerspective_TypeBit)) {
-        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3];
-        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4];
-        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * gRESCALE;
-
-        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3];
-        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4];
-        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * gRESCALE;
-
-        tmp.fM[6] = 0;
-        tmp.fM[7] = 0;
-        tmp.fM[8] = gRESCALE * gRESCALE;
-    } else {
-        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3] + a.fM[2] * b.fM[6];
-        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4] + a.fM[2] * b.fM[7];
-        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * b.fM[8];
-
-        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3] + a.fM[5] * b.fM[6];
-        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4] + a.fM[5] * b.fM[7];
-        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * b.fM[8];
-
-        tmp.fM[6] = a.fM[6] * b.fM[0] + a.fM[7] * b.fM[3] + a.fM[8] * b.fM[6];
-        tmp.fM[7] = a.fM[6] * b.fM[1] + a.fM[7] * b.fM[4] + a.fM[8] * b.fM[7];
-        tmp.fM[8] = a.fM[6] * b.fM[2] + a.fM[7] * b.fM[5] + a.fM[8] * b.fM[8];
-    }
-    *this = tmp;
-    this->computeTypeMask();
-}
-
-void GrMatrix::preConcat(const GrMatrix& m) {
-    setConcat(*this, m);
-}
-
-void GrMatrix::postConcat(const GrMatrix& m) {
-    setConcat(m, *this);
-}
-
-double GrMatrix::determinant() const {
-    if (fTypeMask & kPerspective_TypeBit) {
-        return  fM[0]*((double)fM[4]*fM[8] - (double)fM[5]*fM[7]) +
-                fM[1]*((double)fM[5]*fM[6] - (double)fM[3]*fM[8]) +
-                fM[2]*((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
-    } else {
-        return (double)fM[0]*fM[4]*gRESCALE -
-               (double)fM[1]*fM[3]*gRESCALE;
-    }
-}
-
-bool GrMatrix::invert(GrMatrix* inverted) const {
-
-    if (isIdentity()) {
-        if (inverted != this) {
-            inverted->setIdentity();
-        }
-        return true;
-    }
-    static const double MIN_DETERMINANT_SQUARED = 1.e-16;
-
-    // could do more optimizations based on type bits. Hopefully this call is
-    // low frequency.
-
-    double det = determinant();
-
-    // check if we can't be inverted
-    if (det*det <= MIN_DETERMINANT_SQUARED) {
-        return false;
-    } else if (NULL == inverted) {
-        return true;
-    }
-
-    double t[9];
-
-    if (fTypeMask & kPerspective_TypeBit) {
-        t[0] = ((double)fM[4]*fM[8] - (double)fM[5]*fM[7]);
-        t[1] = ((double)fM[2]*fM[7] - (double)fM[1]*fM[8]);
-        t[2] = ((double)fM[1]*fM[5] - (double)fM[2]*fM[4]);
-        t[3] = ((double)fM[5]*fM[6] - (double)fM[3]*fM[8]);
-        t[4] = ((double)fM[0]*fM[8] - (double)fM[2]*fM[6]);
-        t[5] = ((double)fM[2]*fM[3] - (double)fM[0]*fM[5]);
-        t[6] = ((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
-        t[7] = ((double)fM[1]*fM[6] - (double)fM[0]*fM[7]);
-        t[8] = ((double)fM[0]*fM[4] - (double)fM[1]*fM[3]);
-        det = 1.0 / det;
-        for (int i = 0; i < 9; ++i) {
-            inverted->fM[i] = (GrScalar)(t[i] * det);
-        }
-    } else {
-        t[0] =  (double)fM[4]*gRESCALE;
-        t[1] = -(double)fM[1]*gRESCALE;
-        t[2] =  (double)fM[1]*fM[5] - (double)fM[2]*fM[4];
-        t[3] = -(double)fM[3]*gRESCALE;
-        t[4] =  (double)fM[0]*gRESCALE;
-        t[5] =  (double)fM[2]*fM[3] - (double)fM[0]*fM[5];
-        //t[6] = 0.0;
-        //t[7] = 0.0;
-        t[8] = (double)fM[0]*fM[4] - (double)fM[1]*fM[3];
-        det = 1.0 / det;
-        for (int i = 0; i < 6; ++i) {
-            inverted->fM[i] = (GrScalar)(t[i] * det);
-        }
-        inverted->fM[6] = 0;
-        inverted->fM[7] = 0;
-        inverted->fM[8] = (GrScalar)(t[8] * det);
-    }
-    inverted->computeTypeMask();
-    return true;
-}
-
-void GrMatrix::mapRect(GrRect* dst, const GrRect& src) const {
-    GrPoint srcPts[4], dstPts[4];
-    srcPts[0].set(src.fLeft, src.fTop);
-    srcPts[1].set(src.fRight, src.fTop);
-    srcPts[2].set(src.fRight, src.fBottom);
-    srcPts[3].set(src.fLeft, src.fBottom);
-    this->mapPoints(dstPts, srcPts, 4);
-    dst->setBounds(dstPts, 4);
-}
-
-bool GrMatrix::hasPerspective() const {
-    GrAssert(!!(kPerspective_TypeBit & fTypeMask) ==
-             (fM[kPersp0] != 0 || fM[kPersp1] != 0 || fM[kPersp2] != gRESCALE));
-    return 0 != (kPerspective_TypeBit & fTypeMask);
-}
-
-bool GrMatrix::isIdentity() const {
-    GrAssert((0 == fTypeMask) ==
-             (GR_Scalar1 == fM[kScaleX] && 0          == fM[kSkewX]  && 0          == fM[kTransX] &&
-              0          == fM[kSkewY]  && GR_Scalar1 == fM[kScaleY] && 0          == fM[kTransY] &&
-              0          == fM[kPersp0] && 0          == fM[kPersp1] && gRESCALE == fM[kPersp2]));
-    return (0 == fTypeMask);
-}
-
-
-GrScalar GrMatrix::getMaxStretch() const {
-
-    if (fTypeMask & kPerspective_TypeBit) {
-        return -GR_Scalar1;
-    }
-
-    GrScalar stretch;
-
-    if (isIdentity()) {
-        stretch = GR_Scalar1;
-    } else if (!(fTypeMask & kSkew_TypeBit)) {
-        stretch = GrMax(GrScalarAbs(fM[kScaleX]), GrScalarAbs(fM[kScaleY]));
-    } else if (fTypeMask & kZeroScale_TypeBit) {
-        stretch = GrMax(GrScalarAbs(fM[kSkewX]), GrScalarAbs(fM[kSkewY]));
-    } else {
-        // ignore the translation part of the matrix, just look at 2x2 portion.
-        // compute singular values, take largest abs value.
-        // [a b; b c] = A^T*A
-        GrScalar a = GrMul(fM[kScaleX], fM[kScaleX]) + GrMul(fM[kSkewY],  fM[kSkewY]);
-        GrScalar b = GrMul(fM[kScaleX], fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kSkewY]);
-        GrScalar c = GrMul(fM[kSkewX],  fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kScaleY]);
-        // eigenvalues of A^T*A are the squared singular values of A.
-        // characteristic equation is det((A^T*A) - l*I) = 0
-        // l^2 - (a + c)l + (ac-b^2)
-        // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
-        // and roots are guaraunteed to be pos and real).
-        GrScalar largerRoot;
-        GrScalar bSqd = GrMul(b,b);
-        // TODO: fixed point tolerance value.
-        if (bSqd < 1e-10) { // will be true if upper left 2x2 is orthogonal, which is common, so save some math
-            largerRoot = GrMax(a, c);
-        } else {
-            GrScalar aminusc = a - c;
-            GrScalar apluscdiv2 = (a + c) / 2;
-            GrScalar x = sqrtf(GrMul(aminusc,aminusc) + GrMul(4,(bSqd))) / 2;
-            largerRoot = apluscdiv2 + x;
-        }
-
-        stretch = sqrtf(largerRoot);
-    }
-#if GR_DEBUG && 0
-    // test a bunch of vectors. None should be scaled by more than stretch
-    // (modulo some error) and we should find a vector that is scaled by almost
-    // stretch.
-    GrPoint pt;
-    GrScalar max = 0;
-    for (int i = 0; i < 1000; ++i) {
-        GrScalar x = (float)rand() / RAND_MAX;
-        GrScalar y = sqrtf(1 - (x*x));
-        pt.fX = fM[kScaleX]*x + fM[kSkewX]*y;
-        pt.fY = fM[kSkewY]*x + fM[kScaleY]*y;
-        GrScalar d = pt.distanceToOrigin();
-        GrAssert(d <= (1.0001 * stretch));
-        max = GrMax(max, pt.distanceToOrigin());
-    }
-    GrAssert((stretch - max) < .05*stretch);
-#endif
-    return stretch;
-}
-
-bool GrMatrix::operator == (const GrMatrix& m) const {
-    if (fTypeMask != m.fTypeMask) {
-        return false;
-    }
-    if (!fTypeMask) {
-        return true;
-    }
-    for (int i = 0; i < 9; ++i) {
-        if (m.fM[i] != fM[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-bool GrMatrix::operator != (const GrMatrix& m) const {
-    return !(*this == m);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Matrix transformation procs
-//////
-
-void GrMatrix::mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    if (src != dst) {
-        for (uint32_t i = 0; i < count; ++i) {
-            dst[i] = src[i];
-        }
-    }
-}
-
-void GrMatrix::mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    for (uint32_t i = 0; i < count; ++i) {
-        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]);
-        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]);
-    }
-}
-
-
-void GrMatrix::mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    for (uint32_t i = 0; i < count; ++i) {
-        dst[i].fX = src[i].fX + fM[kTransX];
-        dst[i].fY = src[i].fY + fM[kTransY];
-    }
-}
-
-void GrMatrix::mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    for (uint32_t i = 0; i < count; ++i) {
-        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + fM[kTransX];
-        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + fM[kTransY];
-    }
-}
-
-void GrMatrix::mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    if (src != dst) {
-        for (uint32_t i = 0; i < count; ++i) {
-            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
-            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
-        }
-    } else {
-        for (uint32_t i = 0; i < count; ++i) {
-            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
-            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
-            dst[i].fX = newX;
-        }
-    }
-}
-
-void GrMatrix::mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    if (src != dst) {
-        for (uint32_t i = 0; i < count; ++i) {
-            dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
-            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
-        }
-    } else {
-        for (uint32_t i = 0; i < count; ++i) {
-            GrScalar newX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
-            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
-            dst[i].fX = newX;
-        }
-    }
-}
-
-void GrMatrix::mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    if (src != dst) {
-        for (uint32_t i = 0; i < count; ++i) {
-            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
-            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
-        }
-    } else {
-        for (uint32_t i = 0; i < count; ++i) {
-            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
-            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
-            dst[i].fX = newX;
-        }
-    }
-}
-
-void GrMatrix::mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    if (src != dst) {
-        for (uint32_t i = 0; i < count; ++i) {
-            dst[i].fX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
-            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
-        }
-    } else {
-        for (uint32_t i = 0; i < count; ++i) {
-            GrScalar newX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
-            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
-            dst[i].fX = newX;
-        }
-    }
-}
-
-void GrMatrix::mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    for (uint32_t i = 0; i < count; ++i) {
-        GrScalar x, y, w;
-        x = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
-        y = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
-        w = GrMul(fM[kPersp0], src[i].fX) + GrMul(fM[kPersp1], src[i].fY) + fM[kPersp2];
-        // TODO need fixed point invert
-        if (w) {
-            w = 1 / w;
-        }
-        dst[i].fX = GrMul(x, w);
-        dst[i].fY = GrMul(y, w);
-    }
-}
-
-void GrMatrix::mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    GrAssert(0);
-}
-
-void GrMatrix::mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    memset(dst, 0, sizeof(GrPoint)*count);
-}
-
-void GrMatrix::mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    for (uint32_t i = 0; i < count; ++i) {
-        dst[i].fX = fM[kTransX];
-        dst[i].fY = fM[kTransY];
-    }
-}
-
-void GrMatrix::mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    if (src != dst) {
-        for (uint32_t i = 0; i < count; ++i) {
-            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]);
-            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
-        }
-    } else {
-        for (uint32_t i = 0; i < count; ++i) {
-            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]);
-            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
-            dst[i].fX = newX;
-        }
-    }
-}
-
-void GrMatrix::mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
-    if (src != dst) {
-        for (uint32_t i = 0; i < count; ++i) {
-            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
-            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
-        }
-    } else {
-        for (uint32_t i = 0; i < count; ++i) {
-            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
-            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
-            dst[i].fX = newX;
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Unit test
-//////
-
-#include "GrRandom.h"
-
-#if GR_DEBUG
-enum MatrixType {
-    kRotate_MatrixType,
-    kScaleX_MatrixType,
-    kScaleY_MatrixType,
-    kSkewX_MatrixType,
-    kSkewY_MatrixType,
-    kTranslateX_MatrixType,
-    kTranslateY_MatrixType,
-    kSwapScaleXY_MatrixType,
-    kPersp_MatrixType,
-
-    kMatrixTypeCount
-};
-
-static void create_matrix(GrMatrix* matrix, GrRandom& rand) {
-    MatrixType type = (MatrixType)(rand.nextU() % kMatrixTypeCount);
-    switch (type) {
-        case kRotate_MatrixType: {
-            float angle = rand.nextF() * 2 *3.14159265358979323846f;
-            GrScalar cosa = GrFloatToScalar(cosf(angle));
-            GrScalar sina = GrFloatToScalar(sinf(angle));
-            matrix->setAll(cosa,      -sina,           0,
-                           sina,       cosa,           0,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kScaleX_MatrixType: {
-            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
-            matrix->setAll(scale,      0,              0,
-                           0,          GR_Scalar1,     0,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kScaleY_MatrixType: {
-            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
-            matrix->setAll(GR_Scalar1, 0,              0,
-                           0,          scale,          0,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kSkewX_MatrixType: {
-            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
-            matrix->setAll(GR_Scalar1, skew,           0,
-                           0,          GR_Scalar1,     0,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kSkewY_MatrixType: {
-            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
-            matrix->setAll(GR_Scalar1, 0,              0,
-                           skew,       GR_Scalar1,     0,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kTranslateX_MatrixType: {
-            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
-            matrix->setAll(GR_Scalar1, 0,              trans,
-                           0,          GR_Scalar1,     0,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kTranslateY_MatrixType: {
-            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
-            matrix->setAll(GR_Scalar1, 0,              0,
-                           0,          GR_Scalar1,     trans,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kSwapScaleXY_MatrixType: {
-            GrScalar xy = GrFloatToScalar(rand.nextF(-2, 2));
-            GrScalar yx = GrFloatToScalar(rand.nextF(-2, 2));
-            matrix->setAll(0,          xy,             0,
-                           yx,         0,              0,
-                           0,          0,              GrMatrix::I()[8]);
-        } break;
-        case kPersp_MatrixType: {
-            GrScalar p0 = GrFloatToScalar(rand.nextF(-2, 2));
-            GrScalar p1 = GrFloatToScalar(rand.nextF(-2, 2));
-            GrScalar p2 = GrFloatToScalar(rand.nextF(-0.5f, 0.75f));
-            matrix->setAll(GR_Scalar1, 0,              0,
-                           0,          GR_Scalar1,     0,
-                           p0,         p1,             GrMul(p2,GrMatrix::I()[8]));
-        } break;
-        default:
-            GrAssert(0);
-            break;
-    }
-}
-#endif
-
-void GrMatrix::UnitTest() {
-    GrRandom rand;
-
-    // Create a bunch of matrices and test point mapping, max stretch calc,
-    // inversion and multiply-by-inverse.
-#if GR_DEBUG
-    for (int i = 0; i < 10000; ++i) {
-        GrMatrix a, b;
-        a.setIdentity();
-        int num = rand.nextU() % 6;
-        // force testing of I and swapXY
-        if (0 == i) {
-            num = 0;
-            GrAssert(a.isIdentity());
-        } else if (1 == i) {
-            num = 0;
-            a.setAll(0, GR_Scalar1, 0,
-                     GR_Scalar1, 0, 0,
-                     0, 0, I()[8]);
-        }
-        for (int j = 0; j < num; ++j) {
-            create_matrix(&b, rand);
-            a.preConcat(b);
-        }
-
-        GrScalar maxStretch = a.getMaxStretch();
-        if (maxStretch > 0) {
-            maxStretch = GrMul(GR_Scalar1 + GR_Scalar1 / 100, maxStretch);
-        }
-        GrPoint origin = a.mapPoint(GrPoint(0,0));
-
-        for (int j = 0; j < 9; ++j) {
-            int mask, origMask = a.fTypeMask;
-            GrScalar old = a[j];
-
-            a.set(j, GR_Scalar1);
-            mask = a.fTypeMask;
-            a.computeTypeMask();
-            GrAssert(mask == a.fTypeMask);
-
-            a.set(j, 0);
-            mask = a.fTypeMask;
-            a.computeTypeMask();
-            GrAssert(mask == a.fTypeMask);
-
-            a.set(j, 10 * GR_Scalar1);
-            mask = a.fTypeMask;
-            a.computeTypeMask();
-            GrAssert(mask == a.fTypeMask);
-
-            a.set(j, old);
-            GrAssert(a.fTypeMask == origMask);
-        }
-
-        for (int j = 0; j < 100; ++j) {
-            GrPoint pt;
-            pt.fX = GrFloatToScalar(rand.nextF(-10, 10));
-            pt.fY = GrFloatToScalar(rand.nextF(-10, 10));
-
-            GrPoint t0, t1, t2;
-            t0 = a.mapPoint(pt);             // map to a new point
-            t1 = pt;
-            a.mapPoints(&t1, &t1, 1);        // in place
-            a.mapPerspective(&t2, &pt, 1);   // full mult
-            GrAssert(t0 == t1 && t1 == t2);
-            if (maxStretch >= 0.f) {
-                GrVec vec;
-                vec.setBetween(t0, origin);
-                GrScalar stretch = vec.length() / pt.distanceToOrigin();
-                GrAssert(stretch <= maxStretch);
-            }
-        }
-        double det = a.determinant();
-        if (fabs(det) > 1e-3 && a.invert(&b)) {
-            GrMatrix c;
-            c.setConcat(a,b);
-            for (int i = 0; i < 9; ++i) {
-                GrScalar diff = GrScalarAbs(c[i] - I()[i]);
-                GrAssert(diff < (5*GR_Scalar1 / 100));
-            }
-        }
-    }
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-int Gr_clz(uint32_t n) {
-    if (0 == n) {
-        return 32;
-    }
-
-    int count = 0;
-    if (0 == (n & 0xFFFF0000)) {
-        count += 16;
-        n <<= 16;
-    }
-    if (0 == (n & 0xFF000000)) {
-        count += 8;
-        n <<= 8;
-    }
-    if (0 == (n & 0xF0000000)) {
-        count += 4;
-        n <<= 4;
-    }
-    if (0 == (n & 0xC0000000)) {
-        count += 2;
-        n <<= 2;
-    }
-    if (0 == (n & 0x80000000)) {
-        count += 1;
-    }
-    return count;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-#include "GrRect.h"
-
-void GrRect::setBounds(const GrPoint pts[], int count) {
-    if (count <= 0) {
-        this->setEmpty();
-    } else {
-        GrScalar L, R, T, B;
-        L = R = pts[0].fX;
-        T = B = pts[0].fY;
-        for (int i = 1; i < count; i++) {
-            GrScalar x = pts[i].fX;
-            GrScalar y = pts[i].fY;
-            if (x < L) {
-                L = x;
-            } else if (x > R) {
-                R = x;
-            }
-            if (y < T) {
-                T = y;
-            } else if (y > B) {
-                B = y;
-            }
-        }
-        this->setLTRB(L, T, R, B);
-    }
-}
-
-
-
+/*
+    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.
+ */
+
+
+#include "GrMatrix.h"
+#include "GrRect.h"
+#include <stddef.h>
+
+#if GR_SCALAR_IS_FLOAT
+    const GrScalar GrMatrix::gRESCALE(GR_Scalar1);
+#else
+    GR_STATIC_ASSERT(GR_SCALAR_IS_FIXED);
+    // fixed point isn't supported right now
+    GR_STATIC_ASSERT(false);
+const GrScalar GrMatrix::gRESCALE(1 << 30);
+#endif
+
+const GrMatrix::MapProc GrMatrix::gMapProcs[] = {
+// Scales are not both zero
+    &GrMatrix::mapIdentity,
+    &GrMatrix::mapScale,
+    &GrMatrix::mapTranslate,
+    &GrMatrix::mapScaleAndTranslate,
+    &GrMatrix::mapSkew,
+    &GrMatrix::mapScaleAndSkew,
+    &GrMatrix::mapSkewAndTranslate,
+    &GrMatrix::mapNonPerspective,
+    // no optimizations for perspective matrices
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+
+// Scales are zero (every other is invalid because kScale_TypeBit must be set if
+// kZeroScale_TypeBit is set)
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapZero,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSetToTranslate,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSwappedScale,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSwappedScaleAndTranslate,
+
+    // no optimizations for perspective matrices
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapZero,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+};
+
+void GrMatrix::setIdentity() {
+    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = 0;
+    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = 0;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = 0;
+}
+
+void GrMatrix::setTranslate(GrScalar dx, GrScalar dy) {
+    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = dx;
+    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = dy;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = (0 != dx || 0 != dy) ? kTranslate_TypeBit : 0;
+}
+
+void GrMatrix::setScale(GrScalar sx, GrScalar sy) {
+    fM[0] = sx; fM[1] = 0;  fM[2] = 0;
+    fM[3] = 0;  fM[4] = sy; fM[5] = 0;
+    fM[6] = 0;  fM[7] = 0;  fM[8] = gRESCALE;
+    fTypeMask = (GR_Scalar1 != sx || GR_Scalar1 != sy) ? kScale_TypeBit : 0;
+}
+
+void GrMatrix::setSkew(GrScalar skx, GrScalar sky) {
+    fM[0] = GR_Scalar1; fM[1] = skx;        fM[2] = 0;
+    fM[3] = sky;        fM[4] = GR_Scalar1; fM[5] = 0;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = (0 != skx || 0 != sky) ? kSkew_TypeBit : 0;
+}
+
+void GrMatrix::setConcat(const GrMatrix& a, const GrMatrix& b) {
+    if (a.isIdentity()) {
+        if (this != &b) {
+            for (int i = 0; i < 9; ++i) {
+                fM[i] = b.fM[i];
+            }
+            fTypeMask = b.fTypeMask;
+        }
+        return;
+    }
+
+    if (b.isIdentity()) {
+        GrAssert(!a.isIdentity());
+        if (this != &a) {
+            for (int i = 0; i < 9; ++i) {
+                    fM[i] = a.fM[i];
+            }
+            fTypeMask = a.fTypeMask;
+        }
+        return;
+    }
+
+    // a and/or b could be this
+    GrMatrix tmp;
+
+    // could do more optimizations based on type bits. Hopefully this call is
+    // low frequency.
+    // TODO: make this work for fixed point
+    if (!((b.fTypeMask | a.fTypeMask) & kPerspective_TypeBit)) {
+        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3];
+        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4];
+        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * gRESCALE;
+
+        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3];
+        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4];
+        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * gRESCALE;
+
+        tmp.fM[6] = 0;
+        tmp.fM[7] = 0;
+        tmp.fM[8] = gRESCALE * gRESCALE;
+    } else {
+        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3] + a.fM[2] * b.fM[6];
+        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4] + a.fM[2] * b.fM[7];
+        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * b.fM[8];
+
+        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3] + a.fM[5] * b.fM[6];
+        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4] + a.fM[5] * b.fM[7];
+        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * b.fM[8];
+
+        tmp.fM[6] = a.fM[6] * b.fM[0] + a.fM[7] * b.fM[3] + a.fM[8] * b.fM[6];
+        tmp.fM[7] = a.fM[6] * b.fM[1] + a.fM[7] * b.fM[4] + a.fM[8] * b.fM[7];
+        tmp.fM[8] = a.fM[6] * b.fM[2] + a.fM[7] * b.fM[5] + a.fM[8] * b.fM[8];
+    }
+    *this = tmp;
+    this->computeTypeMask();
+}
+
+void GrMatrix::preConcat(const GrMatrix& m) {
+    setConcat(*this, m);
+}
+
+void GrMatrix::postConcat(const GrMatrix& m) {
+    setConcat(m, *this);
+}
+
+double GrMatrix::determinant() const {
+    if (fTypeMask & kPerspective_TypeBit) {
+        return  fM[0]*((double)fM[4]*fM[8] - (double)fM[5]*fM[7]) +
+                fM[1]*((double)fM[5]*fM[6] - (double)fM[3]*fM[8]) +
+                fM[2]*((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
+    } else {
+        return (double)fM[0]*fM[4]*gRESCALE -
+               (double)fM[1]*fM[3]*gRESCALE;
+    }
+}
+
+bool GrMatrix::invert(GrMatrix* inverted) const {
+
+    if (isIdentity()) {
+        if (inverted != this) {
+            inverted->setIdentity();
+        }
+        return true;
+    }
+    static const double MIN_DETERMINANT_SQUARED = 1.e-16;
+
+    // could do more optimizations based on type bits. Hopefully this call is
+    // low frequency.
+
+    double det = determinant();
+
+    // check if we can't be inverted
+    if (det*det <= MIN_DETERMINANT_SQUARED) {
+        return false;
+    } else if (NULL == inverted) {
+        return true;
+    }
+
+    double t[9];
+
+    if (fTypeMask & kPerspective_TypeBit) {
+        t[0] = ((double)fM[4]*fM[8] - (double)fM[5]*fM[7]);
+        t[1] = ((double)fM[2]*fM[7] - (double)fM[1]*fM[8]);
+        t[2] = ((double)fM[1]*fM[5] - (double)fM[2]*fM[4]);
+        t[3] = ((double)fM[5]*fM[6] - (double)fM[3]*fM[8]);
+        t[4] = ((double)fM[0]*fM[8] - (double)fM[2]*fM[6]);
+        t[5] = ((double)fM[2]*fM[3] - (double)fM[0]*fM[5]);
+        t[6] = ((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
+        t[7] = ((double)fM[1]*fM[6] - (double)fM[0]*fM[7]);
+        t[8] = ((double)fM[0]*fM[4] - (double)fM[1]*fM[3]);
+        det = 1.0 / det;
+        for (int i = 0; i < 9; ++i) {
+            inverted->fM[i] = (GrScalar)(t[i] * det);
+        }
+    } else {
+        t[0] =  (double)fM[4]*gRESCALE;
+        t[1] = -(double)fM[1]*gRESCALE;
+        t[2] =  (double)fM[1]*fM[5] - (double)fM[2]*fM[4];
+        t[3] = -(double)fM[3]*gRESCALE;
+        t[4] =  (double)fM[0]*gRESCALE;
+        t[5] =  (double)fM[2]*fM[3] - (double)fM[0]*fM[5];
+        //t[6] = 0.0;
+        //t[7] = 0.0;
+        t[8] = (double)fM[0]*fM[4] - (double)fM[1]*fM[3];
+        det = 1.0 / det;
+        for (int i = 0; i < 6; ++i) {
+            inverted->fM[i] = (GrScalar)(t[i] * det);
+        }
+        inverted->fM[6] = 0;
+        inverted->fM[7] = 0;
+        inverted->fM[8] = (GrScalar)(t[8] * det);
+    }
+    inverted->computeTypeMask();
+    return true;
+}
+
+void GrMatrix::mapRect(GrRect* dst, const GrRect& src) const {
+    GrPoint srcPts[4], dstPts[4];
+    srcPts[0].set(src.fLeft, src.fTop);
+    srcPts[1].set(src.fRight, src.fTop);
+    srcPts[2].set(src.fRight, src.fBottom);
+    srcPts[3].set(src.fLeft, src.fBottom);
+    this->mapPoints(dstPts, srcPts, 4);
+    dst->setBounds(dstPts, 4);
+}
+
+bool GrMatrix::hasPerspective() const {
+    GrAssert(!!(kPerspective_TypeBit & fTypeMask) ==
+             (fM[kPersp0] != 0 || fM[kPersp1] != 0 || fM[kPersp2] != gRESCALE));
+    return 0 != (kPerspective_TypeBit & fTypeMask);
+}
+
+bool GrMatrix::isIdentity() const {
+    GrAssert((0 == fTypeMask) ==
+             (GR_Scalar1 == fM[kScaleX] && 0          == fM[kSkewX]  && 0          == fM[kTransX] &&
+              0          == fM[kSkewY]  && GR_Scalar1 == fM[kScaleY] && 0          == fM[kTransY] &&
+              0          == fM[kPersp0] && 0          == fM[kPersp1] && gRESCALE == fM[kPersp2]));
+    return (0 == fTypeMask);
+}
+
+
+GrScalar GrMatrix::getMaxStretch() const {
+
+    if (fTypeMask & kPerspective_TypeBit) {
+        return -GR_Scalar1;
+    }
+
+    GrScalar stretch;
+
+    if (isIdentity()) {
+        stretch = GR_Scalar1;
+    } else if (!(fTypeMask & kSkew_TypeBit)) {
+        stretch = GrMax(GrScalarAbs(fM[kScaleX]), GrScalarAbs(fM[kScaleY]));
+    } else if (fTypeMask & kZeroScale_TypeBit) {
+        stretch = GrMax(GrScalarAbs(fM[kSkewX]), GrScalarAbs(fM[kSkewY]));
+    } else {
+        // ignore the translation part of the matrix, just look at 2x2 portion.
+        // compute singular values, take largest abs value.
+        // [a b; b c] = A^T*A
+        GrScalar a = GrMul(fM[kScaleX], fM[kScaleX]) + GrMul(fM[kSkewY],  fM[kSkewY]);
+        GrScalar b = GrMul(fM[kScaleX], fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kSkewY]);
+        GrScalar c = GrMul(fM[kSkewX],  fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kScaleY]);
+        // eigenvalues of A^T*A are the squared singular values of A.
+        // characteristic equation is det((A^T*A) - l*I) = 0
+        // l^2 - (a + c)l + (ac-b^2)
+        // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
+        // and roots are guaraunteed to be pos and real).
+        GrScalar largerRoot;
+        GrScalar bSqd = GrMul(b,b);
+        // TODO: fixed point tolerance value.
+        if (bSqd < 1e-10) { // will be true if upper left 2x2 is orthogonal, which is common, so save some math
+            largerRoot = GrMax(a, c);
+        } else {
+            GrScalar aminusc = a - c;
+            GrScalar apluscdiv2 = (a + c) / 2;
+            GrScalar x = sqrtf(GrMul(aminusc,aminusc) + GrMul(4,(bSqd))) / 2;
+            largerRoot = apluscdiv2 + x;
+        }
+
+        stretch = sqrtf(largerRoot);
+    }
+#if GR_DEBUG && 0
+    // test a bunch of vectors. None should be scaled by more than stretch
+    // (modulo some error) and we should find a vector that is scaled by almost
+    // stretch.
+    GrPoint pt;
+    GrScalar max = 0;
+    for (int i = 0; i < 1000; ++i) {
+        GrScalar x = (float)rand() / RAND_MAX;
+        GrScalar y = sqrtf(1 - (x*x));
+        pt.fX = fM[kScaleX]*x + fM[kSkewX]*y;
+        pt.fY = fM[kSkewY]*x + fM[kScaleY]*y;
+        GrScalar d = pt.distanceToOrigin();
+        GrAssert(d <= (1.0001 * stretch));
+        max = GrMax(max, pt.distanceToOrigin());
+    }
+    GrAssert((stretch - max) < .05*stretch);
+#endif
+    return stretch;
+}
+
+bool GrMatrix::operator == (const GrMatrix& m) const {
+    if (fTypeMask != m.fTypeMask) {
+        return false;
+    }
+    if (!fTypeMask) {
+        return true;
+    }
+    for (int i = 0; i < 9; ++i) {
+        if (m.fM[i] != fM[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool GrMatrix::operator != (const GrMatrix& m) const {
+    return !(*this == m);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Matrix transformation procs
+//////
+
+void GrMatrix::mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i] = src[i];
+        }
+    }
+}
+
+void GrMatrix::mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]);
+        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]);
+    }
+}
+
+
+void GrMatrix::mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = src[i].fX + fM[kTransX];
+        dst[i].fY = src[i].fY + fM[kTransY];
+    }
+}
+
+void GrMatrix::mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + fM[kTransX];
+        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + fM[kTransY];
+    }
+}
+
+void GrMatrix::mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        GrScalar x, y, w;
+        x = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+        y = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+        w = GrMul(fM[kPersp0], src[i].fX) + GrMul(fM[kPersp1], src[i].fY) + fM[kPersp2];
+        // TODO need fixed point invert
+        if (w) {
+            w = 1 / w;
+        }
+        dst[i].fX = GrMul(x, w);
+        dst[i].fY = GrMul(y, w);
+    }
+}
+
+void GrMatrix::mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    GrAssert(0);
+}
+
+void GrMatrix::mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    memset(dst, 0, sizeof(GrPoint)*count);
+}
+
+void GrMatrix::mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = fM[kTransX];
+        dst[i].fY = fM[kTransY];
+    }
+}
+
+void GrMatrix::mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Unit test
+//////
+
+#include "GrRandom.h"
+
+#if GR_DEBUG
+enum MatrixType {
+    kRotate_MatrixType,
+    kScaleX_MatrixType,
+    kScaleY_MatrixType,
+    kSkewX_MatrixType,
+    kSkewY_MatrixType,
+    kTranslateX_MatrixType,
+    kTranslateY_MatrixType,
+    kSwapScaleXY_MatrixType,
+    kPersp_MatrixType,
+
+    kMatrixTypeCount
+};
+
+static void create_matrix(GrMatrix* matrix, GrRandom& rand) {
+    MatrixType type = (MatrixType)(rand.nextU() % kMatrixTypeCount);
+    switch (type) {
+        case kRotate_MatrixType: {
+            float angle = rand.nextF() * 2 *3.14159265358979323846f;
+            GrScalar cosa = GrFloatToScalar(cosf(angle));
+            GrScalar sina = GrFloatToScalar(sinf(angle));
+            matrix->setAll(cosa,      -sina,           0,
+                           sina,       cosa,           0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kScaleX_MatrixType: {
+            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(scale,      0,              0,
+                           0,          GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kScaleY_MatrixType: {
+            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           0,          scale,          0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kSkewX_MatrixType: {
+            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, skew,           0,
+                           0,          GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kSkewY_MatrixType: {
+            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           skew,       GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kTranslateX_MatrixType: {
+            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
+            matrix->setAll(GR_Scalar1, 0,              trans,
+                           0,          GR_Scalar1,     0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kTranslateY_MatrixType: {
+            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           0,          GR_Scalar1,     trans,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kSwapScaleXY_MatrixType: {
+            GrScalar xy = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar yx = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(0,          xy,             0,
+                           yx,         0,              0,
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kPersp_MatrixType: {
+            GrScalar p0 = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar p1 = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar p2 = GrFloatToScalar(rand.nextF(-0.5f, 0.75f));
+            matrix->setAll(GR_Scalar1, 0,              0,
+                           0,          GR_Scalar1,     0,
+                           p0,         p1,             GrMul(p2,GrMatrix::I()[8]));
+        } break;
+        default:
+            GrAssert(0);
+            break;
+    }
+}
+#endif
+
+void GrMatrix::UnitTest() {
+    GrRandom rand;
+
+    // Create a bunch of matrices and test point mapping, max stretch calc,
+    // inversion and multiply-by-inverse.
+#if GR_DEBUG
+    for (int i = 0; i < 10000; ++i) {
+        GrMatrix a, b;
+        a.setIdentity();
+        int num = rand.nextU() % 6;
+        // force testing of I and swapXY
+        if (0 == i) {
+            num = 0;
+            GrAssert(a.isIdentity());
+        } else if (1 == i) {
+            num = 0;
+            a.setAll(0, GR_Scalar1, 0,
+                     GR_Scalar1, 0, 0,
+                     0, 0, I()[8]);
+        }
+        for (int j = 0; j < num; ++j) {
+            create_matrix(&b, rand);
+            a.preConcat(b);
+        }
+
+        GrScalar maxStretch = a.getMaxStretch();
+        if (maxStretch > 0) {
+            maxStretch = GrMul(GR_Scalar1 + GR_Scalar1 / 100, maxStretch);
+        }
+        GrPoint origin = a.mapPoint(GrPoint(0,0));
+
+        for (int j = 0; j < 9; ++j) {
+            int mask, origMask = a.fTypeMask;
+            GrScalar old = a[j];
+
+            a.set(j, GR_Scalar1);
+            mask = a.fTypeMask;
+            a.computeTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, 0);
+            mask = a.fTypeMask;
+            a.computeTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, 10 * GR_Scalar1);
+            mask = a.fTypeMask;
+            a.computeTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, old);
+            GrAssert(a.fTypeMask == origMask);
+        }
+
+        for (int j = 0; j < 100; ++j) {
+            GrPoint pt;
+            pt.fX = GrFloatToScalar(rand.nextF(-10, 10));
+            pt.fY = GrFloatToScalar(rand.nextF(-10, 10));
+
+            GrPoint t0, t1, t2;
+            t0 = a.mapPoint(pt);             // map to a new point
+            t1 = pt;
+            a.mapPoints(&t1, &t1, 1);        // in place
+            a.mapPerspective(&t2, &pt, 1);   // full mult
+            GrAssert(t0 == t1 && t1 == t2);
+            if (maxStretch >= 0.f) {
+                GrVec vec;
+                vec.setBetween(t0, origin);
+                GrScalar stretch = vec.length() / pt.distanceToOrigin();
+                GrAssert(stretch <= maxStretch);
+            }
+        }
+        double det = a.determinant();
+        if (fabs(det) > 1e-3 && a.invert(&b)) {
+            GrMatrix c;
+            c.setConcat(a,b);
+            for (int i = 0; i < 9; ++i) {
+                GrScalar diff = GrScalarAbs(c[i] - I()[i]);
+                GrAssert(diff < (5*GR_Scalar1 / 100));
+            }
+        }
+    }
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+int Gr_clz(uint32_t n) {
+    if (0 == n) {
+        return 32;
+    }
+
+    int count = 0;
+    if (0 == (n & 0xFFFF0000)) {
+        count += 16;
+        n <<= 16;
+    }
+    if (0 == (n & 0xFF000000)) {
+        count += 8;
+        n <<= 8;
+    }
+    if (0 == (n & 0xF0000000)) {
+        count += 4;
+        n <<= 4;
+    }
+    if (0 == (n & 0xC0000000)) {
+        count += 2;
+        n <<= 2;
+    }
+    if (0 == (n & 0x80000000)) {
+        count += 1;
+    }
+    return count;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#include "GrRect.h"
+
+void GrRect::setBounds(const GrPoint pts[], int count) {
+    if (count <= 0) {
+        this->setEmpty();
+    } else {
+        GrScalar L, R, T, B;
+        L = R = pts[0].fX;
+        T = B = pts[0].fY;
+        for (int i = 1; i < count; i++) {
+            GrScalar x = pts[i].fX;
+            GrScalar y = pts[i].fY;
+            if (x < L) {
+                L = x;
+            } else if (x > R) {
+                R = x;
+            }
+            if (y < T) {
+                T = y;
+            } else if (y > B) {
+                B = y;
+            }
+        }
+        this->setLTRB(L, T, R, B);
+    }
+}
+
+
+
