Rev the GrContext interface. Context has draw* functions that take a new GrPaint object. Removed many of the lower-level GrGpu function call-throughs on context.

Remove unused/unsupported point size (we don't draw non-hairline points using GL points).
Change current* getter functions to get* for consistency.
Fix bounds when drawing inverse-filled paths.


git-svn-id: http://skia.googlecode.com/svn/trunk@718 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index fdf0e9f..c2838b8 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -19,16 +19,14 @@
 

 #include "GrClip.h"

 #include "GrGpu.h"

-#include "GrSamplerState.h"

 #include "GrTextureCache.h"

 #include "GrInOrderDrawBuffer.h"

 #include "GrVertexBufferAllocPool.h"

+#include "GrPaint.h"

 

 class GrFontCache;

 class GrPathIter;

 

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

-

 class GrContext : public GrRefCnt {

 public:

     /**

@@ -52,6 +50,9 @@
      */

     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.

@@ -108,6 +109,35 @@
                                      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);

+

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

+    // Render targets

+

+    /**

      * Wraps an externally-created rendertarget in a GrRenderTarget.

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

      */

@@ -128,52 +158,91 @@
     }

 

     /**

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

+     * Sets the render target.

+     * @param target    the render target to set. (should not be NULL.)

      */

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

-

-    ///////////////////////////////////////////////////////////////////////////

-

-    GrRenderTarget* currentRenderTarget() const;

-    void getViewMatrix(GrMatrix* m) const;

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

-

     void setRenderTarget(GrRenderTarget* target);

 

-    void setTexture(int stage, GrTexture* texture);

-    void setSamplerState(int stage, const GrSamplerState&);

-    void setTextureMatrix(int stage, const GrMatrix& m);

+    /**

+     * Gets the current render target.

+     * @return the currently bound render target. Should never be NULL.

+     */

+    const GrRenderTarget* getRenderTarget() const;

+    GrRenderTarget* getRenderTarget();

 

-    void setAntiAlias(bool);

-    void setDither(bool);

-    void setAlpha(uint8_t alpha);

-    void setColor(GrColor color);

-    void setPointSize(float size);

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

-    void setViewMatrix(const GrMatrix& m);

-    void setClip(const GrClip&);

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

+    // Matrix state

 

     /**

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

+     * 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 current color.

+     *  Draw everywhere (respecting the clip) with the paint.

      */

-    void drawFull(bool useTexture);

+    void drawPaint(const GrPaint& paint);

 

     /**

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

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

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

-     *  a single pixel thick.

+     *  Draw the rect using a paint.

+     *  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.

+     *  The rects coords are used to access the paint (through texture matrix)

      */

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

+    void drawRect(const GrPaint& paint, const GrRect&, GrScalar strokeWidth = -1);

 

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

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

-    }

+    /**

+     * Maps a rect of paint coordinates onto the a rect of destination

+     * coordinates. The srcRect is transformed by the paint's matrix and the

+     * dstRect is transformed by the context's matrix.

+     */

+    void drawRectToRect(const GrPaint& paint,

+                        const GrRect& dstRect,

+                        const GrRect& srcRect);

 

     /**

      * Path filling rules

@@ -191,16 +260,100 @@
     /**

      * Tessellates and draws a path.

      *

+     * @param paint         describes how to color pixels.

      * @param path          the path to draw

-     * @param paint         the paint to set before drawing

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

-     *                      texture coorindates referencing last texture passed

-     *                      to setTexture.

+     * @param fill          the path filling rule to use.

+     * @param translate     optional additional translation applied to the

+     *                      path.

      */

-    void drawPath(GrPathIter* path,

+    void drawPath(const GrPaint& paint,

+                  GrPathIter* path,

                   PathFills fill,

-                  bool useTexture,

                   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,

+                      GrDrawTarget::PrimitiveType 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,

+                            GrDrawTarget::PrimitiveType 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,

+                            GrDrawTarget::PrimitiveType primitiveType,

+                            const POS_SRC& posSrc);

+    template <typename POS_SRC, typename TEX_SRC>

+    void drawCustomVertices(const GrPaint& paint,

+                            GrDrawTarget::PrimitiveType primitiveType,

+                            const POS_SRC& posSrc,

+                            const TEX_SRC* texCoordSrc);

+    template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>

+    void drawCustomVertices(const GrPaint& paint,

+                            GrDrawTarget::PrimitiveType 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

@@ -227,39 +380,9 @@
     void writePixels(int left, int top, int width, int height,

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

 

-    /* -------------------------------------------------------

-     * Mimicking the GrGpu interface for now

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

-     */

 

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

-

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

-

-    bool reserveAndLockGeometry(GrVertexLayout    vertexLayout,

-                                uint32_t          vertexCount,

-                                uint32_t          indexCount,

-                                void**            vertices,

-                                void**            indices);

-

-    void drawIndexed(GrGpu::PrimitiveType type,

-                     uint32_t startVertex,

-                     uint32_t startIndex,

-                     uint32_t vertexCount,

-                     uint32_t indexCount);

-

-    void drawNonIndexed(GrGpu::PrimitiveType type,

-                        uint32_t startVertex,

-                        uint32_t vertexCount);

-

-    void setVertexSourceToArray(const void* array,

-                                GrVertexLayout vertexLayout);

-    void setIndexSourceToArray(const void* array);

-    void setVertexSourceToBuffer(GrVertexBuffer* buffer,

-                                GrVertexLayout vertexLayout);

-    void setIndexSourceToBuffer(GrIndexBuffer* buffer);

-

-    void releaseReservedGeometry();

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

+    // Statistics

 

     void resetStats();

 

@@ -267,11 +390,14 @@
 

     void printStats() const;

 

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

+    // Helpers

+

     class AutoRenderTarget : ::GrNoncopyable {

     public:

         AutoRenderTarget(GrContext* context, GrRenderTarget* target) {

             fContext = NULL;

-            fPrevTarget = context->currentRenderTarget();

+            fPrevTarget = context->getRenderTarget();

             if (fPrevTarget != target) {

                 context->setRenderTarget(target);

                 fContext = context;

@@ -287,36 +413,12 @@
         GrRenderTarget* fPrevTarget;

     };

 

+

     ///////////////////////////////////////////////////////////////////////////

-

-    /**

-     *  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);

-

-    /* -------------------------------------------------------

-     */

-

-    // Intended only to be used within Ganesh:

+    // Functions intended for internal use only.

     GrGpu* getGpu() { return fGpu; }

     GrFontCache* getFontCache() { return fFontCache; }

-    GrDrawTarget* getTextTarget();

+    GrDrawTarget* getTextTarget(const GrPaint& paint);

     void flushText();

 

     const GrIndexBuffer* quadIndexBuffer() const;

@@ -331,7 +433,11 @@
     GrInOrderDrawBuffer     fTextDrawBuffer;

 

     GrContext(GrGpu* gpu);

+

+    static void SetPaint(const GrPaint& paint, GrDrawTarget* target);

+

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

+    void prepareToDraw(const GrPaint& paint);

 

     void drawClipIntoStencil();

 };

@@ -339,17 +445,17 @@
 /**

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

  */

-class GrAutoViewMatrix : GrNoncopyable {

+class GrAutoMatrix : GrNoncopyable {

 public:

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

-        ctx->getViewMatrix(&fMatrix);

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

+        fMatrix = ctx->getMatrix();

     }

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

-        ctx->getViewMatrix(&fMatrix);

-        ctx->setViewMatrix(matrix);

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

+        fMatrix = ctx->getMatrix();

+        ctx->setMatrix(matrix);

     }

-    ~GrAutoViewMatrix() {

-        fContext->setViewMatrix(fMatrix);

+    ~GrAutoMatrix() {

+        fContext->setMatrix(fMatrix);

     }

 

 private:

@@ -359,3 +465,4 @@
 

 #endif

 

+#include "GrContext_impl.h"

diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h
new file mode 100644
index 0000000..b54e927
--- /dev/null
+++ b/gpu/include/GrContext_impl.h
@@ -0,0 +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,

+                                          GrDrawTarget::PrimitiveType primitiveType,

+                                          const POS_SRC& posSrc,

+                                          const TEX_SRC* texCoordSrc,

+                                          const COL_SRC* colorSrc,

+                                          const IDX_SRC* idxSrc) {

+

+    GrVertexLayout layout = 0;

+

+    GrDrawTarget::AutoReleaseGeometry geo;

+

+    this->prepareToDraw(paint);

+

+    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(fGpu, 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) {

+        fGpu->drawNonIndexed(primitiveType, 0, vertexCount);

+    } else {

+        fGpu->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,

+                                          GrDrawTarget::PrimitiveType 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,

+                                          GrDrawTarget::PrimitiveType 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,

+                                          GrDrawTarget::PrimitiveType 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 3405bb5..ec84cda 100644
--- a/gpu/include/GrDrawTarget.h
+++ b/gpu/include/GrDrawTarget.h
@@ -34,26 +34,26 @@
 class GrDrawTarget : public GrRefCnt {
 public:
     /**
-     * Number of texture stages. Each stage takes as input a color and 
-     * 2D texture coordinates. The color input to the first enabled stage is the 
-     * per-vertex color or the constant color (setColor/setAlpha) if there are no
-     * per-vertex colors. For subsequent stages the input color is the output  
+     * Number of texture stages. Each stage takes as input a color and
+     * 2D texture coordinates. The color input to the first enabled stage is the
+     * per-vertex color or the constant color (setColor/setAlpha) if there are
+     * no per-vertex colors. For subsequent stages the input color is the output
      * color from the previous enabled stage. The output color of each stage is
-     * the input color modulated with the result of a texture lookup. Texture 
+     * the input color modulated with the result of a texture lookup. Texture
      * lookups are specified by a texture (setTexture), a texture matrix
-     * (setTextureMatrix), and a sampler (setSamplerState). Texture coordinates 
+     * (setTextureMatrix), and a sampler (setSamplerState). Texture coordinates
      * for each stage come from the vertices based on a GrVertexLayout bitfield.
      * The output fragment color is the output color of the last enabled stage.
-     * The presence or absence of texture coordinates for each stage in the 
+     * The presence or absence of texture coordinates for each stage in the
      * vertex layout indicates whether a stage is enabled or not.
      */
-    
+
     // Currently there is just one stage but this will be changed soon.
     enum {
         kNumStages = 1,
         kMaxTexCoords = kNumStages
     };
-    
+
     /**
      * Geometric primitives used for drawing.
      */
@@ -154,7 +154,6 @@
         GrSamplerState        	fSamplerStates[kNumStages];
         GrRenderTarget*     	fRenderTarget;
         GrColor             	fColor;
-        float               	fPointSize;
         StencilPass             fStencilPass;
         bool                    fReverseFill;
         GrMatrix                fViewMatrix;
@@ -202,14 +201,13 @@
      *            texture has been set, NULL was most recently passed to
      *            setTexture, or the last setTexture was destroyed.
      */
-    GrTexture* currentTexture(int stage) const;
+    const GrTexture* getTexture(int stage) const;
+    GrTexture* getTexture(int stage);
 
     /**
      * Sets the rendertarget used at the next drawing call
      *
-     * @param target  The render target to set. Must be a valid rendertarget.
-     *                That is it is a value that was returned by
-     *                currentRenderTarget() or GrTexture::asRenderTarget().
+     * @param target  The render target to set.
      */
     void setRenderTarget(GrRenderTarget* target);
 
@@ -218,7 +216,8 @@
      *
      * @return    The currently set render target.
      */
-    GrRenderTarget* currentRenderTarget() const;
+    const GrRenderTarget* getRenderTarget() const;
+    GrRenderTarget* getRenderTarget();
 
     /**
      * Sets the sampler state for the next draw.
@@ -318,13 +317,6 @@
     }
 
     /**
-     * Sets the size of points used the next time points are drawn.
-     *
-     * @param the point size
-     */
-    void setPointSize(float size);
-
-    /**
      * Sets the blending function coeffecients.
      *
      * The blend function will be:
@@ -341,9 +333,9 @@
 
     /**
      * Retrieves the current view matrix
-     * @param matrix will be the current view matrix after return.
+     * return the current view matrix.
      */
-    void getViewMatrix(GrMatrix* matrix) const;
+    const GrMatrix& getViewMatrix() const;
 
     /**
      *  Retrieves the inverse of the current view matrix.
@@ -396,7 +388,7 @@
     /**
      * The format of vertices is represented as a bitfield of flags.
      * Flags that indicate the layout of vertex data. Vertices always contain
-     * positions and may also contain up to kMaxTexCoords sets of 2D texture 
+     * positions and may also contain up to kMaxTexCoords sets of 2D texture
      * coordinates and per-vertex colors. Each stage can use any of the texture
      * coordinates as its input texture coordinates or it may use the positions.
      *
@@ -404,18 +396,18 @@
      * disabled.
      *
      * Only one type of texture coord can be specified per stage. For
-     * example StageTexCoordVertexLayoutBit(0, 2) and 
+     * example StageTexCoordVertexLayoutBit(0, 2) and
      * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
      *
-     * The order in memory is always (position, texture coord 0, ..., color) 
+     * The order in memory is always (position, texture coord 0, ..., color)
      * with any unused fields omitted. Note that this means that if only texture
-     * coordinates 1 is referenced then there is no texture coordinates 0 and 
+     * coordinates 1 is referenced then there is no texture coordinates 0 and
      * the order would be (position, texture coordinate 1[, color]).
      */
-    
+
     /**
      * Generates a bit indicating that a texture stage uses texture coordinates
-     * 
+     *
      * @param stage       the stage that will use texture coordinates.
      * @param texCoordIdx the index of the texture coordinates to use
      *
@@ -433,31 +425,31 @@
      * Generates a bit indicating that a texture stage uses the position
      * as its texture coordinate.
      *
-     * @param stage       the stage that will use position as texture 
+     * @param stage       the stage that will use position as texture
      *                    coordinates.
      *
      * @return the bit to add to a GrVertexLayout bitfield.
      */
     static int StagePosAsTexCoordVertexLayoutBit(int stage) {
         GrAssert(stage < kNumStages);
-        return (1 << (TEX_COORD_BIT_CNT + stage)); 
+        return (1 << (TEX_COORD_BIT_CNT + stage));
     }
 private:
     static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
-    
+
 public:
-    
+
     /**
      * Additional Bits that can be specified in GrVertexLayout.
      */
     enum VertexLayoutBits {
-        
+
         kColor_VertexLayoutBit              = 1 << (STAGE_BIT_CNT + 0),
                                                 //<! vertices have colors
         kTextFormat_VertexLayoutBit         = 1 << (STAGE_BIT_CNT + 1),
                                                 //<! use text vertices. (Pos
                                                 //   and tex coords may be
-                                                //   a different type for 
+                                                //   a different type for
                                                 //   text [GrGpuTextVertex vs
                                                 //   GrPoint].)
         // for below assert
@@ -634,12 +626,33 @@
                                                        &fVertices,
                                                        &fIndices);
         }
+
+        AutoReleaseGeometry() {
+            fSuccess = false;
+        }
+
         ~AutoReleaseGeometry() {
             if (fSuccess) {
                 fTarget->releaseReservedGeometry();
             }
         }
 
+        bool set(GrDrawTarget*  target,
+                 GrVertexLayout vertexLayout,
+                 uint32_t       vertexCount,
+                 uint32_t       indexCount) {
+            if (fSuccess) {
+                fTarget->releaseReservedGeometry();
+            }
+            fTarget = target;
+            fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
+                                                       vertexCount,
+                                                       indexCount,
+                                                       &fVertices,
+                                                       &fIndices);
+            return fSuccess;
+        }
+
         bool succeeded() const { return fSuccess; }
         void* vertices() const { return fVertices; }
         void* indices() const { return fIndices; }
@@ -674,13 +687,13 @@
 
     ////////////////////////////////////////////////////////////////////////////
     // Helpers for picking apart vertex layouts
-    
+
     /**
      * Helper function to compute the size of a vertex from a vertex layout
      * @return size of a single vertex.
      */
     static size_t VertexSize(GrVertexLayout vertexLayout);
-    
+
     /**
      * Helper function for determining the index of texture coordinates that
      * is input for a texture stage. Note that a stage may instead use positions
@@ -698,7 +711,7 @@
     /**
      * Helper function to compute the offset of texture coordinates in a vertex
      * @return offset of texture coordinates in vertex layout or -1 if the
-     *         layout has no texture coordinates. Will be 0 if positions are 
+     *         layout has no texture coordinates. Will be 0 if positions are
      *         used as texture coordinates for the stage.
      */
     static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
@@ -711,18 +724,18 @@
     static int VertexColorOffset(GrVertexLayout vertexLayout);
 
     /**
-     * Helper function to determine if vertex layout contains explicit texture 
+     * Helper function to determine if vertex layout contains explicit texture
      * coordinates of some index.
      *
      * @param coordIndex    the tex coord index to query
      * @param vertexLayout  layout to query
      *
-     * @return true if vertex specifies texture coordinates for the index, 
+     * @return true if vertex specifies texture coordinates for the index,
      *              false otherwise.
      */
-    static bool VertexUsesTexCoordIdx(int coordIndex, 
+    static bool VertexUsesTexCoordIdx(int coordIndex,
                                       GrVertexLayout vertexLayout);
-    
+
     /**
      * Helper function to determine if vertex layout contains either explicit or
      * implicit texture coordinates for a stage.
@@ -730,15 +743,15 @@
      * @param stage         the stage to query
      * @param vertexLayout  layout to query
      *
-     * @return true if vertex specifies texture coordinates for the stage, 
+     * @return true if vertex specifies texture coordinates for the stage,
      *              false otherwise.
      */
     static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
 
     /**
-     * Helper function to compute the size of each vertex and the offsets of 
-     * texture coordinates and color. Determines tex coord offsets by tex coord 
-     * index rather than by stage. (Each stage can be mapped to any t.c. index 
+     * Helper function to compute the size of each vertex and the offsets of
+     * texture coordinates and color. Determines tex coord offsets by tex coord
+     * index rather than by stage. (Each stage can be mapped to any t.c. index
      * by StageTexCoordVertexLayoutBit.)
      *
      * @param vertexLayout          the layout to query
@@ -750,12 +763,12 @@
     static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
                                          int texCoordOffsetsByIdx[kMaxTexCoords],
                                          int *colorOffset);
-    
+
     /**
-     * Helper function to compute the size of each vertex and the offsets of 
-     * texture coordinates and color. Determines tex coord offsets by stage 
-     * rather than by index. (Each stage can be mapped to any t.c. index 
-     * by StageTexCoordVertexLayoutBit.) If a stage uses positions for 
+     * Helper function to compute the size of each vertex and the offsets of
+     * texture coordinates and color. Determines tex coord offsets by stage
+     * rather than by index. (Each stage can be mapped to any t.c. index
+     * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
      * tex coords then that stage's offset will be 0 (positions are always at 0).
      *
      * @param vertexLayout              the layout to query
@@ -768,7 +781,7 @@
                                            int texCoordOffsetsByStage[kNumStages],
                                            int *colorOffset);
 protected:
-    
+
     // Helpers for GrDrawTarget subclasses that won't have private access to
     // SavedDrawState but need to peek at the state values.
     static DrState& accessSavedDrawState(SavedDrawState& sds)
diff --git a/gpu/include/GrPaint.h b/gpu/include/GrPaint.h
new file mode 100644
index 0000000..23902a8
--- /dev/null
+++ b/gpu/include/GrPaint.h
@@ -0,0 +1,106 @@
+/*

+    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 "GrSamplerState.h"

+#include "GrDrawTarget.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)

+    GrDrawTarget::BlendCoeff    fSrcBlendCoeff;

+    GrDrawTarget::BlendCoeff    fDstBlendCoeff;

+    bool                        fAntiAlias;

+    bool                        fDither;

+

+    GrColor                     fColor;

+

+    GrMatrix                    fTextureMatrix;

+    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;

+

+        fTextureMatrix = paint.fTextureMatrix;

+        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 = GrDrawTarget::kOne_BlendCoeff;

+        fDstBlendCoeff = GrDrawTarget::kZero_BlendCoeff;

+    }

+

+    void resetOptions() {

+        fAntiAlias = false;

+        fDither = false;

+    }

+

+    void resetColor() {

+        fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);

+    }

+

+    void resetTexture() {

+        setTexture(NULL);

+        fTextureMatrix = GrMatrix::I();

+        fSampler.setClampNoFilter();

+    }

+

+};

+

+#endif

diff --git a/gpu/include/GrSamplerState.h b/gpu/include/GrSamplerState.h
index 5fb10b9..9715c45 100644
--- a/gpu/include/GrSamplerState.h
+++ b/gpu/include/GrSamplerState.h
@@ -46,27 +46,27 @@
         this->setClampNoFilter();
     }
 
-    GrSamplerState(bool filter) {
+    explicit GrSamplerState(bool filter) {
         fWrapX = kClamp_WrapMode;
         fWrapY = kClamp_WrapMode;
         fSampleMode = kNormal_SampleMode;
         fFilter = filter;
     }
-    
+
     GrSamplerState(WrapMode wx, WrapMode wy, bool filter) {
         fWrapX = wx;
         fWrapY = wy;
         fSampleMode = kNormal_SampleMode;
         fFilter = filter;
     }
-    
+
     GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, bool filter) {
         fWrapX = wx;
         fWrapY = wy;
         fSampleMode = sample;
         fFilter = filter;
     }
-    
+
     WrapMode getWrapX() const { return fWrapX; }
     WrapMode getWrapY() const { return fWrapY; }
     SampleMode getSampleMode() const { return fSampleMode; }
@@ -95,8 +95,8 @@
     bool     isRadial2PosRoot() const { return fRadial2PosRoot; }
 
     /**
-     * Sets the parameters for kRadial2_SampleMode. The texture 
-     * matrix must be set so that the first point is at (0,0) and the second 
+     * Sets the parameters for kRadial2_SampleMode. The texture
+     * matrix must be set so that the first point is at (0,0) and the second
      * point lies on the x-axis. The second radius minus the first is 1 unit.
      * The additional parameters to define the gradient are specified by this
      * function.
diff --git a/gpu/include/GrTextContext.h b/gpu/include/GrTextContext.h
index 6b7446b..d813c09 100644
--- a/gpu/include/GrTextContext.h
+++ b/gpu/include/GrTextContext.h
@@ -27,7 +27,9 @@
 
 class GrTextContext {
 public:
-    GrTextContext(GrContext*, const GrMatrix* extMatrix = NULL);
+    GrTextContext(GrContext*,
+                  const GrPaint& paint,
+                  const GrMatrix* extMatrix = NULL);
     ~GrTextContext();
 
     void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
@@ -36,6 +38,7 @@
     void flush();   // optional; automatically called by destructor
 
 private:
+    const GrPaint&  fPaint;
     GrContext*      fContext;
     GrDrawTarget*   fDrawTarget;
 
@@ -53,7 +56,7 @@
     };
 
     GrGpuTextVertex* fVertices;
-    
+
     int32_t     fMaxVertices;
     GrTexture*  fCurrTexture;
     int         fCurrVertex;
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index ee78848..5e6b824 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -138,17 +138,17 @@
         GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);

 

         if (NULL != texture) {

-            GrGpu::AutoStateRestore asr(fGpu);

+            GrDrawTarget::AutoStateRestore asr(fGpu);

             fGpu->setRenderTarget(texture->asRenderTarget());

             fGpu->setTexture(0, clampEntry->texture());

-            fGpu->setStencilPass(GrGpu::kNone_StencilPass);

+            fGpu->setStencilPass(GrDrawTarget::kNone_StencilPass);

             fGpu->setTextureMatrix(0, GrMatrix::I());

             fGpu->setViewMatrix(GrMatrix::I());

             fGpu->setAlpha(0xff);

-            fGpu->setBlendFunc(GrGpu::kOne_BlendCoeff, GrGpu::kZero_BlendCoeff);

-            fGpu->disableState(GrGpu::kDither_StateBit |

-                               GrGpu::kClip_StateBit   |

-                               GrGpu::kAntialias_StateBit);

+            fGpu->setBlendFunc(GrDrawTarget::kOne_BlendCoeff, GrDrawTarget::kZero_BlendCoeff);

+            fGpu->disableState(GrDrawTarget::kDither_StateBit |

+                               GrDrawTarget::kClip_StateBit   |

+                               GrDrawTarget::kAntialias_StateBit);

             GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,

                                           GrSamplerState::kClamp_WrapMode,

                                           sampler.isFilter());

@@ -171,7 +171,7 @@
                                               clampTexture->contentHeight() /

                                               clampTexture->allocHeight());

                 verts[1].setRectFan(0, 0, tw, th, 2*sizeof(GrPoint));

-                fGpu->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType,

+                fGpu->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType,

                                      0, 4);

                 entry = fTextureCache->createAndLock(*key, texture);

             }

@@ -275,11 +275,24 @@
 

 ////////////////////////////////////////////////////////////////////////////////

 

+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::drawFull(bool useTexture) {

+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());

@@ -289,8 +302,7 @@
     } else {

         GrPrintf("---- fGpu->getViewInverse failed\n");

     }

-

-    this->fillRect(r, useTexture);

+    this->drawRect(paint, r);

 }

 

 /*  create a triangle strip that strokes the specified triangle. There are 8

@@ -314,8 +326,11 @@
     verts[9] = verts[1];

 }

 

-void GrContext::drawRect(const GrRect& rect, bool useTexture, GrScalar width) {

-    GrVertexLayout layout = useTexture ?

+void GrContext::drawRect(const GrPaint& paint,

+                         const GrRect& rect,

+                         GrScalar width) {

+

+    GrVertexLayout layout = (NULL != paint.getTexture()) ?

                             GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :

                             0;

 

@@ -325,21 +340,21 @@
         return;

     }

 

-    this->flushText();

+    this->prepareToDraw(paint);

 

     int vertCount;

-    GrGpu::PrimitiveType primType;

+    GrDrawTarget::PrimitiveType primType;

     GrPoint* vertex = geo.positions();

 

     if (width >= 0) {

         if (width > 0) {

             vertCount = 10;

-            primType = GrGpu::kTriangleStrip_PrimitiveType;

+            primType = GrDrawTarget::kTriangleStrip_PrimitiveType;

             setStrokeRectStrip(vertex, rect, width);

         } else {

             // hairline

             vertCount = 5;

-            primType = GrGpu::kLineStrip_PrimitiveType;

+            primType = GrDrawTarget::kLineStrip_PrimitiveType;

             vertex[0].set(rect.fLeft, rect.fTop);

             vertex[1].set(rect.fRight, rect.fTop);

             vertex[2].set(rect.fRight, rect.fBottom);

@@ -348,13 +363,111 @@
         }

     } else {

         vertCount = 4;

-        primType = GrGpu::kTriangleFan_PrimitiveType;

+        primType = GrDrawTarget::kTriangleFan_PrimitiveType;

         vertex->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);

     }

 

     fGpu->drawNonIndexed(primType, 0, vertCount);

 }

 

+void GrContext::drawRectToRect(const GrPaint& paint,

+                               const GrRect& dstRect,

+                               const GrRect& srcRect) {

+

+    if (NULL == paint.getTexture()) {

+        drawRect(paint, dstRect);

+        return;

+    }

+

+    GrVertexLayout layout = GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);

+    static const int VCOUNT = 4;

+

+    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);

+    if (!geo.succeeded()) {

+        return;

+    }

+

+    this->prepareToDraw(paint);

+

+    GrPoint* vertex = (GrPoint*) geo.vertices();

+

+    vertex[0].setRectFan(dstRect.fLeft, dstRect.fTop,

+                         dstRect.fRight, dstRect.fBottom,

+                         2 * sizeof(GrPoint));

+    vertex[1].setRectFan(srcRect.fLeft, srcRect.fTop,

+                         srcRect.fRight, srcRect.fBottom,

+                         2 * sizeof(GrPoint));

+

+    fGpu->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, 0, VCOUNT);

+}

+

+void GrContext::drawVertices(const GrPaint& paint,

+                             GrDrawTarget::PrimitiveType primitiveType,

+                             int vertexCount,

+                             const GrPoint positions[],

+                             const GrPoint texCoords[],

+                             const GrColor colors[],

+                             const uint16_t indices[],

+                             int indexCount) {

+    GrVertexLayout layout = 0;

+    bool interLeave = false;

+

+    GrDrawTarget::AutoReleaseGeometry geo;

+

+    this->prepareToDraw(paint);

+

+    if (NULL != paint.getTexture()) {

+        if (NULL == texCoords) {

+            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);

+        } else {

+            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);

+            interLeave = true;

+        }

+    }

+

+    if (NULL != colors) {

+        layout |= GrDrawTarget::kColor_VertexLayoutBit;

+    }

+

+    static const GrVertexLayout interleaveMask =

+        (GrDrawTarget::StageTexCoordVertexLayoutBit(0,0) |

+         GrDrawTarget::kColor_VertexLayoutBit);

+    if (interleaveMask & layout) {

+        if (!geo.set(fGpu, 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 {

+        fGpu->setVertexSourceToArray(positions, layout);

+    }

+

+    if (NULL != indices) {

+        fGpu->setIndexSourceToArray(indices);

+        fGpu->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);

+    } else {

+        fGpu->drawNonIndexed(primitiveType, 0, vertexCount);

+    }

+}

+

+

 ////////////////////////////////////////////////////////////////////////////////

 

 #define NEW_EVAL        1   // Use adaptive path tesselation

@@ -533,7 +646,6 @@
 

 static inline bool single_pass_path(const GrPathIter& path,

                                     GrContext::PathFills fill,

-                                    bool useTex,

                                     const GrGpu& gpu) {

 #if STENCIL_OFF

     return true;

@@ -554,16 +666,18 @@
 #endif

 }

 

-void GrContext::drawPath(GrPathIter* path, PathFills fill,

-                         bool useTexture, const GrPoint* translate) {

+void GrContext::drawPath(const GrPaint& paint,

+                         GrPathIter* path,

+                         PathFills fill,

+                         const GrPoint* translate) {

 

-    flushText();

 

-    GrGpu::AutoStateRestore asr(fGpu);

+    this->prepareToDraw(paint);

+

+    GrDrawTarget::AutoStateRestore asr(fGpu);

 

 #if NEW_EVAL

-    GrMatrix viewM;

-    fGpu->getViewMatrix(&viewM);

+    GrMatrix viewM = fGpu->getViewMatrix();

     // In order to tesselate the path we get a bound on how much the matrix can

     // stretch when mapping to screen coordinates.

     GrScalar stretch = viewM.getMaxStretch();

@@ -594,7 +708,8 @@
 #endif

                                         tol);

     GrVertexLayout layout = 0;

-    if (useTexture) {

+

+    if (NULL != paint.getTexture()) {

         layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);

     }

     // add 4 to hold the bounding rect

@@ -609,20 +724,20 @@
     path->rewind();

 

     // TODO: use primitve restart if available rather than multiple draws

-    GrGpu::PrimitiveType  type;

+    GrDrawTarget::PrimitiveType  type;

     int                   passCount = 0;

-    GrGpu::StencilPass    passes[3];

+    GrDrawTarget::StencilPass    passes[3];

     bool                  reverse = false;

 

     if (kHairLine_PathFill == fill) {

-        type = GrGpu::kLineStrip_PrimitiveType;

+        type = GrDrawTarget::kLineStrip_PrimitiveType;

         passCount = 1;

-        passes[0] = GrGpu::kNone_StencilPass;

+        passes[0] = GrDrawTarget::kNone_StencilPass;

     } else {

-        type = GrGpu::kTriangleFan_PrimitiveType;

-        if (single_pass_path(*path, fill, useTexture, *fGpu)) {

+        type = GrDrawTarget::kTriangleFan_PrimitiveType;

+        if (single_pass_path(*path, fill, *fGpu)) {

             passCount = 1;

-            passes[0] = GrGpu::kNone_StencilPass;

+            passes[0] = GrDrawTarget::kNone_StencilPass;

         } else {

             switch (fill) {

                 case kInverseEvenOdd_PathFill:

@@ -630,21 +745,21 @@
                     // fallthrough

                 case kEvenOdd_PathFill:

                     passCount = 2;

-                    passes[0] = GrGpu::kEvenOddStencil_StencilPass;

-                    passes[1] = GrGpu::kEvenOddColor_StencilPass;

+                    passes[0] = GrDrawTarget::kEvenOddStencil_StencilPass;

+                    passes[1] = GrDrawTarget::kEvenOddColor_StencilPass;

                     break;

 

                 case kInverseWinding_PathFill:

                     reverse = true;

                     // fallthrough

                 case kWinding_PathFill:

-                    passes[0] = GrGpu::kWindingStencil1_StencilPass;

+                    passes[0] = GrDrawTarget::kWindingStencil1_StencilPass;

                     if (fGpu->supportsSingleStencilPassWinding()) {

-                        passes[1] = GrGpu::kWindingColor_StencilPass;

+                        passes[1] = GrDrawTarget::kWindingColor_StencilPass;

                         passCount = 2;

                     } else {

-                        passes[1] = GrGpu::kWindingStencil2_StencilPass;

-                        passes[2] = GrGpu::kWindingColor_StencilPass;

+                        passes[1] = GrDrawTarget::kWindingStencil2_StencilPass;

+                        passes[2] = GrDrawTarget::kWindingColor_StencilPass;

                         passCount = 3;

                     }

                     break;

@@ -752,11 +867,15 @@
     if (useBounds) {

         GrRect bounds;

         if (reverse) {

-            GrAssert(NULL != fGpu->currentRenderTarget());

+            GrAssert(NULL != fGpu->getRenderTarget());

             // draw over the whole world.

             bounds.setLTRB(0, 0,

-                           GrIntToScalar(fGpu->currentRenderTarget()->width()),

-                           GrIntToScalar(fGpu->currentRenderTarget()->height()));

+                           GrIntToScalar(fGpu->getRenderTarget()->width()),

+                           GrIntToScalar(fGpu->getRenderTarget()->height()));

+            GrMatrix vmi;

+            if (fGpu->getViewInverse(&vmi)) {

+                vmi.mapRect(&bounds);

+            }

         } else {

             bounds.setBounds((GrPoint*)base, vert - base);

         }

@@ -766,10 +885,11 @@
 

     for (int p = 0; p < passCount; ++p) {

         fGpu->setStencilPass(passes[p]);

-        if (useBounds && (GrGpu::kEvenOddColor_StencilPass == passes[p] ||

-                          GrGpu::kWindingColor_StencilPass == passes[p])) {

-            fGpu->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType,

+        if (useBounds && (GrDrawTarget::kEvenOddColor_StencilPass == passes[p] ||

+                          GrDrawTarget::kWindingColor_StencilPass == passes[p])) {

+            fGpu->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType,

                                  maxPts, 4);

+

         } else {

             int baseVertex = 0;

             for (int sp = 0; sp < subpathCnt; ++sp) {

@@ -782,6 +902,8 @@
     }

 }

 

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

+

 void GrContext::flush(bool flushRenderTarget) {

     flushText();

     if (flushRenderTarget) {

@@ -803,6 +925,10 @@
 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

     };

@@ -830,126 +956,72 @@
     fGpu->setTexture(0, texture);

     fGpu->setSamplerState(0, GrSamplerState::ClampNoFilter());

 

-    this->fillRect(GrRect(0, 0, GrIntToScalar(width), GrIntToScalar(height)),

-                   true);

+    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(GrDrawTarget::kTriangleFan_PrimitiveType, 0, VCOUNT);

+}

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

+

+void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) {

+    target->setTexture(0, paint.getTexture());

+    target->setTextureMatrix(0, paint.fTextureMatrix);

+    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);

+}

+

+void GrContext::prepareToDraw(const GrPaint& paint) {

+

+    flushText();

+    SetPaint(paint, fGpu);

 }

 

 ////////////////////////////////////////////////////////////////////////////////

 

-

-/* -------------------------------------------------------

- * Mimicking the GrGpu interface for now

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

- */

-

 void GrContext::resetContext() {

     fGpu->resetContext();

 }

 

-GrVertexBuffer* GrContext::createVertexBuffer(uint32_t size, bool dynamic) {

-    return fGpu->createVertexBuffer(size, dynamic);

-}

-

-GrIndexBuffer* GrContext::createIndexBuffer(uint32_t size, bool dynamic) {

-    return fGpu->createIndexBuffer(size, dynamic);

-}

-

-void GrContext::setTexture(int stage, GrTexture* texture) {

-    fGpu->setTexture(stage, texture);

-}

-

 void GrContext::setRenderTarget(GrRenderTarget* target) {

     flushText();

     fGpu->setRenderTarget(target);

 }

 

-GrRenderTarget* GrContext::currentRenderTarget() const {

-    return fGpu->currentRenderTarget();

+GrRenderTarget* GrContext::getRenderTarget() {

+    return fGpu->getRenderTarget();

 }

 

-void GrContext::setSamplerState(int stage, const GrSamplerState& samplerState) {

-    fGpu->setSamplerState(stage, samplerState);

+const GrRenderTarget* GrContext::getRenderTarget() const {

+    return fGpu->getRenderTarget();

 }

 

-void GrContext::setTextureMatrix(int stage, const GrMatrix& m) {

-    fGpu->setTextureMatrix(stage, m);

+const GrMatrix& GrContext::getMatrix() const {

+    return fGpu->getViewMatrix();

 }

 

-void GrContext::getViewMatrix(GrMatrix* m) const {

-    fGpu->getViewMatrix(m);

-}

-

-void GrContext::setViewMatrix(const GrMatrix& m) {

+void GrContext::setMatrix(const GrMatrix& m) {

     fGpu->setViewMatrix(m);

 }

 

-bool GrContext::reserveAndLockGeometry(GrVertexLayout    vertexLayout,

-                                       uint32_t          vertexCount,

-                                       uint32_t          indexCount,

-                                       void**            vertices,

-                                       void**            indices) {

-    return fGpu->reserveAndLockGeometry(vertexLayout,

-                                        vertexCount,

-                                        indexCount,

-                                        vertices,

-                                        indices);

-}

-

-void GrContext::drawIndexed(GrGpu::PrimitiveType type,

-                            uint32_t startVertex,

-                            uint32_t startIndex,

-                            uint32_t vertexCount,

-                            uint32_t indexCount) {

-    flushText();

-    fGpu->drawIndexed(type,

-                      startVertex,

-                      startIndex,

-                      vertexCount,

-                      indexCount);

-}

-

-void GrContext::drawNonIndexed(GrGpu::PrimitiveType type,

-                               uint32_t startVertex,

-                               uint32_t vertexCount) {

-    flushText();

-    fGpu->drawNonIndexed(type,

-                         startVertex,

-                         vertexCount);

-}

-

-void GrContext::setVertexSourceToArray(const void* array,

-                                       GrVertexLayout vertexLayout) {

-    fGpu->setVertexSourceToArray(array, vertexLayout);

-}

-

-void GrContext::setIndexSourceToArray(const void* array) {

-    fGpu->setIndexSourceToArray(array);

-}

-

-void GrContext::setVertexSourceToBuffer(GrVertexBuffer* buffer,

-                                       GrVertexLayout vertexLayout) {

-    fGpu->setVertexSourceToBuffer(buffer, vertexLayout);

-}

-

-void GrContext::setIndexSourceToBuffer(GrIndexBuffer* buffer) {

-    fGpu->setIndexSourceToBuffer(buffer);

-}

-

-void GrContext::releaseReservedGeometry() {

-    fGpu->releaseReservedGeometry();

-}

-

-void GrContext::setClip(const GrClip& clip) {

-    fGpu->setClip(clip);

-    fGpu->enableState(GrDrawTarget::kClip_StateBit);

-}

-

-void GrContext::setAlpha(uint8_t alpha) {

-    fGpu->setAlpha(alpha);

-}

-

-void GrContext::setColor(GrColor color) {

-    fGpu->setColor(color);

+void GrContext::concatMatrix(const GrMatrix& m) const {

+    fGpu->concatViewMatrix(m);

 }

 

 static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {

@@ -962,34 +1034,6 @@
     return bits;

 }

 

-void GrContext::setAntiAlias(bool aa) {

-    if (aa) {

-        fGpu->enableState(GrGpu::kAntialias_StateBit);

-    } else {

-        fGpu->disableState(GrGpu::kAntialias_StateBit);

-    }

-}

-

-void GrContext::setDither(bool dither) {

-    // hack for now, since iPad dither is hella-slow

-    dither = false;

-

-    if (dither) {

-        fGpu->enableState(GrGpu::kDither_StateBit);

-    } else {

-        fGpu->disableState(GrGpu::kDither_StateBit);

-    }

-}

-

-void GrContext::setPointSize(float size) {

-    fGpu->setPointSize(size);

-}

-

-void GrContext::setBlendFunc(GrGpu::BlendCoeff srcCoef,

-                             GrGpu::BlendCoeff dstCoef) {

-    fGpu->setBlendFunc(srcCoef, dstCoef);

-}

-

 void GrContext::resetStats() {

     fGpu->resetStats();

 }

@@ -1031,13 +1075,16 @@
     return 0 != bits;

 }

 

-GrDrawTarget* GrContext::getTextTarget() {

+GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {

+    GrDrawTarget* target;

 #if DEFER_TEXT_RENDERING

     fTextDrawBuffer.initializeDrawStateAndClip(*fGpu);

-    return &fTextDrawBuffer;

+    target = &fTextDrawBuffer;

 #else

-    return fGpu;

+    target = fGpu;

 #endif

+    SetPaint(paint, target);

+    return target;

 }

 

 const GrIndexBuffer* GrContext::quadIndexBuffer() const {

@@ -1050,4 +1097,3 @@
 

 

 

-

diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index df0f0be..abc9fb4 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -22,7 +22,7 @@
 // one stage
 template <int N>
 static int stage_mask_recur(int stage) {
-    return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) | 
+    return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
            stage_mask_recur<N+1>(stage);
 }
 template<> // linux build doesn't like static on specializations
@@ -35,7 +35,7 @@
 
 // mask of all bits relevant to one stage
 static int stage_mask(int stage) {
-    return stage_tex_coord_mask(stage) | 
+    return stage_tex_coord_mask(stage) |
            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
 }
 
@@ -43,7 +43,7 @@
 // texture coordinate index
 template <int N>
 static int tex_coord_mask_recur(int texCoordIdx) {
-    return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) | 
+    return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
            tex_coord_mask_recur<N+1>(texCoordIdx);
 }
 template<> // linux build doesn't like static on specializations
@@ -67,8 +67,8 @@
 
 size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
     GrAssert(check_layout(vertexLayout));
-    
-    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+
+    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                         sizeof(GrGpuTextVertex) :
                         sizeof(GrPoint);
 
@@ -91,8 +91,8 @@
     }
     int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
     if (tcIdx >= 0) {
-        
-        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                     sizeof(GrGpuTextVertex) :
                                     sizeof(GrPoint);
         int offset = vecSize; // position
@@ -110,9 +110,9 @@
 
 int  GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
     GrAssert(check_layout(vertexLayout));
-    
+
     if (vertexLayout & kColor_VertexLayoutBit) {
-        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                     sizeof(GrGpuTextVertex) :
                                     sizeof(GrPoint);
         int offset = vecSize; // position
@@ -131,15 +131,15 @@
                                              int texCoordOffsetsByIdx[kMaxTexCoords],
                                              int* colorOffset) {
     GrAssert(check_layout(vertexLayout));
-    
+
     GrAssert(NULL != texCoordOffsetsByIdx);
     GrAssert(NULL != colorOffset);
 
-    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 
+    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                                     sizeof(GrGpuTextVertex) :
                                                     sizeof(GrPoint);
     int size = vecSize; // position
-    
+
     for (int t = 0; t < kMaxTexCoords; ++t) {
         if (tex_coord_idx_mask(t) & vertexLayout) {
             texCoordOffsetsByIdx[t] = size;
@@ -164,10 +164,10 @@
 
     GrAssert(NULL != texCoordOffsetsByStage);
     GrAssert(NULL != colorOffset);
-    
+
     int texCoordOffsetsByIdx[kMaxTexCoords];
-    int size = VertexSizeAndOffsetsByIdx(vertexLayout, 
-                                         texCoordOffsetsByIdx, 
+    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
+                                         texCoordOffsetsByIdx,
                                          colorOffset);
     for (int s = 0; s < kNumStages; ++s) {
         int tcIdx;
@@ -179,7 +179,7 @@
             texCoordOffsetsByStage[s] = -1;
         }
     }
-    return size;    
+    return size;
 }
 
 bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
@@ -188,9 +188,9 @@
     return !!(stage_mask(stage) & vertexLayout);
 }
 
-bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex, 
+bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
                                          GrVertexLayout vertexLayout) {
-    GrAssert(coordIndex < kMaxTexCoords);     
+    GrAssert(coordIndex < kMaxTexCoords);
     GrAssert(check_layout(vertexLayout));
     return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
 }
@@ -222,7 +222,7 @@
             for (int t = 0; t < kMaxTexCoords; ++t) {
                 stageMask |= StageTexCoordVertexLayoutBit(s,t);
             }
-            GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));            
+            GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
             GrAssert(stage_tex_coord_mask(s) == stageMask);
             stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
             GrAssert(stage_mask(s) == stageMask);
@@ -242,7 +242,7 @@
                     GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
                     GrAssert(!VertexUsesStage(s2, tcMask));
                     GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
-                    
+
                     GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
                     GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
                     GrAssert(VertexUsesStage(s2, posAsTex));
@@ -255,7 +255,7 @@
             }
             GrAssert(tex_coord_idx_mask(t) == tcMask);
             GrAssert(check_layout(tcMask));
-            
+
             int stageOffsets[kNumStages];
             int colorOffset;
             int size;
@@ -300,7 +300,12 @@
     fCurrDrawState.fTextures[stage] = tex;
 }
 
-GrTexture* GrDrawTarget::currentTexture(int stage) const {
+const GrTexture* GrDrawTarget::getTexture(int stage) const {
+    GrAssert(stage >= 0 && stage < kNumStages);
+    return fCurrDrawState.fTextures[stage];
+}
+
+GrTexture* GrDrawTarget::getTexture(int stage) {
     GrAssert(stage >= 0 && stage < kNumStages);
     return fCurrDrawState.fTextures[stage];
 }
@@ -309,7 +314,11 @@
     fCurrDrawState.fRenderTarget = target;
 }
 
-GrRenderTarget* GrDrawTarget::currentRenderTarget() const {
+const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
+    return fCurrDrawState.fRenderTarget;
+}
+
+GrRenderTarget* GrDrawTarget::getRenderTarget() {
     return fCurrDrawState.fRenderTarget;
 }
 
@@ -321,13 +330,12 @@
     fCurrDrawState.fViewMatrix.preConcat(matrix);
 }
 
-// Can't this just return a const&
-void GrDrawTarget::getViewMatrix(GrMatrix* matrix) const {
-    *matrix = fCurrDrawState.fViewMatrix;
+const GrMatrix& GrDrawTarget::getViewMatrix() const {
+    return fCurrDrawState.fViewMatrix;
 }
 
 bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
-    // Mike:  Can we cache this somewhere? 
+    // Mike:  Can we cache this somewhere?
     // Brian: Sure, do we use it often?
 
     GrMatrix inverse;
@@ -366,10 +374,6 @@
     fCurrDrawState.fFlagBits &= ~(bits);
 }
 
-void GrDrawTarget::setPointSize(float size) {
-    fCurrDrawState.fPointSize = size;
-}
-
 void GrDrawTarget::setBlendFunc(BlendCoeff srcCoef,
                                 BlendCoeff dstCoef) {
     fCurrDrawState.fSrcBlend = srcCoef;
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 63cf237..1dbc5fb 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -415,7 +415,6 @@
     fHWDrawState.fSrcBlend = (BlendCoeff)-1;
     fHWDrawState.fDstBlend = (BlendCoeff)-1;
     fHWDrawState.fColor = GrColor_ILLEGAL;
-    fHWDrawState.fPointSize = -1;
 
     fHWDrawState.fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); // illegal
 
@@ -501,6 +500,8 @@
                                 this);
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
 // defines stencil formats from more to less preferred
 GLenum GR_GL_STENCIL_FORMAT_ARRAY[] = {
     GR_STENCIL_INDEX8,
@@ -852,7 +853,7 @@
                 // bind the stencil to rt fbo if present, othewise the tex fbo
                 GR_GLEXT(fExts, FramebufferRenderbuffer(GR_FRAMEBUFFER,
                                                  GR_STENCIL_ATTACHMENT,
-                                                GR_RENDERBUFFER,
+                                                 GR_RENDERBUFFER,
                                                  rtIDs.fStencilRenderbufferID));
             }
             status = GR_GLEXT(fExts, CheckFramebufferStatus(GR_FRAMEBUFFER));
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index 611485d..dbc5de3 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -85,7 +85,7 @@
 
     void eraseStencil(uint32_t value, uint32_t mask);
     virtual void eraseStencilClip();
-    
+
     void setTextureUnit(int unitIdx);
 
     // flushes state that is common to fixed and programmable GL
@@ -123,7 +123,7 @@
     void notifyTextureDelete(GrGLTexture* texture);
     void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
     void notifyTextureRemoveRenderTarget(GrGLTexture* texture);
-    
+
     void setSpareTextureUnit();
 
     void flushRenderTarget();
@@ -156,9 +156,9 @@
 
     // ES requires an extension to support RGBA8 in RenderBufferStorage
     bool fRGBA8Renderbuffer;
-    
+
     int fActiveTextureUnitIdx;
-    
+
     typedef GrGpu INHERITED;
 };
 
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
index 99a593d..3fd8d5c 100644
--- a/gpu/src/GrGpuGLFixed.cpp
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -26,26 +26,26 @@
 
 struct GrGpuMatrix {
     GrScalar    fMat[16];
-    
+
     void reset() {
         Gr_bzero(fMat, sizeof(fMat));
         fMat[0] = fMat[5] = fMat[10] = fMat[15] = GR_Scalar1;
     }
-    
+
     void set(const GrMatrix& m) {
         Gr_bzero(fMat, sizeof(fMat));
         fMat[0]  = m[GrMatrix::kScaleX];
         fMat[4]  = m[GrMatrix::kSkewX];
         fMat[12] = m[GrMatrix::kTransX];
-        
+
         fMat[1]  = m[GrMatrix::kSkewY];
         fMat[5]  = m[GrMatrix::kScaleY];
         fMat[13] = m[GrMatrix::kTransY];
-        
+
         fMat[3]  = m[GrMatrix::kPersp0];
         fMat[7]  = m[GrMatrix::kPersp1];
         fMat[15] = m[GrMatrix::kPersp2];
-        
+
         fMat[10] = GR_Scalar1;    // z-scale
     }
 };
@@ -74,7 +74,7 @@
 
     for (int s = 0; s < kNumStages; ++s) {
         setTextureUnit(s);
-        GR_GL(EnableClientState(GL_VERTEX_ARRAY));    
+        GR_GL(EnableClientState(GL_VERTEX_ARRAY));
         GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
         GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,   GL_MODULATE));
         GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,      GL_TEXTURE0+s));
@@ -86,12 +86,12 @@
         GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA));
         GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS));
         GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA));
-        
-        // color oprand0 changes between GL_SRC_COLR and GL_SRC_ALPHA depending 
-        // upon whether we have a (premultiplied) RGBA texture or just an ALPHA 
+
+        // color oprand0 changes between GL_SRC_COLR and GL_SRC_ALPHA depending
+        // upon whether we have a (premultiplied) RGBA texture or just an ALPHA
         // texture, e.g.:
         //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,  GL_SRC_COLOR);
-        fHWRGBOperand0[s] = (TextureEnvRGBOperands) -1;    
+        fHWRGBOperand0[s] = (TextureEnvRGBOperands) -1;
     }
 
     fHWGeometryState.fVertexLayout = 0;
@@ -100,11 +100,13 @@
     GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
     GR_GL(ShadeModel(GL_FLAT));
     GR_GL(DisableClientState(GL_COLOR_ARRAY));
-    
+
+    GR_GL(PointSize(1.f));
+
     GrGLClearErr();
     fTextVerts = false;
 
-    fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal    
+    fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
     fBaseVertex = 0xffffffff;
 }
 
@@ -112,25 +114,25 @@
 void GrGpuGLFixed::flushProjectionMatrix() {
     float mat[16];
     Gr_bzero(mat, sizeof(mat));
-    
+
     GrAssert(NULL != fCurrDrawState.fRenderTarget);
-    
+
     mat[0] = 2.f / fCurrDrawState.fRenderTarget->width();
     mat[5] = -2.f / fCurrDrawState.fRenderTarget->height();
     mat[10] = -1.f;
     mat[15] = 1;
-    
+
     mat[12] = -1.f;
     mat[13] = 1.f;
-    
+
     GR_GL(MatrixMode(GL_PROJECTION));
     GR_GL(LoadMatrixf(mat));
 }
 
 bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
-    
+
     bool usingTextures[kNumStages];
-    
+
     for (int s = 0; s < kNumStages; ++s) {
         usingTextures[s] = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
 
@@ -139,16 +141,16 @@
             return false;
         }
     }
-    
+
     if (!flushGLStateCommon(type)) {
         return false;
     }
 
-    if (fRenderTargetChanged) {    
+    if (fRenderTargetChanged) {
         flushProjectionMatrix();
         fRenderTargetChanged = false;
     }
-    
+
     for (int s = 0; s < kNumStages; ++s) {
         bool wasUsingTexture = VertexUsesStage(s, fHWGeometryState.fVertexLayout);
         if (usingTextures[s] != wasUsingTexture) {
@@ -160,11 +162,11 @@
             }
         }
     }
-        
+
     uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
-    uint32_t prevVertColor = (fHWGeometryState.fVertexLayout & 
+    uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
                               kColor_VertexLayoutBit);
-    
+
     if (vertColor != prevVertColor) {
         if (vertColor) {
             GR_GL(ShadeModel(GL_SMOOTH));
@@ -175,12 +177,7 @@
         }
     }
 
-    if (kPoints_PrimitiveType == type &&
-        fHWDrawState.fPointSize != fCurrDrawState.fPointSize) {
-        GR_GL(PointSize(fCurrDrawState.fPointSize));
-        fHWDrawState.fPointSize = fCurrDrawState.fPointSize;
-    }
-    
+
     if (!vertColor && fHWDrawState.fColor != fCurrDrawState.fColor) {
         GR_GL(Color4ub(GrColorUnpackR(fCurrDrawState.fColor),
                        GrColorUnpackG(fCurrDrawState.fColor),
@@ -194,25 +191,25 @@
         if (usingTextures[s]) {
             GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTextures[s];
             if (NULL != texture) {
-                TextureEnvRGBOperands nextRGBOperand0 = 
-                    (texture->config() == GrTexture::kAlpha_8_PixelConfig) ? 
-                        kAlpha_TextureEnvRGBOperand : 
+                TextureEnvRGBOperands nextRGBOperand0 =
+                    (texture->config() == GrTexture::kAlpha_8_PixelConfig) ?
+                        kAlpha_TextureEnvRGBOperand :
                         kColor_TextureEnvRGBOperand;
                 if (fHWRGBOperand0[s] != nextRGBOperand0) {
                     setTextureUnit(s);
-                    GR_GL(TexEnvi(GL_TEXTURE_ENV, 
+                    GR_GL(TexEnvi(GL_TEXTURE_ENV,
                                   GL_OPERAND0_RGB,
-                                  (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ? 
-                                    GL_SRC_ALPHA : 
+                                  (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ?
+                                    GL_SRC_ALPHA :
                                     GL_SRC_COLOR));
                     fHWRGBOperand0[s] = nextRGBOperand0;
                 }
-                
+
                 if (fHWTextureOrientation != texture->orientation() ||
-                    fHWDrawState.fTextureMatrices[s] != 
+                    fHWDrawState.fTextureMatrices[s] !=
                     fCurrDrawState.fTextureMatrices[s]) {
                     GrGpuMatrix glm;
-                    if (GrGLTexture::kBottomUp_Orientation == 
+                    if (GrGLTexture::kBottomUp_Orientation ==
                         texture->orientation()) {
                         GrMatrix m(
                             GR_Scalar1, 0, 0,
@@ -227,7 +224,7 @@
                     setTextureUnit(s);
                     GR_GL(MatrixMode(GL_TEXTURE));
                     GR_GL(LoadMatrixf(glm.fMat));
-                    fHWDrawState.fTextureMatrices[s] = 
+                    fHWDrawState.fTextureMatrices[s] =
                                             fCurrDrawState.fTextureMatrices[s];
                     fHWTextureOrientation = texture->orientation();
                 }
@@ -243,7 +240,7 @@
         glm.set(fCurrDrawState.fViewMatrix);
         GR_GL(MatrixMode(GL_MODELVIEW));
         GR_GL(LoadMatrixf(glm.fMat));
-        fHWDrawState.fViewMatrix = 
+        fHWDrawState.fViewMatrix =
         fCurrDrawState.fViewMatrix;
     }
     return true;
@@ -253,49 +250,49 @@
                                  uint32_t startIndex,
                                  uint32_t vertexCount,
                                  uint32_t indexCount) {
-    
+
     int newColorOffset;
     int newTexCoordOffsets[kNumStages];
-    
+
     GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
-                                                    newTexCoordOffsets, 
+                                                    newTexCoordOffsets,
                                                     &newColorOffset);
     int oldColorOffset;
     int oldTexCoordOffsets[kNumStages];
     GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
-                                                    oldTexCoordOffsets, 
+                                                    oldTexCoordOffsets,
                                                     &oldColorOffset);
-    
+
     const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
-    
+
     if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
         GrAssert(NULL != fGeometrySrc.fVertexBuffer);
         GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
         if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
-            GrGLVertexBuffer* buf = 
+            GrGLVertexBuffer* buf =
                             (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
             GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
             fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
         }
-    } else { 
+    } else {
         if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
-            posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray + 
+            posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray +
                              (intptr_t)posPtr);
         } else {
             GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
-            posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);            
+            posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);
         }
         if (NULL != fHWGeometryState.fVertexBuffer) {
             GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
             fHWGeometryState.fVertexBuffer = NULL;
         }
     }
-    
+
     if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
         GrAssert(NULL != fGeometrySrc.fIndexBuffer);
         GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
         if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
-            GrGLIndexBuffer* buf = 
+            GrGLIndexBuffer* buf =
             (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
             GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
             fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
@@ -304,29 +301,29 @@
         GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
         fHWGeometryState.fIndexBuffer = NULL;
     }
-    
+
     GLenum scalarType;
     if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
         scalarType = GrGLTextType;
     } else {
         scalarType = GrGLType;
     }
-    
+
     bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
-    bool scalarChange = 
+    bool scalarChange =
         (GrGLTextType != GrGLType) &&
         (kTextFormat_VertexLayoutBit &
          (fHWGeometryState.fVertexLayout ^ fGeometrySrc.fVertexLayout));
     bool strideChange = newStride != oldStride;
     bool posChange = baseChange || scalarChange || strideChange;
-    
+
     if (posChange) {
         GR_GL(VertexPointer(2, scalarType, newStride, posPtr));
         fHWGeometryState.fPositionPtr = posPtr;
     }
-    
+
     for (int s = 0; s < kNumStages; ++s) {
-        // need to enable array if tex coord offset is 0 
+        // need to enable array if tex coord offset is 0
         // (using positions as coords)
         if (newTexCoordOffsets[s] >= 0) {
             GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[s];
@@ -343,7 +340,7 @@
             GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
         }
     }
-    
+
     if (newColorOffset > 0) {
         GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
         if (oldColorOffset <= 0) {
@@ -355,7 +352,7 @@
     } else if (oldColorOffset > 0) {
         GR_GL(DisableClientState(GL_COLOR_ARRAY));
     }
-    
+
     fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
 }
 
diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp
index 0a777d6..59a907e 100644
--- a/gpu/src/GrTextContext.cpp
+++ b/gpu/src/GrTextContext.cpp
@@ -23,7 +23,7 @@
 #include "GrTextStrike_impl.h"
 #include "GrFontScaler.h"
 
-static const GrVertexLayout VLAYOUT = 
+static const GrVertexLayout VLAYOUT =
                                 GrDrawTarget::kTextFormat_VertexLayoutBit |
                                 GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
 
@@ -57,7 +57,9 @@
     }
 }
 
-GrTextContext::GrTextContext(GrContext* context, const GrMatrix* extMatrix) {
+GrTextContext::GrTextContext(GrContext* context,
+                             const GrPaint& paint,
+                             const GrMatrix* extMatrix) : fPaint(paint) {
     fContext = context;
     fStrike = NULL;
 
@@ -80,17 +82,17 @@
         }
     }
 
-    fContext->getViewMatrix(&fOrigViewMatrix);
-    fContext->setViewMatrix(fExtMatrix);
+    fOrigViewMatrix = fContext->getMatrix();
+    fContext->setMatrix(fExtMatrix);
 
     fVertices = NULL;
     fMaxVertices = 0;
-    fDrawTarget = fContext->getTextTarget();
+    fDrawTarget = fContext->getTextTarget(fPaint);
 }
 
 GrTextContext::~GrTextContext() {
     this->flushGlyphs();
-    fContext->setViewMatrix(fOrigViewMatrix);
+    fContext->setMatrix(fOrigViewMatrix);
 }
 
 void GrTextContext::flush() {
@@ -161,12 +163,11 @@
             glyph->fPath = path;
         }
         GrPath::Iter iter(*glyph->fPath);
-        bool useTexture = false;
         GrPoint translate;
         translate.set(GrFixedToScalar(vx - GrIntToFixed(glyph->fBounds.fLeft)),
                       GrFixedToScalar(vy - GrIntToFixed(glyph->fBounds.fTop)));
-        fContext->drawPath(&iter, GrContext::kWinding_PathFill,
-                              useTexture, &translate);
+        fContext->drawPath(fPaint, &iter, GrContext::kWinding_PathFill,
+                           &translate);
         return;
     }
 
@@ -196,7 +197,7 @@
         if (flush) {
             this->flushGlyphs();
             fContext->flushText();
-            fDrawTarget = fContext->getTextTarget();
+            fDrawTarget = fContext->getTextTarget(fPaint);
             fMaxVertices = kDefaultRequestedVerts;
             // ignore return, no point in flushing again.
             fDrawTarget->geometryHints(VLAYOUT,
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 9c612c5..49a14da 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -143,6 +143,7 @@
 
 private:
     GrContext*      fContext;
+
     GrSkDrawProcs*  fDrawProcs;
 
     // state for our offscreen render-target
@@ -152,28 +153,27 @@
     bool            fNeedClear;
     bool            fNeedPrepareRenderTarget;
 
-    SkDrawProcs* initDrawForText(const SkPaint&, GrTextContext*);
-    bool bindDeviceAsTexture(SkPoint* max);
+    // doesn't set the texture/sampler/matrix state
+    // caller needs to null out GrPaint's texture if
+    // non-textured drawing is desired.
+    bool skPaint2GrPaintNoShader(const SkPaint& skPaint,
+                                 bool justAlpha,
+                                 GrPaint* grPaint);
+
+    // uses the SkShader to setup paint, act used to
+    // hold lock on cached texture and free it when
+    // destroyed.
+    bool skPaint2GrPaintShader(const SkPaint& skPaint,
+                               SkAutoCachedTexture* act,
+                               const SkMatrix& ctm,
+                               GrPaint* grPaint);
+
+    SkDrawProcs* initDrawForText(GrTextContext*);
+    bool bindDeviceAsTexture(GrPaint* paint, SkPoint* max);
 
     void prepareRenderTarget(const SkDraw&);
     void internalDrawBitmap(const SkDraw&, const SkBitmap&,
-                            const SkIRect&, const SkMatrix&, const SkPaint&);
-
-    class AutoPaintShader {
-    public:
-        AutoPaintShader();
-        AutoPaintShader(SkGpuDevice*, const SkPaint& paint, const SkMatrix&);
-
-        void init(SkGpuDevice*, const SkPaint& paint, const SkMatrix&);
-
-        bool failed() const { return !fSuccess; }
-        bool useTex() const { return fTexture != 0; }
-    private:
-        GrTexture*              fTexture;
-        SkAutoCachedTexture     fCachedTexture;
-        bool                    fSuccess;
-    };
-    friend class AutoPaintShader;
+                            const SkIRect&, const SkMatrix&, GrPaint* grPaint);
 
     typedef SkDevice INHERITED;
 };
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 4e9801f..2987639 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -55,7 +55,7 @@
     #endif
     #define SkScalarToGrScalar(x)       SkScalarToFloat(x)
 
-#else 
+#else
     #error "Ganesh scalar type not defined"
 #endif
 
@@ -72,7 +72,7 @@
 GR_STATIC_ASSERT((int)GrSamplerState::kClamp_WrapMode == (int)SkShader::kClamp_TileMode);
 GR_STATIC_ASSERT((int)GrSamplerState::kRepeat_WrapMode ==(
                  int)SkShader::kRepeat_TileMode);
-GR_STATIC_ASSERT((int)GrSamplerState::kMirror_WrapMode == 
+GR_STATIC_ASSERT((int)GrSamplerState::kMirror_WrapMode ==
                  (int)SkShader::kMirror_TileMode);
 
 #define sk_tile_mode_to_grwrap(X) ((GrSamplerState::WrapMode)(X))
@@ -117,13 +117,13 @@
         memcpy(dst, &src, sizeof(*dst));
         return *dst;
     }
-    
+
     static inline GrIRect& SetIRect(GrIRect* dst, const SkIRect& src) {
         GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
         memcpy(dst, &src, sizeof(*dst));
         return *dst;
     }
-    
+
     /**
      *  Convert the SkBitmap::Config to the corresponding PixelConfig, or
      *  kUnknown_PixelConfig if the conversion cannot be done.
@@ -146,7 +146,7 @@
                   SkScalarToGrScalar(m[7]),
                   SkScalarToGrScalar(m[8]));
     }
-    
+
     static GrColor SkColor2GrColor(SkColor c) {
         SkPMColor pm = SkPreMultiplyColor(c);
         unsigned r = SkGetPackedR32(pm);
@@ -176,7 +176,7 @@
     virtual void rewind();
     virtual ConvexHint hint() const;
 private:
-    
+
 #if !SK_SCALAR_IS_GR_SCALAR
     SkPoint             fPoints[4];
 #endif
@@ -190,9 +190,9 @@
         fIter.reset(clip);
         this->invalidateBoundsCache();
     }
-    
+
     // overrides
-    
+
     virtual bool isDone() { return fIter.done(); }
     virtual void getRect(GrIRect* rect) {
         SkGr::SetIRect(rect, fIter.rect());
@@ -228,11 +228,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Helper functions
 
-GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx, 
+GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx,
                                             GrTextureKey* key,
                                             const GrSamplerState& sampler,
                                             const SkBitmap& bitmap);
 
-void sk_gr_set_paint(GrContext* ctx, const SkPaint& paint, bool justAlpha = false);
 
 #endif
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index bf8cb6b..e77562a 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -167,7 +167,6 @@
     SkPicture* fPicture;
     SkGpuCanvas* fGpuCanvas;
     GrContext* fGrContext;
-    GrRenderTarget* fGrRenderTarget;
     SkPath fClipPath;
 
     enum CanvasType {
@@ -219,19 +218,14 @@
     #endif
 
     if (NULL == fGrContext) {
-        SkASSERT(NULL == fGrRenderTarget);
     #if defined(SK_USE_SHADERS)
         fGrContext = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
     #else
         fGrContext = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
     #endif
-        if (NULL != fGrContext) {
-            fGrRenderTarget = fGrContext->createRenderTargetFrom3DApiState();
-        }
     }
 
     if (NULL != fGrContext) {
-        SkASSERT(NULL != fGrRenderTarget);
         return true;
     } else {
         detachGL();
@@ -255,7 +249,6 @@
     fGpuCanvas = NULL;
 
     fGrContext = NULL;
-    fGrRenderTarget = NULL;
 
 #ifdef DEFAULT_TO_GPU
     fCanvasType = kGPU_CanvasType;
@@ -291,9 +284,6 @@
 SampleWindow::~SampleWindow() {
     delete fPicture;
     delete fGpuCanvas;
-    if (NULL != fGrRenderTarget) {
-        fGrRenderTarget->unref();
-    }
     if (NULL != fGrContext) {
         fGrContext->unref();
     }
@@ -414,7 +404,11 @@
                 SkDevice* device = canvas->getDevice();
                 const SkBitmap& bitmap = device->accessBitmap(true);
 
-                fGpuCanvas = new SkGpuCanvas(fGrContext, fGrRenderTarget);
+                GrRenderTarget* renderTarget;
+                renderTarget = fGrContext->createRenderTargetFrom3DApiState();
+                fGpuCanvas = new SkGpuCanvas(fGrContext, renderTarget);
+                renderTarget->unref();
+
                 device = fGpuCanvas->createDevice(SkBitmap::kARGB_8888_Config,
                                                   bitmap.width(), bitmap.height(),
                                                   false, false);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index f14de35..11f030e 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -82,7 +82,6 @@
     if (texture) {
         // return the native texture
         fTex = NULL;
-        device->context()->setTexture(0, texture);
     } else {
         // look it up in our cache
         fTex = device->lockCachedTexture(bitmap, sampler, &texture, false);
@@ -121,8 +120,8 @@
     fNeedPrepareRenderTarget = false;
     fDrawProcs = NULL;
 
-    // should I ref() this, and then unref in destructor? <mrr>
     fContext = context;
+    fContext->ref();
 
     fCache = NULL;
     fTexture = NULL;
@@ -197,6 +196,7 @@
     } else if (NULL != fRenderTarget) {
         fRenderTarget->unref();
     }
+    fContext->unref();
 }
 
 intptr_t SkGpuDevice::getLayerTextureHandle() const {
@@ -271,7 +271,7 @@
                                const SkRegion& clip) {
     GrMatrix grmat;
     SkGr::SkMatrix2GrMatrix(matrix, &grmat);
-    context->setViewMatrix(grmat);
+    context->setMatrix(grmat);
 
     SkGrClipIterator iter;
     iter.reset(clip);
@@ -286,7 +286,7 @@
 // and not the state from some other canvas/device
 void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
     if (fNeedPrepareRenderTarget ||
-        fContext->currentRenderTarget() != fRenderTarget) {
+        fContext->getRenderTarget() != fRenderTarget) {
 
         fContext->setRenderTarget(fRenderTarget);
         convert_matrixclip(fContext, *draw.fMatrix, *draw.fClip);
@@ -314,9 +314,9 @@
     }
 }
 
-bool SkGpuDevice::bindDeviceAsTexture(SkPoint* max) {
+bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint, SkPoint* max) {
     if (NULL != fTexture) {
-        fContext->setTexture(0, fTexture);
+        paint->setTexture(fTexture);
         if (NULL != max) {
             max->set(SkFixedToScalar((width() << 16) /
                                      fTexture->allocWidth()),
@@ -330,39 +330,68 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-// must be in the same order as SkXfermode::Coeff in SkXfermode.h
+// must be in SkShader::BitmapTypeOrder
 
-SkGpuDevice::AutoPaintShader::AutoPaintShader() {
-    fSuccess = false;
-    fTexture = NULL;
+static const GrSamplerState::SampleMode sk_bmp_type_to_sample_mode[] = {
+    (GrSamplerState::SampleMode) -1,                    // kNone_BitmapType
+    GrSamplerState::kNormal_SampleMode,                 // kDefault_BitmapType
+    GrSamplerState::kRadial_SampleMode,                 // kRadial_BitmapType
+    GrSamplerState::kSweep_SampleMode,                  // kSweep_BitmapType
+    GrSamplerState::kRadial2_SampleMode,                // kTwoPointRadial_BitmapType
+};
+
+bool SkGpuDevice::skPaint2GrPaintNoShader(const SkPaint& skPaint,
+                                          bool justAlpha,
+                                          GrPaint* grPaint) {
+
+    grPaint->fDither    = skPaint.isDither();
+    grPaint->fAntiAlias = skPaint.isAntiAlias();
+
+    SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
+    SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
+
+    SkXfermode* mode = skPaint.getXfermode();
+    if (mode) {
+        if (!mode->asCoeff(&sm, &dm)) {
+            SkDebugf("Unsupported xfer mode.\n");
+#if 0
+            return false;
+#endif
+        }
+    }
+    grPaint->fSrcBlendCoeff = sk_blend_to_grblend(sm);
+    grPaint->fDstBlendCoeff = sk_blend_to_grblend(dm);
+
+    if (justAlpha) {
+        uint8_t alpha = skPaint.getAlpha();
+        grPaint->fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
+    } else {
+        grPaint->fColor = SkGr::SkColor2GrColor(skPaint.getColor());
+        grPaint->setTexture(NULL);
+    }
+    return true;
 }
 
-SkGpuDevice::AutoPaintShader::AutoPaintShader(SkGpuDevice* device,
-                                              const SkPaint& paint,
-                                              const SkMatrix& matrix) {
-    fSuccess = false;
-    fTexture = NULL;
-    this->init(device, paint, matrix);
-}
+bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint,
+                                        SkAutoCachedTexture* act,
+                                        const SkMatrix& ctm,
+                                        GrPaint* grPaint) {
 
-void SkGpuDevice::AutoPaintShader::init(SkGpuDevice* device,
-                                        const SkPaint& paint,
-                                        const SkMatrix& ctm) {
-    fSuccess = true;
-    GrContext* ctx = device->context();
-    sk_gr_set_paint(ctx, paint); // should we pass true for justAlpha if we have a shader/texture?
+    SkASSERT(NULL != act);
 
-    SkShader* shader = paint.getShader();
+    SkShader* shader = skPaint.getShader();
     if (NULL == shader) {
-        return;
+        return this->skPaint2GrPaintNoShader(skPaint, false, grPaint);
+        grPaint->setTexture(NULL);
+        return true;
+    } else if (!this->skPaint2GrPaintNoShader(skPaint, true, grPaint)) {
+        return false;
     }
 
-    if (!shader->setContext(device->accessBitmap(false), paint, ctm)) {
-        fSuccess = false;
-        return;
-    }
+    SkPaint noAlphaPaint(skPaint);
+    noAlphaPaint.setAlpha(255);
+    shader->setContext(this->accessBitmap(false), noAlphaPaint, ctm);
 
-    GrSamplerState::SampleMode sampleMode;
     SkBitmap bitmap;
     SkMatrix matrix;
     SkShader::TileMode tileModes[2];
@@ -370,51 +399,28 @@
     SkShader::BitmapType bmptype = shader->asABitmap(&bitmap, &matrix,
                                                      tileModes, twoPointParams);
 
-    switch (bmptype) {
-    case SkShader::kNone_BitmapType:
-        SkDebugf("shader->asABitmap() == kNone_BitmapType");
-        return;
-    case SkShader::kDefault_BitmapType:
-        sampleMode = GrSamplerState::kNormal_SampleMode;
-        break;
-    case SkShader::kRadial_BitmapType:
-        sampleMode = GrSamplerState::kRadial_SampleMode;
-        break;
-    case SkShader::kSweep_BitmapType:
-        sampleMode = GrSamplerState::kSweep_SampleMode;
-        break;
-    case SkShader::kTwoPointRadial_BitmapType:
-        sampleMode = GrSamplerState::kRadial2_SampleMode;
-        break;
-    default:
-        SkASSERT("Unexpected return from asABitmap");
-        return;
+    GrSamplerState::SampleMode sampleMode = sk_bmp_type_to_sample_mode[bmptype];
+    if (-1 == sampleMode) {
+        SkDebugf("shader->asABitmap() == kNone_BitmapType\n");
+        return false;
     }
+    grPaint->fSampler.setSampleMode(sampleMode);
 
-    bitmap.lockPixels();
-    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
-        return;
-    }
-
-    // see if we've already cached the bitmap from the shader
-    GrSamplerState samplerState(sk_tile_mode_to_grwrap(tileModes[0]),
-                                sk_tile_mode_to_grwrap(tileModes[1]),
-                                sampleMode,
-                                paint.isFilterBitmap());
+    grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
+    grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
 
     if (GrSamplerState::kRadial2_SampleMode == sampleMode) {
-        samplerState.setRadial2Params(twoPointParams[0],
-                                      twoPointParams[1],
-                                      twoPointParams[2] < 0);
+        grPaint->fSampler.setRadial2Params(twoPointParams[0],
+                                           twoPointParams[1],
+                                           twoPointParams[2] < 0);
     }
 
-    GrTexture* texture = fCachedTexture.set(device, bitmap, samplerState);
+    GrTexture* texture = act->set(this, bitmap, grPaint->fSampler);
     if (NULL == texture) {
-        return;
+        SkDebugf("Couldn't convert bitmap to texture.\n");
+        return false;
     }
-
-    // the lock has already called setTexture for us
-    ctx->setSamplerState(0, samplerState);
+    grPaint->setTexture(texture);
 
     // since our texture coords will be in local space, we wack the texture
     // matrix to map them back into 0...1 before we load it
@@ -437,40 +443,161 @@
                      (bitmap.width() * texture->allocWidth());
         matrix.postScale(s, s);
     }
-    GrMatrix grmat;
-    SkGr::SkMatrix2GrMatrix(matrix, &grmat);
-    ctx->setTextureMatrix(0, grmat);
 
-    // since we're going to use a shader/texture, we don't want the color,
-    // just its alpha
-    ctx->setAlpha(paint.getAlpha());
-    // report that we have setup the texture
-    fSuccess = true;
-    fTexture = texture;
+    GrMatrix grmat;
+    SkGr::SkMatrix2GrMatrix(matrix, &grPaint->fTextureMatrix);
+
+    return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+
+class SkPositionSource {
+public:
+    SkPositionSource(const SkPoint* points, int count)
+        : fPoints(points), fCount(count) {}
+
+    int count() const { return fCount; }
+
+    void writeValue(int i, GrPoint* dstPosition) const {
+        SkASSERT(i < fCount);
+        dstPosition->fX = SkScalarToGrScalar(fPoints[i].fX);
+        dstPosition->fY = SkScalarToGrScalar(fPoints[i].fY);
+    }
+private:
+    int             fCount;
+    const SkPoint*  fPoints;
+};
+
+class SkTexCoordSource {
+public:
+    SkTexCoordSource(const SkPoint* coords)
+        : fCoords(coords) {}
+
+    void writeValue(int i, GrPoint* dstCoord) const {
+        dstCoord->fX = SkScalarToGrScalar(fCoords[i].fX);
+        dstCoord->fY = SkScalarToGrScalar(fCoords[i].fY);
+    }
+private:
+    const SkPoint*  fCoords;
+};
+
+class SkColorSource {
+public:
+    SkColorSource(const SkColor* colors) : fColors(colors) {}
+
+    void writeValue(int i, GrColor* dstColor) const {
+        *dstColor = SkGr::SkColor2GrColor(fColors[i]);
+    }
+private:
+    const SkColor* fColors;
+};
+
+class SkIndexSource {
+public:
+    SkIndexSource(const uint16_t* indices, int count)
+        : fIndices(indices), fCount(count) {
+    }
+
+    int count() const { return fCount; }
+
+    void writeValue(int i, uint16_t* dstIndex) const {
+        *dstIndex = fIndices[i];
+    }
+
+private:
+    int             fCount;
+    const uint16_t* fIndices;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+// can be used for positions or texture coordinates
+class SkRectFanSource {
+public:
+    SkRectFanSource(const SkRect& rect) : fRect(rect) {}
+
+    int count() const { return 4; }
+
+    void writeValue(int i, GrPoint* dstPoint) const {
+        SkASSERT(i < 4);
+        dstPoint->fX = SkScalarToGrScalar((i % 3) ? fRect.fRight :
+                                                    fRect.fLeft);
+        dstPoint->fY = SkScalarToGrScalar((i < 2) ? fRect.fTop  :
+                                                    fRect.fBottom);
+    }
+private:
+    const SkRect&   fRect;
+};
+
+class SkIRectFanSource {
+public:
+    SkIRectFanSource(const SkIRect& rect) : fRect(rect) {}
+
+    int count() const { return 4; }
+
+    void writeValue(int i, GrPoint* dstPoint) const {
+        SkASSERT(i < 4);
+        dstPoint->fX = (i % 3) ? GrIntToScalar(fRect.fRight) :
+                                 GrIntToScalar(fRect.fLeft);
+        dstPoint->fY = (i < 2) ? GrIntToScalar(fRect.fTop)  :
+                                 GrIntToScalar(fRect.fBottom);
+    }
+private:
+    const SkIRect&   fRect;
+};
+
+class SkMatRectFanSource {
+public:
+    SkMatRectFanSource(const SkRect& rect, const SkMatrix& matrix)
+        : fRect(rect), fMatrix(matrix) {}
+
+    int count() const { return 4; }
+
+    void writeValue(int i, GrPoint* dstPoint) const {
+        SkASSERT(i < 4);
+
+#if SK_SCALAR_IS_GR_SCALAR
+        fMatrix.mapXY((i % 3) ? fRect.fRight : fRect.fLeft,
+                      (i < 2) ? fRect.fTop   : fRect.fBottom,
+                      (SkPoint*)dstPoint);
+#else
+        SkPoint dst;
+        fMatrix.mapXY((i % 3) ? fRect.fRight : fRect.fLeft,
+                      (i < 2) ? fRect.fTop   : fRect.fBottom,
+                      &dst);
+        dstPoint->fX = SkScalarToGrScalar(dst.fX);
+        dstPoint->fY = SkScalarToGrScalar(dst.fY);
+#endif
+    }
+private:
+    const SkRect&   fRect;
+    const SkMatrix& fMatrix;
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw);
 
-    AutoPaintShader   shader(this, paint, *draw.fMatrix);
-    if (shader.failed()) {
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
         return;
     }
-    fContext->drawFull(shader.useTex());
+
+    fContext->drawPaint(grPaint);
 }
 
 // must be in SkCanvas::PointMode order
-static const GrGpu::PrimitiveType gPointMode2PrimtiveType[] = {
-    GrGpu::kPoints_PrimitiveType,
-    GrGpu::kLines_PrimitiveType,
-    GrGpu::kLineStrip_PrimitiveType
+static const GrDrawTarget::PrimitiveType gPointMode2PrimtiveType[] = {
+    GrDrawTarget::kPoints_PrimitiveType,
+    GrDrawTarget::kLines_PrimitiveType,
+    GrDrawTarget::kLineStrip_PrimitiveType
 };
 
 void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
-                            size_t count, const SkPoint pts[], const SkPaint& paint) {
+                             size_t count, const SkPoint pts[], const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw);
 
     SkScalar width = paint.getStrokeWidth();
@@ -484,27 +611,26 @@
         return;
     }
 
-    AutoPaintShader shader(this, paint, *draw.fMatrix);
-    if (shader.failed()) {
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
         return;
     }
 
-    GrVertexLayout layout = shader.useTex() ?
-                            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
-                            0;
 #if SK_SCALAR_IS_GR_SCALAR
-    fContext->setVertexSourceToArray(pts, layout);
-    fContext->drawNonIndexed(gPointMode2PrimtiveType[mode], 0, count);
+    fContext->drawVertices(grPaint,
+                           gPointMode2PrimtiveType[mode],
+                           count,
+                           (GrPoint*)pts,
+                           NULL,
+                           NULL,
+                           NULL,
+                           0);
 #else
-    GrPoint* v;
-    fContext->reserveAndLockGeometry(layout, count, 0, (void**)&v, NULL);
-    for (size_t i = 0; i < count; ++i) {
-        v[i].set(SkScalarToGrScalar(pts[i].fX), SkScalarToGrScalar(pts[i].fY));
-    }
-    fContext->drawNonIndexed(gPointMode2PrimtiveType[mode], 0, count);
-    fContext->releaseReservedGeometry();
+    fContext->drawCustomVertices(grPaint,
+                                 gPointMode2PrimtiveType[mode],
+                                 SkPositionSource(pts, count));
 #endif
-
 }
 
 void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
@@ -525,12 +651,12 @@
         return;
     }
 
-    AutoPaintShader shader(this, paint, *draw.fMatrix);
-    if (shader.failed()) {
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix,  &grPaint)) {
         return;
     }
-
-    fContext->drawRect(Sk2Gr(rect), shader.useTex(), doStroke ? width : -1);
+    fContext->drawRect(grPaint, Sk2Gr(rect), doStroke ? width : -1);
 }
 
 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& path,
@@ -538,8 +664,9 @@
                            bool pathIsMutable) {
     CHECK_SHOULD_DRAW(draw);
 
-    AutoPaintShader shader(this, paint, *draw.fMatrix);
-    if (shader.failed()) {
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
         return;
     }
 
@@ -573,13 +700,13 @@
                 fill = GrContext::kInverseEvenOdd_PathFill;
                 break;
             default:
-                SkDebugf("Unsupported path fill type");
+                SkDebugf("Unsupported path fill type\n");
                 return;
         }
     }
 
     SkGrPathIter iter(fillPath);
-    fContext->drawPath(&iter, fill, shader.useTex());
+    fContext->drawPath(grPaint, &iter, fill);
 }
 
 /*
@@ -603,10 +730,16 @@
         srcRect = *srcRectPtr;
     }
 
+    GrPaint grPaint;
+    if (!this->skPaint2GrPaintNoShader(paint, true, &grPaint)) {
+        return;
+    }
+    grPaint.fSampler.setFilter(paint.isFilterBitmap());
+
     if (bitmap.getTexture() || (bitmap.width() <= MAX_TEXTURE_DIM &&
                                 bitmap.height() <= MAX_TEXTURE_DIM)) {
         // take the fast case
-        this->internalDrawBitmap(draw, bitmap, srcRect, m, paint);
+        this->internalDrawBitmap(draw, bitmap, srcRect, m, &grPaint);
         return;
     }
 
@@ -656,7 +789,7 @@
                     int dy = tileR.fTop -  DY + SkMax32(0, srcR.fTop);
                     tmpM.preTranslate(SkIntToScalar(dx), SkIntToScalar(dy));
                 }
-                this->internalDrawBitmap(draw, tmpB, srcR, tmpM, paint);
+                this->internalDrawBitmap(draw, tmpB, srcR, tmpM, &grPaint);
             }
         }
     }
@@ -666,13 +799,14 @@
  *  This is called by drawBitmap(), which has to handle images that may be too
  *  large to be represented by a single texture.
  *
- *  internalDrawBitmap assumes that the specified bitmap will fit in a texture.
+ *  internalDrawBitmap assumes that the specified bitmap will fit in a texture
+ *  and that non-texture portion of the GrPaint has already been setup.
  */
 void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
                                      const SkBitmap& bitmap,
                                      const SkIRect& srcRect,
                                      const SkMatrix& m,
-                                     const SkPaint& paint) {
+                                     GrPaint* grPaint) {
     SkASSERT(bitmap.width() <= MAX_TEXTURE_DIM &&
              bitmap.height() <= MAX_TEXTURE_DIM);
 
@@ -681,72 +815,35 @@
         return;
     }
 
-    GrSamplerState sampler(paint.isFilterBitmap()); // defaults to clamp
-    // the lock has already called setTexture for us
-    fContext->setSamplerState(0, sampler);
+    grPaint->fSampler.setWrapX(GrSamplerState::kClamp_WrapMode);
+    grPaint->fSampler.setWrapY(GrSamplerState::kClamp_WrapMode);
+    grPaint->fSampler.setSampleMode(GrSamplerState::kNormal_SampleMode);
 
     GrTexture* texture;
-    SkAutoCachedTexture act(this, bitmap, sampler, &texture);
+    SkAutoCachedTexture act(this, bitmap, grPaint->fSampler, &texture);
     if (NULL == texture) {
         return;
     }
 
-    GrVertexLayout layout = GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0);
+    grPaint->setTexture(texture);
+    grPaint->fTextureMatrix.setIdentity();
 
-    GrPoint* vertex;
-    if (!fContext->reserveAndLockGeometry(layout, 4,
-                                          0, GrTCast<void**>(&vertex), NULL)) {
-        return;
-    }
+    SkRect paintRect;
+    paintRect.set(SkFixedToScalar((srcRect.fLeft << 16)  / texture->allocWidth()),
+                  SkFixedToScalar((srcRect.fTop << 16)   / texture->allocHeight()),
+                  SkFixedToScalar((srcRect.fRight << 16) / texture->allocWidth()),
+                  SkFixedToScalar((srcRect.fBottom << 16)/ texture->allocHeight()));
 
-    {
-        GrMatrix grmat;
-        SkGr::SkMatrix2GrMatrix(m, &grmat);
-        vertex[0].setIRectFan(0, 0, srcRect.width(), srcRect.height(),
-                              2*sizeof(GrPoint));
-        grmat.mapPointsWithStride(vertex, 2*sizeof(GrPoint), 4);
-    }
+    SkRect dstRect;
+    dstRect.set(SkIntToScalar(0),SkIntToScalar(0), 
+                SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height()));
 
-    SkScalar left   = SkFixedToScalar((srcRect.fLeft << 16) /
-                                      texture->allocWidth());
-    SkScalar right  = SkFixedToScalar((srcRect.fRight << 16) /
-                                      texture->allocWidth());
-    SkScalar top    = SkFixedToScalar((srcRect.fTop << 16) /
-                                      texture->allocHeight());
-    SkScalar bottom = SkFixedToScalar((srcRect.fBottom << 16) /
-                                      texture->allocHeight());
-    vertex[1].setRectFan(left, top, right, bottom, 2*sizeof(GrPoint));
+    SkRectFanSource texSrc(paintRect);
+    fContext->drawCustomVertices(*grPaint,
+                                 GrDrawTarget::kTriangleFan_PrimitiveType,
+                                 SkMatRectFanSource(dstRect, m),
+                                 &texSrc);
 
-    fContext->setTextureMatrix(0, GrMatrix::I());
-    // now draw the mesh
-    sk_gr_set_paint(fContext, paint, true);
-    fContext->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType, 0, 4);
-    fContext->releaseReservedGeometry();
-}
-
-static void gl_drawSprite(GrContext* ctx,
-                          int x, int y, int w, int h, const SkPoint& max,
-                          const SkPaint& paint) {
-    GrAutoViewMatrix avm(ctx, GrMatrix::I());
-
-    ctx->setSamplerState(0, GrSamplerState::ClampNoFilter());
-    ctx->setTextureMatrix(0, GrMatrix::I());
-
-    GrPoint* vertex;
-    GrVertexLayout layout = GrGpu::StageTexCoordVertexLayoutBit(0, 0);
-    if (!ctx->reserveAndLockGeometry(layout, 4, 0,
-                                     GrTCast<void**>(&vertex), NULL)) {
-        return;
-    }
-
-    vertex[1].setRectFan(0, 0, max.fX, max.fY, 2*sizeof(GrPoint));
-
-    vertex[0].setIRectFan(x, y, x + w, y + h, 2*sizeof(GrPoint));
-
-    sk_gr_set_paint(ctx, paint, true);
-    // should look to use glDrawTexi() has we do for text...
-    ctx->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType, 0, 4);
-    ctx->releaseReservedGeometry();
 }
 
 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
@@ -758,16 +855,31 @@
         return;
     }
 
-    SkPoint max;
-    GrTexture* texture;
-    SkAutoCachedTexture act(this, bitmap, GrSamplerState::ClampNoFilter(),
-                            &texture);
+    GrPaint grPaint;
+    if(!this->skPaint2GrPaintNoShader(paint, true, &grPaint)) {
+        return;
+    }
 
+    GrAutoMatrix avm(fContext, GrMatrix::I());
+
+    GrTexture* texture;
+    grPaint.fSampler.setClampNoFilter();
+    SkAutoCachedTexture act(this, bitmap, grPaint.fSampler, &texture);
+
+    grPaint.fTextureMatrix.setIdentity();
+    grPaint.setTexture(texture);
+
+    SkPoint max;
     max.set(SkFixedToScalar((texture->contentWidth() << 16) /
                              texture->allocWidth()),
             SkFixedToScalar((texture->contentHeight() << 16) /
                             texture->allocHeight()));
-    gl_drawSprite(fContext, left, top, bitmap.width(), bitmap.height(), max, paint);
+
+    fContext->drawRectToRect(grPaint,
+                             GrRect(GrIntToScalar(left), GrIntToScalar(top),
+                                    GrIntToScalar(left + bitmap.width()),
+                                    GrIntToScalar(top + bitmap.height())),
+                             GrRect(0, 0, max.fX, max.fY));
 }
 
 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
@@ -775,21 +887,41 @@
     CHECK_SHOULD_DRAW(draw);
 
     SkPoint max;
-    if (((SkGpuDevice*)dev)->bindDeviceAsTexture(&max)) {
-        const SkBitmap& bm = dev->accessBitmap(false);
-        int w = bm.width();
-        int h = bm.height();
-        gl_drawSprite(fContext, x, y, w, h, max, paint);
+    GrPaint grPaint;
+    if (!((SkGpuDevice*)dev)->bindDeviceAsTexture(&grPaint, &max) ||
+        !this->skPaint2GrPaintNoShader(paint, true, &grPaint)) {
+        return;
     }
+
+    SkASSERT(NULL != grPaint.getTexture());
+
+    const SkBitmap& bm = dev->accessBitmap(false);
+    int w = bm.width();
+    int h = bm.height();
+
+    GrAutoMatrix avm(fContext, GrMatrix::I());
+
+    grPaint.fSampler.setClampNoFilter();
+    grPaint.fTextureMatrix.setIdentity();
+
+    fContext->drawRectToRect(grPaint,
+                             GrRect(GrIntToScalar(x), 
+                                    GrIntToScalar(y), 
+                                    GrIntToScalar(x + w), 
+                                    GrIntToScalar(y + h)),
+                             GrRect(0, 
+                                    0, 
+                                    GrIntToScalar(max.fX), 
+                                    GrIntToScalar(max.fY)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 // must be in SkCanvas::VertexMode order
-static const GrGpu::PrimitiveType gVertexMode2PrimitiveType[] = {
-    GrGpu::kTriangles_PrimitiveType,
-    GrGpu::kTriangleStrip_PrimitiveType,
-    GrGpu::kTriangleFan_PrimitiveType,
+static const GrDrawTarget::PrimitiveType gVertexMode2PrimitiveType[] = {
+    GrDrawTarget::kTriangles_PrimitiveType,
+    GrDrawTarget::kTriangleStrip_PrimitiveType,
+    GrDrawTarget::kTriangleFan_PrimitiveType,
 };
 
 void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
@@ -800,77 +932,57 @@
                               const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw);
 
-    sk_gr_set_paint(fContext, paint);
-
-    TexCache* cache = NULL;
-
-    bool useTexture = false;
-
-    AutoPaintShader autoShader;
-
-    if (texs) {
-        autoShader.init(this, paint, *draw.fMatrix);
-
-        if (autoShader.failed()) {
+    GrPaint grPaint;
+    SkAutoCachedTexture act;
+    // we ignore the shader if texs is null.
+    if (NULL == texs) {
+        if (!this->skPaint2GrPaintNoShader(paint, false, &grPaint)) {
             return;
         }
-        useTexture = autoShader.useTex();
-    }
-
-    bool releaseVerts = false;
-    GrVertexLayout layout = 0;
-    if (useTexture) {
-        layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0);
-    }
-    if (NULL != colors) {
-        layout |= GrDrawTarget::kColor_VertexLayoutBit;
-    }
-
-    #if SK_SCALAR_IS_GR_SCALAR
-    if (!layout) {
-        fContext->setVertexSourceToArray(vertices, layout);
-    } else
-    #endif
-    {
-        void* verts;
-        releaseVerts = true;
-        if (!fContext->reserveAndLockGeometry(layout, vertexCount, 0,
-                                              &verts, NULL)) {
-            return;
-        }
-        int texOffsets[GrDrawTarget::kNumStages];
-        int colorOffset;
-        uint32_t stride = GrDrawTarget::VertexSizeAndOffsetsByStage(layout,
-                                                                    texOffsets,
-                                                                    &colorOffset);
-        for (int i = 0; i < vertexCount; ++i) {
-            GrPoint* p = (GrPoint*)((intptr_t)verts + i * stride);
-            p->set(SkScalarToGrScalar(vertices[i].fX),
-                   SkScalarToGrScalar(vertices[i].fY));
-            if (texOffsets[0] > 0) {
-                GrPoint* t = (GrPoint*)((intptr_t)p + texOffsets[0]);
-                t->set(SkScalarToGrScalar(texs[i].fX),
-                       SkScalarToGrScalar(texs[i].fY));
-            }
-            if (colorOffset > 0) {
-                uint32_t* color = (uint32_t*) ((intptr_t)p + colorOffset);
-                *color = SkGr::SkColor2GrColor(colors[i]);
-            }
-        }
-    }
-    if (indices) {
-        fContext->setIndexSourceToArray(indices);
-        fContext->drawIndexed(gVertexMode2PrimitiveType[vmode], 0, 0,
-                                 vertexCount, indexCount);
     } else {
-        fContext->drawNonIndexed(gVertexMode2PrimitiveType[vmode],
-                                 0, vertexCount);
+        if (!this->skPaint2GrPaintShader(paint, &act, 
+                                         *draw.fMatrix, 
+                                         &grPaint)) {
+            return;
+        }
     }
-    if (cache) {
-        this->unlockCachedTexture(cache);
+
+    if (NULL != xmode && NULL != texs && NULL != colors) {
+        SkXfermode::Mode mode;
+        if (!SkXfermode::IsMode(xmode, &mode) ||
+            SkXfermode::kMultiply_Mode != mode) {
+            SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
+#if 0
+            return
+#endif
+        }
     }
-    if (releaseVerts) {
-        fContext->releaseReservedGeometry();
+
+#if SK_SCALAR_IS_GR_SCALAR
+    // even if GrColor and SkColor byte offsets match we need
+    // to perform pre-multiply.
+    if (NULL == colors) {
+        fContext->drawVertices(grPaint,
+                               gVertexMode2PrimitiveType[vmode],
+                               vertexCount,
+                               (GrPoint*) vertices,
+                               (GrPoint*) texs,
+                               NULL,
+                               indices,
+                               indexCount);
+    } else
+#endif
+    {
+        SkTexCoordSource texSrc(texs);
+        SkColorSource colSrc(colors);
+        SkIndexSource idxSrc(indices, indexCount);
+
+        fContext->drawCustomVertices(grPaint,
+                                     gVertexMode2PrimitiveType[vmode],
+                                     SkPositionSource(vertices, vertexCount),
+                                     (NULL == texs) ? NULL : &texSrc,
+                                     (NULL == colors) ? NULL : &colSrc,
+                                     (NULL == indices) ? NULL : &idxSrc);
     }
 }
 
@@ -908,8 +1020,7 @@
                                          procs->fFontScaler);
 }
 
-SkDrawProcs* SkGpuDevice::initDrawForText(const SkPaint& paint,
-                                          GrTextContext* context) {
+SkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) {
 
     // deferred allocation
     if (NULL == fDrawProcs) {
@@ -935,9 +1046,15 @@
     } else {
         SkAutoExtMatrix aem(draw.fExtMatrix);
         SkDraw myDraw(draw);
-        sk_gr_set_paint(fContext, paint);
-        GrTextContext context(fContext, aem.extMatrix());
-        myDraw.fProcs = this->initDrawForText(paint, &context);
+
+        GrPaint grPaint;
+        SkAutoCachedTexture act;
+
+        if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
+            return;
+        }
+        GrTextContext context(fContext, grPaint, aem.extMatrix());
+        myDraw.fProcs = this->initDrawForText(&context);
         this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
     }
 }
@@ -955,9 +1072,15 @@
     } else {
         SkAutoExtMatrix aem(draw.fExtMatrix);
         SkDraw myDraw(draw);
-        sk_gr_set_paint(fContext, paint);
-        GrTextContext context(fContext, aem.extMatrix());
-        myDraw.fProcs = this->initDrawForText(paint, &context);
+
+        GrPaint grPaint;
+        SkAutoCachedTexture act;
+        if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
+            return;
+        }
+
+        GrTextContext context(fContext, grPaint, aem.extMatrix());
+        myDraw.fProcs = this->initDrawForText(&context);
         this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
                                      scalarsPerPos, paint);
     }
@@ -1014,7 +1137,6 @@
 
     if (NULL != entry) {
         newTexture = entry->texture();
-        ctx->setTexture(0, newTexture);
         if (texture) {
             *texture = newTexture;
         }
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 8849db7..41cf1bd 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -19,18 +19,18 @@
 
 /*  Fill out buffer with the compressed format Ganesh expects from a colortable
  based bitmap. [palette (colortable) + indices].
- 
- At the moment Ganesh only supports 8bit version. If Ganesh allowed we others 
+
+ At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
  we could detect that the colortable.count is <= 16, and then repack the
  indices as nibbles to save RAM, but it would take more time (i.e. a lot
  slower than memcpy), so skipping that for now.
- 
+
  Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
  as the colortable.count says it is.
  */
 static void build_compressed_data(void* buffer, const SkBitmap& bitmap) {
     SkASSERT(SkBitmap::kIndex8_Config == bitmap.config());
-  
+
     SkAutoLockPixels apl(bitmap);
     if (!bitmap.readyToDraw()) {
         SkASSERT(!"bitmap not ready to draw!");
@@ -39,10 +39,10 @@
 
     SkColorTable* ctable = bitmap.getColorTable();
     char* dst = (char*)buffer;
-    
+
     memcpy(dst, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
     ctable->unlockColors(false);
-    
+
     // always skip a full 256 number of entries, even if we memcpy'd fewer
     dst += GrGpu::kColorTableSize;
 
@@ -63,7 +63,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx, 
+GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx,
                                             GrTextureKey* key,
                                             const GrSamplerState& sampler,
                                             const SkBitmap& origBitmap) {
@@ -75,7 +75,7 @@
     SkBitmap tmpBitmap;
 
     const SkBitmap* bitmap = &origBitmap;
-    
+
     GrGpu::TextureDesc desc = {
         0,
         GrGpu::kNone_AALevel,
@@ -83,16 +83,16 @@
         bitmap->height(),
         SkGr::Bitmap2PixelConfig(*bitmap)
     };
-    
+
     if (SkBitmap::kIndex8_Config == bitmap->config()) {
         // build_compressed_data doesn't do npot->pot expansion
         // and paletted textures can't be sub-updated
         if (ctx->supportsIndex8PixelConfig(sampler,
                                            bitmap->width(), bitmap->height())) {
-            size_t imagesize = bitmap->width() * bitmap->height() + 
+            size_t imagesize = bitmap->width() * bitmap->height() +
                                 GrGpu::kColorTableSize;
             SkAutoMalloc storage(imagesize);
-        
+
             build_compressed_data(storage.get(), origBitmap);
 
             // our compressed data will be trimmed, so pass width() for its
@@ -105,7 +105,7 @@
             // now bitmap points to our temp, which has been promoted to 32bits
             bitmap = &tmpBitmap;
         }
-    } 
+    }
 
     desc.fFormat = SkGr::Bitmap2PixelConfig(*bitmap);
     return ctx->createAndLockTexture(key, sampler, desc, bitmap->getPixels(),
@@ -113,28 +113,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-  
-void sk_gr_set_paint(GrContext* ctx, const SkPaint& paint, bool justAlpha) {
-    ctx->setDither(paint.isDither());
-    ctx->setAntiAlias(paint.isAntiAlias());
 
-    if (justAlpha) {
-        ctx->setAlpha(paint.getAlpha());
-    } else {
-        ctx->setColor(SkGr::SkColor2GrColor(paint.getColor()));
-    }
-    
-    SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
-    SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
-    
-    SkXfermode* mode = paint.getXfermode();
-    if (mode) {
-        mode->asCoeff(&sm, &dm);
-    }   
-    ctx->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
-}
-
-////////////////////////////////////////////////////////////////////////////////
 
 SkGrPathIter::Command SkGrPathIter::next(GrPoint pts[]) {
     GrAssert(NULL != pts);
@@ -160,7 +139,7 @@
 }
 
 GrPathIter::ConvexHint SkGrPathIter::hint() const {
-    return fPath.isConvex() ? GrPathIter::kConvex_ConvexHint : 
+    return fPath.isConvex() ? GrPathIter::kConvex_ConvexHint :
                               GrPathIter::kNone_ConvexHint;
 }
 
diff --git a/src/utils/mac/SkOSWindow_Mac.cpp b/src/utils/mac/SkOSWindow_Mac.cpp
index d4ef7e9..e45a445 100644
--- a/src/utils/mac/SkOSWindow_Mac.cpp
+++ b/src/utils/mac/SkOSWindow_Mac.cpp
@@ -37,26 +37,26 @@
                                    EventRef event, void *userData) {
 	// NOTE: GState is save/restored by the HIView system doing the callback,
     // so the draw handler doesn't need to do it
-    
+
 	OSStatus status = noErr;
 	CGContextRef context;
 	HIRect		bounds;
-    
+
 	// Get the CGContextRef
-	status = GetEventParameter (event, kEventParamCGContextRef, 
-                                typeCGContextRef, NULL, 
+	status = GetEventParameter (event, kEventParamCGContextRef,
+                                typeCGContextRef, NULL,
                                 sizeof (CGContextRef),
                                 NULL,
                                 &context);
-    
+
 	if (status != noErr) {
 		SkDebugf("Got error %d getting the context!\n", status);
 		return status;
-	}		
-    
+	}
+
 	// Get the bounding rectangle
 	HIViewGetBounds ((HIViewRef) userData, &bounds);
-	
+
     gCurrOSWin->doPaint(context);
 	return status;
 }
@@ -88,13 +88,13 @@
 {
 	OSStatus    result;
     WindowRef   wr = (WindowRef)hWnd;
-    
+
     HIViewRef imageView, parent;
     HIViewRef rootView = HIViewGetRoot(wr);
     HIViewFindByID(rootView, kHIViewWindowContentID, &parent);
     result = HIImageViewCreate(NULL, &imageView);
 	SkASSERT(result == noErr);
-    
+
     result = HIViewAddSubview(parent, imageView);
 	SkASSERT(result == noErr);
 
@@ -138,7 +138,7 @@
 	result = InstallEventHandler(GetWindowEventTarget(wr), handlerUPP,
 						count, gTypes, this, nil);
 	SkASSERT(result == noErr);
-    
+
 	gCurrOSWin = this;
 	gCurrEventQ = GetCurrentEventQueue();
 	gEventTarget = GetWindowEventTarget(wr);
@@ -168,7 +168,7 @@
         CGContextScaleCTM(cg, 1, -1);
 
         CGContextDrawImage(cg, r, img);
-        
+
         CGContextRestoreGState(cg);
 
         CGImageRelease(img);
@@ -179,15 +179,15 @@
 void SkOSWindow::updateSize()
 {
 	Rect	r;
-	
+
 	GetWindowBounds((WindowRef)fHWND, kWindowContentRgn, &r);
 	this->resize(r.right - r.left, r.bottom - r.top);
-    
+
 #if 0
     HIRect    frame;
     HIViewRef imageView = (HIViewRef)getHVIEW();
     HIViewRef parent = HIViewGetSuperview(imageView);
-  
+
     HIViewGetBounds(imageView, &frame);
     SkDebugf("------ %d bounds %g %g %g %g\n", r.right - r.left,
              frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
@@ -245,7 +245,7 @@
 	SK_MacRightKey		= 124,
 	SK_MacDownKey		= 125,
 	SK_MacUpKey			= 126,
-    
+
     SK_Mac0Key          = 0x52,
     SK_Mac1Key          = 0x53,
     SK_Mac2Key          = 0x54,
@@ -257,7 +257,7 @@
     SK_Mac8Key          = 0x5b,
     SK_Mac9Key          = 0x5c
 };
-	
+
 static SkKey raw2key(UInt32 raw)
 {
 	static const struct {
@@ -282,7 +282,7 @@
         { SK_Mac8Key,       k8_SkKey        },
         { SK_Mac9Key,       k9_SkKey        }
 	};
-	
+
 	for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++)
 		if (gKeys[i].fRaw == raw)
 			return gKeys[i].fKey;
@@ -294,18 +294,18 @@
 	EventRef	ref;
 	OSStatus	status = CreateEvent(nil, SK_MacEventClass, SK_MacEventKind, 0, 0, &ref);
 	SkASSERT(status == noErr);
-	
+
 #if 0
 	status = SetEventParameter(ref, SK_MacEventParamName, SK_MacEventParamName, sizeof(evt), &evt);
 	SkASSERT(status == noErr);
 	status = SetEventParameter(ref, SK_MacEventSinkIDParamName, SK_MacEventSinkIDParamName, sizeof(sinkID), &sinkID);
 	SkASSERT(status == noErr);
 #endif
-	
+
 	EventTargetRef target = gEventTarget;
 	SetEventParameter(ref, kEventParamPostTarget, typeEventTargetRef, sizeof(target), &target);
 	SkASSERT(status == noErr);
-	
+
 	status = PostEventToQueue(gCurrEventQ, ref, kEventPriorityStandard);
 	SkASSERT(status == noErr);
 
@@ -456,16 +456,16 @@
 {
     GLint major, minor;
     AGLContext ctx;
-    
+
     aglGetVersion(&major, &minor);
     SkDebugf("---- agl version %d %d\n", major, minor);
-    
+
     const GLint pixelAttrs[] = {
         AGL_RGBA,
         AGL_STENCIL_SIZE, 8,
         AGL_SAMPLE_BUFFERS_ARB, 1,
 		AGL_MULTISAMPLE,
-		AGL_SAMPLES_ARB, 2,        
+		AGL_SAMPLES_ARB, 2,
 		(offscreen ? AGL_OFFSCREEN : AGL_ACCELERATED),
         (offscreen ? AGL_NONE : AGL_DOUBLEBUFFER),
         AGL_NONE
@@ -494,14 +494,20 @@
 
     GLboolean success = true;
 
+    int width, height;
+
     if (offscreen) {
         success = aglSetOffScreen((AGLContext)fAGLCtx,
                                     offscreen->width(),
                                     offscreen->height(),
                                     offscreen->rowBytes(),
                                     offscreen->getPixels());
+        width = offscreen->width();
+        height = offscreen->height();
     } else {
         success = aglSetWindowRef((AGLContext)fAGLCtx, (WindowRef)fHWND);
+        width = this->width();
+        height = this->height();
     }
 
     GLenum err = aglGetError();
@@ -509,8 +515,9 @@
         SkDebugf("---- setoffscreen %d %d %s [%d %d]\n", success, err,
                  aglErrorString(err), offscreen->width(), offscreen->height());
     }
-    
+
     if (success) {
+        glViewport(0, 0, width, height);
         glClearColor(0, 0, 0, 0);
         glClearStencil(0);
         glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
diff --git a/src/utils/win/SkOSWindow_Win.cpp b/src/utils/win/SkOSWindow_Win.cpp
index 53449b1..d0e6cc3 100644
--- a/src/utils/win/SkOSWindow_Win.cpp
+++ b/src/utils/win/SkOSWindow_Win.cpp
@@ -438,6 +438,7 @@
         }
     }
     if (wglMakeCurrent(GetDC((HWND)fHWND), (HGLRC)fHGLRC)) {
+        glViewport(0, 0, this->width(), this->height());
         glClearColor(0, 0, 0, 0);
         glClearStencil(0);
         glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
diff --git a/vs/SampleApp/SampleApp.vcxproj b/vs/SampleApp/SampleApp.vcxproj
index 7294cc1..95e7f0a 100644
--- a/vs/SampleApp/SampleApp.vcxproj
+++ b/vs/SampleApp/SampleApp.vcxproj
@@ -74,6 +74,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <AdditionalIncludeDirectories>..\..\include\core;..\..\include\xml;..\..\include\utils;..\..\include\config;..\..\include\views;..\..\src\core;..\..\include\images;..\..\include\effects;..\..\include\gpu;..\..\gpu\include</AdditionalIncludeDirectories>

+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>

     </ClCompile>

     <Link>

       <SubSystem>Windows</SubSystem>

@@ -99,6 +100,7 @@
     <ClInclude Include="..\..\gpu\include\GrColor.h" />

     <ClInclude Include="..\..\gpu\include\GrConfig.h" />

     <ClInclude Include="..\..\gpu\include\GrContext.h" />

+    <ClInclude Include="..\..\gpu\include\GrContext_impl.h" />

     <ClInclude Include="..\..\gpu\include\GrDrawTarget.h" />

     <ClInclude Include="..\..\gpu\include\GrFontScaler.h" />

     <ClInclude Include="..\..\gpu\include\GrGLConfig.h" />

@@ -117,6 +119,7 @@
     <ClInclude Include="..\..\gpu\include\GrMemory.h" />

     <ClInclude Include="..\..\gpu\include\GrMesh.h" />

     <ClInclude Include="..\..\gpu\include\GrNoncopyable.h" />

+    <ClInclude Include="..\..\gpu\include\GrPaint.h" />

     <ClInclude Include="..\..\gpu\include\GrPath.h" />

     <ClInclude Include="..\..\gpu\include\GrPathIter.h" />

     <ClInclude Include="..\..\gpu\include\GrPathSink.h" />

diff --git a/xcode/gpu/gpu.xcodeproj/project.pbxproj b/xcode/gpu/gpu.xcodeproj/project.pbxproj
index 7aa1a77..0403b49 100644
--- a/xcode/gpu/gpu.xcodeproj/project.pbxproj
+++ b/xcode/gpu/gpu.xcodeproj/project.pbxproj
@@ -91,6 +91,8 @@
 		00115EA912C116CA008296FE /* GrUserConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 00115E6D12C116CA008296FE /* GrUserConfig.h */; };
 		00115EAA12C116CA008296FE /* GrVertexBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 00115E6E12C116CA008296FE /* GrVertexBuffer.h */; };
 		00115EAB12C116CA008296FE /* GrVertexBufferAllocPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 00115E6F12C116CA008296FE /* GrVertexBufferAllocPool.h */; };
+		D539049B12EA01E30025F3D6 /* GrContext_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = D539049A12EA01E30025F3D6 /* GrContext_impl.h */; };
+		D53904A112EA026E0025F3D6 /* GrPaint.h in Headers */ = {isa = PBXBuildFile; fileRef = D53904A012EA026E0025F3D6 /* GrPaint.h */; };
 		D58CAF9A12E7212100CB9277 /* GrGLUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D58CAF9812E7212100CB9277 /* GrGLUtil.cpp */; };
 /* End PBXBuildFile section */
 
@@ -180,6 +182,8 @@
 		00115E6E12C116CA008296FE /* GrVertexBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrVertexBuffer.h; path = ../../gpu/include/GrVertexBuffer.h; sourceTree = SOURCE_ROOT; };
 		00115E6F12C116CA008296FE /* GrVertexBufferAllocPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrVertexBufferAllocPool.h; path = ../../gpu/include/GrVertexBufferAllocPool.h; sourceTree = SOURCE_ROOT; };
 		D2AAC046055464E500DB518D /* libgpu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgpu.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		D539049A12EA01E30025F3D6 /* GrContext_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrContext_impl.h; path = ../../gpu/include/GrContext_impl.h; sourceTree = SOURCE_ROOT; };
+		D53904A012EA026E0025F3D6 /* GrPaint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrPaint.h; path = ../../gpu/include/GrPaint.h; sourceTree = SOURCE_ROOT; };
 		D58CAF9812E7212100CB9277 /* GrGLUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrGLUtil.cpp; path = ../../gpu/src/GrGLUtil.cpp; sourceTree = SOURCE_ROOT; };
 /* End PBXFileReference section */
 
@@ -251,6 +255,7 @@
 				00115E6D12C116CA008296FE /* GrUserConfig.h */,
 				00115E6E12C116CA008296FE /* GrVertexBuffer.h */,
 				00115E6F12C116CA008296FE /* GrVertexBufferAllocPool.h */,
+				D53904A012EA026E0025F3D6 /* GrPaint.h */,
 			);
 			name = include;
 			sourceTree = "<group>";
@@ -269,6 +274,7 @@
 		08FB7795FE84155DC02AAC07 /* Source */ = {
 			isa = PBXGroup;
 			children = (
+				D539049A12EA01E30025F3D6 /* GrContext_impl.h */,
 				00115DD812C1167A008296FE /* gr_unittests.cpp */,
 				00115DD912C1167A008296FE /* GrAllocPool.cpp */,
 				00115DDA12C1167A008296FE /* GrAtlas.cpp */,
@@ -385,6 +391,8 @@
 				00115EA912C116CA008296FE /* GrUserConfig.h in Headers */,
 				00115EAA12C116CA008296FE /* GrVertexBuffer.h in Headers */,
 				00115EAB12C116CA008296FE /* GrVertexBufferAllocPool.h in Headers */,
+				D539049B12EA01E30025F3D6 /* GrContext_impl.h in Headers */,
+				D53904A112EA026E0025F3D6 /* GrPaint.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
index 8787064..18bca17 100644
--- a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
+++ b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
@@ -51,7 +51,6 @@
 		0041CE430F00A12400695E8C /* SampleLayers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2D0F00A12400695E8C /* SampleLayers.cpp */; };
 		0041CE450F00A12400695E8C /* SampleMeasure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE2F0F00A12400695E8C /* SampleMeasure.cpp */; };
 		0041CE480F00A12400695E8C /* SampleOverflow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE320F00A12400695E8C /* SampleOverflow.cpp */; };
-		0041CE4A0F00A12400695E8C /* SamplePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE340F00A12400695E8C /* SamplePatch.cpp */; };
 		00575A1810BB02CF00A43B94 /* SampleEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00FF39130FC6ED2C00915187 /* SampleEffects.cpp */; };
 		00575A3B10BB05FE00A43B94 /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */; };
 		00575A9510BB2FF600A43B94 /* SampleMipMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2794C04E0FE72903009AD112 /* SampleMipMap.cpp */; };
@@ -86,7 +85,6 @@
 		00AF787E0FE94433007F9650 /* SamplePath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00003C640EFC22A8000FF73A /* SamplePath.cpp */; };
 		00AF9B18103CD5EB00CBBCB3 /* SampleDitherBitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00AF9B17103CD5EB00CBBCB3 /* SampleDitherBitmap.cpp */; };
 		00BB289B104781D00057BF7E /* SampleForth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00BB289A104781D00057BF7E /* SampleForth.cpp */; };
-		00C1B809103857A400FA5948 /* SampleFillType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE270F00A12400695E8C /* SampleFillType.cpp */; };
 		00EB4593104DBB18002B413E /* ForthTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00EB4592104DBB18002B413E /* ForthTests.cpp */; };
 		00ED55F3104A10EB00F51FF8 /* StdWords.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00ED55F2104A10EB00F51FF8 /* StdWords.cpp */; };
 		00F0441010B447160049C54C /* SamplePathClip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 007C785D0F3B4C230004B142 /* SamplePathClip.cpp */; };
@@ -150,6 +148,8 @@
 		8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; };
 		8D0C4E8E0486CD37000505A6 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; };
 		8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
+		D5A682D712E9CE8500CDDDC6 /* SamplePatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE340F00A12400695E8C /* SamplePatch.cpp */; };
+		D5F4A21F12E9D75300DE986A /* SampleFillType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0041CE270F00A12400695E8C /* SampleFillType.cpp */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -919,7 +919,6 @@
 				0041CE430F00A12400695E8C /* SampleLayers.cpp in Sources */,
 				0041CE450F00A12400695E8C /* SampleMeasure.cpp in Sources */,
 				0041CE480F00A12400695E8C /* SampleOverflow.cpp in Sources */,
-				0041CE4A0F00A12400695E8C /* SamplePatch.cpp in Sources */,
 				007A7CB40F01658C00A2D6EE /* SamplePoints.cpp in Sources */,
 				007A7CB80F01658C00A2D6EE /* SampleStrokeText.cpp in Sources */,
 				007A7CBD0F01658C00A2D6EE /* SampleTextOnPath.cpp in Sources */,
@@ -937,7 +936,6 @@
 				005E92DC0FF08507008965B9 /* SampleFilter2.cpp in Sources */,
 				27005D16100903C100E275B6 /* SampleLines.cpp in Sources */,
 				27005D5F10095B2B00E275B6 /* SampleCircle.cpp in Sources */,
-				00C1B809103857A400FA5948 /* SampleFillType.cpp in Sources */,
 				00AF9B18103CD5EB00CBBCB3 /* SampleDitherBitmap.cpp in Sources */,
 				001B871E1042184D00C84ED4 /* Forth.cpp in Sources */,
 				00BB289B104781D00057BF7E /* SampleForth.cpp in Sources */,
@@ -1022,6 +1020,8 @@
 				009F9D0612C3E89F00C7FD4A /* SampleTiling.cpp in Sources */,
 				009F9D0A12C3E8AF00C7FD4A /* SampleFilter.cpp in Sources */,
 				009F9D1A12C3EB2600C7FD4A /* SampleGM.cpp in Sources */,
+				D5A682D712E9CE8500CDDDC6 /* SamplePatch.cpp in Sources */,
+				D5F4A21F12E9D75300DE986A /* SampleFillType.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};