Fix line endings in Gr files and set svn eol style to LF


git-svn-id: http://skia.googlecode.com/svn/trunk@832 2bbb7eff-a529-9590-31e7-b0007b416f81
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);
+    }
+}
+
+
+