Move ViewMatrix off of drawstate

BUG=skia:

Review URL: https://codereview.chromium.org/815553003
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index b486404..dd15aed 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -92,7 +92,8 @@
                         continue;
                     }
                     GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
-                    gp.reset(GrCubicEffect::Create(0xff000000, et, *tt.target()->caps()));
+                    gp.reset(GrCubicEffect::Create(0xff000000, SkMatrix::I(), et,
+                                                   *tt.target()->caps()));
                     if (!gp) {
                         continue;
                     }
@@ -250,8 +251,8 @@
                         continue;
                     }
                     GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
-                    gp.reset(GrConicEffect::Create(0xff000000, et, *tt.target()->caps(),
-                                                   SkMatrix::I()));
+                    gp.reset(GrConicEffect::Create(0xff000000, SkMatrix::I(), et,
+                                                   *tt.target()->caps(), SkMatrix::I()));
                     if (!gp) {
                         continue;
                     }
@@ -440,8 +441,8 @@
                         continue;
                     }
                     GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
-                    gp.reset(GrQuadEffect::Create(0xff000000, et, *tt.target()->caps(),
-                                                  SkMatrix::I()));
+                    gp.reset(GrQuadEffect::Create(0xff000000, SkMatrix::I(), et,
+                                                  *tt.target()->caps(), SkMatrix::I()));
                     if (!gp) {
                         continue;
                     }
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 65a1816..68610e0 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -134,7 +134,8 @@
 
                 GrDrawState ds;
                 SkAutoTUnref<const GrGeometryProcessor> gp(
-                        GrDefaultGeoProcFactory::Create(0xff000000));
+                        GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
+                                                        0xff000000));
                 ds.addCoverageProcessor(fp);
                 ds.setRenderTarget(rt);
 
@@ -190,7 +191,8 @@
 
                 GrDrawState ds;
                 SkAutoTUnref<const GrGeometryProcessor> gp(
-                        GrDefaultGeoProcFactory::Create(0xff000000));
+                        GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
+                                                        0xff000000));
                 ds.addCoverageProcessor(fp);
                 ds.setRenderTarget(rt);
 
diff --git a/gm/rrects.cpp b/gm/rrects.cpp
index bacc819..e6c62e9 100644
--- a/gm/rrects.cpp
+++ b/gm/rrects.cpp
@@ -126,7 +126,8 @@
                             SkRect bounds = rrect.getBounds();
                             bounds.outset(2.f, 2.f);
 
-                            tt.target()->drawSimpleRect(&drawState, 0xff000000, bounds);
+                            tt.target()->drawSimpleRect(&drawState, 0xff000000, SkMatrix::I(),
+                                                        bounds);
                         } else {
                             drew = false;
                         }
diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp
index beb98b6..8a59532 100644
--- a/gm/texturedomaineffect.cpp
+++ b/gm/texturedomaineffect.cpp
@@ -130,11 +130,11 @@
                     }
                     SkMatrix viewMatrix;
                     viewMatrix.setTranslate(x, y);
-                    GrDrawState drawState(viewMatrix);
+                    GrDrawState drawState;
                     drawState.setRenderTarget(rt);
                     drawState.addColorProcessor(fp);
 
-                    tt.target()->drawSimpleRect(&drawState, GrColor_WHITE, renderRect);
+                    tt.target()->drawSimpleRect(&drawState, GrColor_WHITE, viewMatrix, renderRect);
                     x += renderRect.width() + kTestPad;
                 }
                 y += renderRect.height() + kTestPad;
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index dbf9cd8..ed551ff 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -115,10 +115,10 @@
                 if (fp) {
                     SkMatrix viewMatrix;
                     viewMatrix.setTranslate(x, y);
-                    GrDrawState drawState(viewMatrix);
+                    GrDrawState drawState;
                     drawState.setRenderTarget(rt);
                     drawState.addColorProcessor(fp);
-                    tt.target()->drawSimpleRect(&drawState, GrColor_WHITE, renderRect);
+                    tt.target()->drawSimpleRect(&drawState, GrColor_WHITE, viewMatrix, renderRect);
                 }
                 x += renderRect.width() + kTestPad;
             }
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index ead8ded..60e0104 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -774,6 +774,7 @@
     GrPathRenderer* getPathRenderer(
                     const GrDrawTarget* target,
                     const GrDrawState*,
+                    const SkMatrix& viewMatrix,
                     const SkPath& path,
                     const SkStrokeRec& stroke,
                     bool allowSW,
@@ -860,10 +861,7 @@
     class AutoCheckFlush;
     /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
     /// draw state is left unmodified.
-    GrDrawTarget* prepareToDraw(GrDrawState* ds,
-                                const GrPaint* paint,
-                                const SkMatrix* viewMatrix,
-                                const AutoCheckFlush*);
+    GrDrawTarget* prepareToDraw(GrDrawState* ds, const GrPaint* paint, const AutoCheckFlush*);
 
     void internalDrawPath(GrDrawTarget*,
                           GrDrawState*,
diff --git a/include/gpu/GrPathRendererChain.h b/include/gpu/GrPathRendererChain.h
index 8e1f49b..07d6494 100644
--- a/include/gpu/GrPathRendererChain.h
+++ b/include/gpu/GrPathRendererChain.h
@@ -15,6 +15,7 @@
 class GrDrawState;
 class GrDrawTarget;
 class GrPathRenderer;
+class SkMatrix;
 class SkPath;
 class SkStrokeRec;
 
@@ -58,6 +59,7 @@
         StencilSupport in GrPathRenderer.h. */
     GrPathRenderer* getPathRenderer(const GrDrawTarget* target,
                                     const GrDrawState*,
+                                    const SkMatrix& viewMatrix,
                                     const SkPath& path,
                                     const SkStrokeRec& rec,
                                     DrawType drawType,
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 3a344ce..47b68ed 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -627,7 +627,7 @@
 
 private:
     QuadEdgeEffect(GrColor color, const SkMatrix& localMatrix)
-        : INHERITED(color, false, localMatrix) {
+        : INHERITED(color, SkMatrix::I(), localMatrix) {
         this->initClassID<QuadEdgeEffect>();
         fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
         fInQuadEdge = &this->addVertexAttrib(GrAttribute("inQuadEdge", kVec4f_GrVertexAttribType));
@@ -671,6 +671,7 @@
 
 bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
                                          const GrDrawState*,
+                                         const SkMatrix& viewMatrix,
                                          const SkPath& path,
                                          const SkStrokeRec& stroke,
                                          bool antiAlias) const {
@@ -681,6 +682,7 @@
 bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
                                         GrDrawState* drawState,
                                         GrColor color,
+                                        const SkMatrix& vm,
                                         const SkPath& origPath,
                                         const SkStrokeRec&,
                                         bool antiAlias) {
@@ -690,14 +692,12 @@
         return true;
     }
 
-    SkMatrix viewMatrix = drawState->getViewMatrix();
+    SkMatrix viewMatrix = vm;
     SkMatrix invert;
     if (!viewMatrix.invert(&invert)) {
         return false;
     }
 
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
-
     // We use the fact that SkPath::transform path does subdivision based on
     // perspective. Otherwise, we apply the view matrix when copying to the
     // segment representation.
diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h
index 05f60fb..b07781f 100644
--- a/src/gpu/GrAAConvexPathRenderer.h
+++ b/src/gpu/GrAAConvexPathRenderer.h
@@ -17,6 +17,7 @@
 
     virtual bool canDrawPath(const GrDrawTarget*,
                              const GrDrawState*,
+                             const SkMatrix& viewMatrix,
                              const SkPath&,
                              const SkStrokeRec&,
                              bool antiAlias) const SK_OVERRIDE;
@@ -25,6 +26,7 @@
     virtual bool onDrawPath(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
+                            const SkMatrix& viewMatrix,
                             const SkPath&,
                             const SkStrokeRec&,
                             bool antiAlias) SK_OVERRIDE;
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index 913cda4..99093fa 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -67,6 +67,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target,
                                                 const GrDrawState* drawState,
+                                                const SkMatrix& viewMatrix,
                                                 const SkPath& path,
                                                 const SkStrokeRec& stroke,
                                                 bool antiAlias) const {
@@ -79,14 +80,13 @@
     }
 
     // currently don't support perspective
-    const SkMatrix& vm = drawState->getViewMatrix();
-    if (vm.hasPerspective()) {
+    if (viewMatrix.hasPerspective()) {
         return false;
     }
     
     // only support paths smaller than 64x64, scaled to less than 256x256
     // the goal is to accelerate rendering of lots of small paths that may be scaling
-    SkScalar maxScale = vm.getMaxScale();
+    SkScalar maxScale = viewMatrix.getMaxScale();
     const SkRect& bounds = path.getBounds();
     SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
     return maxDim < 64.f && maxDim*maxScale < 256.f;
@@ -106,6 +106,7 @@
 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
                                                GrDrawState* drawState,
                                                GrColor color,
+                                               const SkMatrix& viewMatrix,
                                                const SkPath& path,
                                                const SkStrokeRec& stroke,
                                                bool antiAlias) {
@@ -117,8 +118,7 @@
     SkASSERT(fContext);
 
     // get mip level
-    const SkMatrix& vm = drawState->getViewMatrix();
-    SkScalar maxScale = vm.getMaxScale();
+    SkScalar maxScale = viewMatrix.getMaxScale();
     const SkRect& bounds = path.getBounds();
     SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
     SkScalar size = maxScale*maxDim;
@@ -144,7 +144,7 @@
     }
 
     // use signed distance field to render
-    return this->internalDrawPath(target, drawState, color, path, pathData);
+    return this->internalDrawPath(target, drawState, color, viewMatrix, path, pathData);
 }
 
 // padding around path bounds to allow for antialiased pixels
@@ -308,6 +308,7 @@
 bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
                                                      GrDrawState* drawState,
                                                      GrColor color,
+                                                     const SkMatrix& viewMatrix,
                                                      const SkPath& path,
                                                      const PathData* pathData) {
     GrTexture* texture = fAtlas->getTexture();
@@ -319,12 +320,13 @@
     
     // set up any flags
     uint32_t flags = 0;
-    const SkMatrix& vm = drawState->getViewMatrix();
-    flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
+    flags |= viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
 
     GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
-    if (flags != fEffectFlags || fCachedGeometryProcessor->color() != color) {
+    if (flags != fEffectFlags || fCachedGeometryProcessor->color() != color ||
+        !fCachedGeometryProcessor->viewMatrix().cheapEqualTo(viewMatrix)) {
         fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color,
+                                                                                   viewMatrix,
                                                                                    texture,
                                                                                    params,
                                                                                    flags,
@@ -370,7 +372,7 @@
                               SkFixedToFloat(texture->texturePriv().normalizeFixedY(ty + th)),
                               vertSize);
     
-    vm.mapRect(&r);
+    viewMatrix.mapRect(&r);
     target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
     target->drawIndexedInstances(drawState, fCachedGeometryProcessor.get(),
                                  kTriangles_GrPrimitiveType, 1, 4, 6, &r);
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.h b/src/gpu/GrAADistanceFieldPathRenderer.h
index 7b40d94..b17b305 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.h
+++ b/src/gpu/GrAADistanceFieldPathRenderer.h
@@ -26,6 +26,7 @@
     
     virtual bool canDrawPath(const GrDrawTarget*,
                              const GrDrawState*,
+                             const SkMatrix& viewMatrix,
                              const SkPath&,
                              const SkStrokeRec&,
                              bool antiAlias) const SK_OVERRIDE;
@@ -39,6 +40,7 @@
     virtual bool onDrawPath(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
+                            const SkMatrix& viewMatrix,
                             const SkPath&,
                             const SkStrokeRec&,
                             bool antiAlias) SK_OVERRIDE;
@@ -79,8 +81,8 @@
     SkTDynamicHash<PathData, PathData::Key> fPathCache;
     PathDataList                       fPathList;
     
-    bool internalDrawPath(GrDrawTarget*, GrDrawState*, GrColor, const SkPath& path,
-                          const PathData* pathData);
+    bool internalDrawPath(GrDrawTarget*, GrDrawState*, GrColor, const SkMatrix& viewMatrix,
+                          const SkPath& path, const PathData* pathData);
     PathData* addPathToAtlas(const SkPath& path, const SkStrokeRec& stroke, bool antiAlias,
                              uint32_t dimension, SkScalar scale);
     bool freeUnusedPlot();
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 319228e..eea6463 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -644,6 +644,7 @@
 
 bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
                                               GrDrawState* drawState,
+                                              const SkMatrix& viewMatrix,
                                               uint8_t coverage,
                                               size_t vertexStride,
                                               GrDrawTarget::AutoReleaseGeometry* arg,
@@ -651,8 +652,6 @@
                                               const SkPath& path,
                                               const PtArray& lines,
                                               int lineCnt) {
-    const SkMatrix& viewM = drawState->getViewMatrix();
-
     int vertCnt = kLineSegNumVertices * lineCnt;
 
     SkASSERT(vertexStride == sizeof(LineVertex));
@@ -665,8 +664,8 @@
     const SkMatrix* toSrc = NULL;
     SkMatrix ivm;
 
-    if (viewM.hasPerspective()) {
-        if (viewM.invert(&ivm)) {
+    if (viewMatrix.hasPerspective()) {
+        if (viewMatrix.invert(&ivm)) {
             toSrc = &ivm;
         }
     }
@@ -685,6 +684,7 @@
 
 bool GrAAHairLinePathRenderer::createBezierGeom(GrDrawTarget* target,
                                                 GrDrawState* drawState,
+                                                const SkMatrix& viewMatrix,
                                                 GrDrawTarget::AutoReleaseGeometry* arg,
                                                 SkRect* devBounds,
                                                 const SkPath& path,
@@ -695,8 +695,6 @@
                                                 const IntArray& qSubdivs,
                                                 const FloatArray& cWeights,
                                                 size_t vertexStride) {
-    const SkMatrix& viewM = drawState->getViewMatrix();
-
     int vertCnt = kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt;
 
     if (!arg->set(target, vertCnt, vertexStride, 0)) {
@@ -709,9 +707,9 @@
     const SkMatrix* toSrc = NULL;
     SkMatrix ivm;
 
-    if (viewM.hasPerspective()) {
-        if (viewM.invert(&ivm)) {
-            toDevice = &viewM;
+    if (viewMatrix.hasPerspective()) {
+        if (viewMatrix.invert(&ivm)) {
+            toDevice = &viewMatrix;
             toSrc = &ivm;
         }
     }
@@ -746,6 +744,7 @@
 
 bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target,
                                            const GrDrawState* drawState,
+                                           const SkMatrix& viewMatrix,
                                            const SkPath& path,
                                            const SkStrokeRec& stroke,
                                            bool antiAlias) const {
@@ -753,9 +752,7 @@
         return false;
     }
 
-    if (!IsStrokeHairlineOrEquivalent(stroke,
-                                      drawState->getViewMatrix(),
-                                      NULL)) {
+    if (!IsStrokeHairlineOrEquivalent(stroke, viewMatrix, NULL)) {
         return false;
     }
 
@@ -767,16 +764,16 @@
 }
 
 template <class VertexType>
-bool check_bounds(GrDrawState* drawState, const SkRect& devBounds, void* vertices, int vCount)
+bool check_bounds(const SkMatrix& viewMatrix, const SkRect& devBounds, void* vertices, int vCount)
 {
     SkRect tolDevBounds = devBounds;
     // The bounds ought to be tight, but in perspective the below code runs the verts
     // through the view matrix to get back to dev coords, which can introduce imprecision.
-    if (drawState->getViewMatrix().hasPerspective()) {
+    if (viewMatrix.hasPerspective()) {
         tolDevBounds.outset(SK_Scalar1 / 1000, SK_Scalar1 / 1000);
     } else {
         // Non-persp matrices cause this path renderer to draw in device space.
-        SkASSERT(drawState->getViewMatrix().isIdentity());
+        SkASSERT(viewMatrix.isIdentity());
     }
     SkRect actualBounds;
 
@@ -788,7 +785,7 @@
         if (SK_ScalarMax == pos.fX) {
             continue;
         }
-        drawState->getViewMatrix().mapPoints(&pos, 1);
+        viewMatrix.mapPoints(&pos, 1);
         if (first) {
             actualBounds.set(pos.fX, pos.fY, pos.fX, pos.fY);
             first = false;
@@ -806,13 +803,13 @@
 bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
                                           GrDrawState* drawState,
                                           GrColor color,
+                                          const SkMatrix& viewMatrix,
                                           const SkPath& path,
                                           const SkStrokeRec& stroke,
                                           bool antiAlias) {
     SkScalar hairlineCoverage;
     uint8_t newCoverage = 0xff;
-    if (IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(),
-                                     &hairlineCoverage)) {
+    if (IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairlineCoverage)) {
         newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
     }
 
@@ -827,18 +824,18 @@
     PREALLOC_PTARRAY(128) conics;
     IntArray qSubdivs;
     FloatArray cWeights;
-    quadCnt = generate_lines_and_quads(path, drawState->getViewMatrix(), devClipBounds,
+    quadCnt = generate_lines_and_quads(path, viewMatrix, devClipBounds,
                                        &lines, &quads, &conics, &qSubdivs, &cWeights);
     lineCnt = lines.count() / 2;
     conicCnt = conics.count() / 3;
 
     // createGeom transforms the geometry to device space when the matrix does not have
     // perspective.
-    GrDrawState::AutoViewMatrixRestore avmr;
+    SkMatrix vm = viewMatrix;
     SkMatrix invert = SkMatrix::I();
-    if (!drawState->getViewMatrix().hasPerspective()) {
-        avmr.setIdentity(drawState);
-        if (!drawState->getViewMatrix().invert(&invert)) {
+    if (!viewMatrix.hasPerspective()) {
+        vm = SkMatrix::I();
+        if (!viewMatrix.invert(&invert)) {
             return false;
         }
     }
@@ -851,14 +848,16 @@
         GrDrawState::AutoRestoreEffects are(drawState);
         uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType |
                            GrDefaultGeoProcFactory::kCoverage_GPType;
-        SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create(color,
-                                                                                   gpFlags,
+        SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create(gpFlags,
+                                                                                   color,
+                                                                                   vm,
+                                                                                   invert,
                                                                                    false,
-                                                                                   newCoverage,
-                                                                                   invert));
+                                                                                   newCoverage));
 
         if (!this->createLineGeom(target,
                                   drawState,
+                                  viewMatrix,
                                   newCoverage,
                                   gp->getVertexStride(),
                                   &arg,
@@ -870,7 +869,9 @@
         }
 
         // Check devBounds
-        SkASSERT(check_bounds<LineVertex>(drawState, devBounds, arg.vertices(),
+        SkASSERT(check_bounds<LineVertex>(viewMatrix.hasPerspective() ? viewMatrix : SkMatrix::I(),
+                                          devBounds,
+                                          arg.vertices(),
                                           kLineSegNumVertices * lineCnt));
 
         {
@@ -898,6 +899,7 @@
 
         if (!this->createBezierGeom(target,
                                     drawState,
+                                    viewMatrix,
                                     &arg,
                                     &devBounds,
                                     path,
@@ -912,12 +914,17 @@
         }
 
         // Check devBounds
-        SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices(),
-                                            kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt));
+        SkASSERT(check_bounds<BezierVertex>(viewMatrix.hasPerspective() ? viewMatrix :
+                                                                          SkMatrix::I(),
+                                            devBounds,
+                                            arg.vertices(),
+                                            kQuadNumVertices * quadCnt +
+                                            kQuadNumVertices * conicCnt));
 
         if (quadCnt > 0) {
             SkAutoTUnref<GrGeometryProcessor> hairQuadProcessor(
                     GrQuadEffect::Create(color,
+                                         vm,
                                          kHairlineAA_GrProcessorEdgeType,
                                          *target->caps(),
                                          invert,
@@ -943,8 +950,8 @@
 
         if (conicCnt > 0) {
             SkAutoTUnref<GrGeometryProcessor> hairConicProcessor(
-                    GrConicEffect::Create(color, kHairlineAA_GrProcessorEdgeType, *target->caps(),
-                                          invert, newCoverage));
+                    GrConicEffect::Create(color, vm, kHairlineAA_GrProcessorEdgeType,
+                                          *target->caps(), invert, newCoverage));
             SkASSERT(hairConicProcessor);
             GrDrawState::AutoRestoreEffects are(drawState);
             target->setIndexSourceToBuffer(fQuadsIndexBuffer);
diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h
index 5b7b785..8bc3e3e 100644
--- a/src/gpu/GrAAHairLinePathRenderer.h
+++ b/src/gpu/GrAAHairLinePathRenderer.h
@@ -19,6 +19,7 @@
 
     virtual bool canDrawPath(const GrDrawTarget*,
                              const GrDrawState*,
+                             const SkMatrix& viewMatrix,
                              const SkPath&,
                              const SkStrokeRec&,
                              bool antiAlias) const SK_OVERRIDE;
@@ -31,6 +32,7 @@
     virtual bool onDrawPath(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
+                            const SkMatrix& viewMatrix,
                             const SkPath&,
                             const SkStrokeRec&,
                             bool antiAlias) SK_OVERRIDE;
@@ -42,6 +44,7 @@
 
     bool createLineGeom(GrDrawTarget* target,
                         GrDrawState*,
+                        const SkMatrix& viewMatrix,
                         uint8_t coverage,
                         size_t vertexStride,
                         GrDrawTarget::AutoReleaseGeometry* arg,
@@ -52,6 +55,7 @@
 
     bool createBezierGeom(GrDrawTarget* target,
                           GrDrawState*,
+                          const SkMatrix& viewMatrix,
                           GrDrawTarget::AutoReleaseGeometry* arg,
                           SkRect* devBounds,
                           const SkPath& path,
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index 3f0e1b0..444bb51 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -25,19 +25,20 @@
 };
 }
 
-static const GrGeometryProcessor* create_rect_gp(const GrDrawState& drawState, GrColor color,
+static const GrGeometryProcessor* create_rect_gp(const GrDrawState& drawState,
+                                                 GrColor color,
                                                  CoverageAttribType* type,
                                                  const SkMatrix& localMatrix) {
     uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType;
     const GrGeometryProcessor* gp;
     if (drawState.canTweakAlphaForCoverage()) {
-        gp = GrDefaultGeoProcFactory::Create(color, flags, localMatrix);
+        gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localMatrix);
         SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
         *type = kUseColor_CoverageAttribType;
     } else {
         flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
-        gp = GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color), 0xff,
-                                             localMatrix);
+        gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localMatrix,
+                                             GrColorIsOpaque(color));
         SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
         *type = kUseCoverage_CoverageAttribType;
     }
@@ -180,12 +181,17 @@
 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
                                           GrDrawState* drawState,
                                           GrColor color,
-                                          const SkMatrix& localMatrix,
+                                          const SkMatrix& viewMatrix,
                                           const SkRect& rect,
-                                          const SkMatrix& combinedMatrix,
                                           const SkRect& devRect) {
     GrDrawState::AutoRestoreEffects are(drawState);
 
+    SkMatrix localMatrix;
+    if (!viewMatrix.invert(&localMatrix)) {
+        SkDebugf("Cannot invert\n");
+        return;
+    }
+
     CoverageAttribType type;
     SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type,
                                                               localMatrix));
@@ -217,7 +223,7 @@
     SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
     inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
 
-    if (combinedMatrix.rectStaysRect()) {
+    if (viewMatrix.rectStaysRect()) {
         // Temporarily #if'ed out. We don't want to pass in the devRect but
         // right now it is computed in GrContext::apply_aa_to_rect and we don't
         // want to throw away the work
@@ -231,8 +237,8 @@
     } else {
         // compute transformed (1, 0) and (0, 1) vectors
         SkVector vec[2] = {
-          { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
-          { combinedMatrix[SkMatrix::kMSkewX],  combinedMatrix[SkMatrix::kMScaleY] }
+          { viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] },
+          { viewMatrix[SkMatrix::kMSkewX],  viewMatrix[SkMatrix::kMScaleY] }
         };
 
         vec[0].normalize();
@@ -243,7 +249,7 @@
         // create the rotated rect
         fan0Pos->setRectFan(rect.fLeft, rect.fTop,
                             rect.fRight, rect.fBottom, vertexStride);
-        combinedMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
+        viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
 
         // Now create the inset points and then outset the original
         // rotated points
@@ -312,16 +318,15 @@
 void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
                                     GrDrawState* drawState,
                                     GrColor color,
-                                    const SkMatrix& localMatrix,
+                                    const SkMatrix& viewMatrix,
                                     const SkRect& rect,
-                                    const SkMatrix& combinedMatrix,
                                     const SkRect& devRect,
                                     const SkStrokeRec& stroke) {
     SkVector devStrokeSize;
     SkScalar width = stroke.getWidth();
     if (width > 0) {
         devStrokeSize.set(width, width);
-        combinedMatrix.mapVectors(&devStrokeSize, 1);
+        viewMatrix.mapVectors(&devStrokeSize, 1);
         devStrokeSize.setAbs(devStrokeSize);
     } else {
         devStrokeSize.set(SK_Scalar1, SK_Scalar1);
@@ -359,7 +364,7 @@
     }
 
     if (spare <= 0 && miterStroke) {
-        this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMatrix::I(),
+        this->fillAARect(target, drawState, color, viewMatrix, devOutside,
                          devOutside);
         return;
     }
@@ -377,20 +382,26 @@
         devOutsideAssist.outset(0, ry);
     }
 
-    this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside, devOutsideAssist,
+    this->geometryStrokeAARect(target, drawState, color, viewMatrix, devOutside, devOutsideAssist,
                                devInside, miterStroke);
 }
 
 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
                                             GrDrawState* drawState,
                                             GrColor color,
-                                            const SkMatrix& localMatrix,
+                                            const SkMatrix& viewMatrix,
                                             const SkRect& devOutside,
                                             const SkRect& devOutsideAssist,
                                             const SkRect& devInside,
                                             bool miterStroke) {
     GrDrawState::AutoRestoreEffects are(drawState);
 
+    SkMatrix localMatrix;
+    if (!viewMatrix.invert(&localMatrix)) {
+        SkDebugf("Cannot invert\n");
+        return;
+    }
+
     CoverageAttribType type;
     SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type,
                                                               localMatrix));
@@ -518,23 +529,22 @@
 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target,
                                          GrDrawState* drawState,
                                          GrColor color,
-                                         const SkMatrix& localMatrix,
-                                         const SkRect rects[2],
-                                         const SkMatrix& combinedMatrix) {
-    SkASSERT(combinedMatrix.rectStaysRect());
+                                         const SkMatrix& viewMatrix,
+                                         const SkRect rects[2]) {
+    SkASSERT(viewMatrix.rectStaysRect());
     SkASSERT(!rects[1].isEmpty());
 
     SkRect devOutside, devOutsideAssist, devInside;
-    combinedMatrix.mapRect(&devOutside, rects[0]);
+    viewMatrix.mapRect(&devOutside, rects[0]);
     // can't call mapRect for devInside since it calls sort
-    combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2);
+    viewMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2);
 
     if (devInside.isEmpty()) {
-        this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMatrix::I(),
+        this->fillAARect(target, drawState, color, viewMatrix, devOutside,
                          devOutside);
         return;
     }
 
-    this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside, devOutsideAssist,
+    this->geometryStrokeAARect(target, drawState, color, viewMatrix, devOutside, devOutsideAssist,
                                devInside, true);
 }
diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h
index d97a111..d6d07dd 100644
--- a/src/gpu/GrAARectRenderer.h
+++ b/src/gpu/GrAARectRenderer.h
@@ -45,19 +45,17 @@
     void fillAARect(GrDrawTarget* target,
                     GrDrawState* ds,
                     GrColor color,
-                    const SkMatrix& localMatrix,
+                    const SkMatrix& viewMatrix,
                     const SkRect& rect,
-                    const SkMatrix& combinedMatrix,
                     const SkRect& devRect) {
-        this->geometryFillAARect(target, ds, color, localMatrix, rect, combinedMatrix, devRect);
+        this->geometryFillAARect(target, ds, color, viewMatrix, rect, devRect);
     }
 
     void strokeAARect(GrDrawTarget*,
                       GrDrawState*,
                       GrColor,
-                      const SkMatrix& localMatrix,
+                      const SkMatrix& viewMatrix,
                       const SkRect& rect,
-                      const SkMatrix& combinedMatrix,
                       const SkRect& devRect,
                       const SkStrokeRec& stroke);
 
@@ -65,9 +63,8 @@
     void fillAANestedRects(GrDrawTarget*,
                            GrDrawState*,
                            GrColor,
-                           const SkMatrix& localMatrix,
-                           const SkRect rects[2],
-                           const SkMatrix& combinedMatrix);
+                           const SkMatrix& viewMatrix,
+                           const SkRect rects[2]);
 
 private:
     GrIndexBuffer* aaStrokeRectIndexBuffer(bool miterStroke);
@@ -75,15 +72,14 @@
     void geometryFillAARect(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
-                            const SkMatrix& localMatrix,
+                            const SkMatrix& viewMatrix,
                             const SkRect& rect,
-                            const SkMatrix& combinedMatrix,
                             const SkRect& devRect);
 
     void geometryStrokeAARect(GrDrawTarget*,
                               GrDrawState*,
                               GrColor,
-                              const SkMatrix& localMatrix,
+                              const SkMatrix& viewMatrix,
                               const SkRect& devOutside,
                               const SkRect& devOutsideAssist,
                               const SkRect& devInside,
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 94b2770..fdf9600 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -528,7 +528,7 @@
 
     if (fCurrVertex > 0) {
         GrDrawState drawState;
-        drawState.setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
+        drawState.setFromPaint(fPaint, fContext->getRenderTarget());
 
         // setup our sampler state for our text texture/atlas
         SkASSERT(SkIsAlign4(fCurrVertex));
@@ -566,7 +566,7 @@
             if (textureUniqueID != fEffectTextureUniqueID ||
                 fCachedGeometryProcessor->color() != color) {
                 uint32_t flags = GrDefaultGeoProcFactory::kLocalCoord_GPType;
-                fCachedGeometryProcessor.reset(GrDefaultGeoProcFactory::Create(color, flags));
+                fCachedGeometryProcessor.reset(GrDefaultGeoProcFactory::Create(flags, color));
                 fCachedTextureProcessor.reset(GrSimpleTextureEffect::Create(fCurrTexture,
                                                                             SkMatrix::I(),
                                                                             params));
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 4b57868..c2dc4fb 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -56,6 +56,7 @@
 bool path_needs_SW_renderer(GrContext* context,
                             const GrDrawTarget* gpu,
                             const GrDrawState* drawState,
+                            const SkMatrix& viewMatrix,
                             const SkPath& origPath,
                             const SkStrokeRec& stroke,
                             bool doAA) {
@@ -69,7 +70,7 @@
                                          GrPathRendererChain::kColorAntiAlias_DrawType :
                                          GrPathRendererChain::kColor_DrawType;
 
-    return NULL == context->getPathRenderer(gpu, drawState, *path, stroke, false, type);
+    return NULL == context->getPathRenderer(gpu, drawState, viewMatrix, *path, stroke, false, type);
 }
 }
 
@@ -79,12 +80,18 @@
  * entire clip should be rendered in SW and then uploaded en masse to the gpu.
  */
 bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState,
+                                      const SkVector& clipToMaskOffset,
                                       const GrReducedClip::ElementList& elements) {
     // TODO: generalize this function so that when
     // a clip gets complex enough it can just be done in SW regardless
     // of whether it would invoke the GrSoftwarePathRenderer.
     SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
 
+    // Set the matrix so that rendered clip elements are transformed to mask space from clip
+    // space.
+    SkMatrix translate;
+    translate.setTranslate(clipToMaskOffset);
+
     for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
         const Element* element = iter.get();
         // rects can always be drawn directly w/o using the software path
@@ -92,8 +99,8 @@
         if (Element::kRect_Type != element->getType()) {
             SkPath path;
             element->asPath(&path);
-            if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawState, path, stroke,
-                                       element->isAA())) {
+            if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawState, translate,
+                                       path, stroke, element->isAA())) {
                 return true;
             }
         }
@@ -273,17 +280,25 @@
     if (0 == rt->numSamples() && requiresAA) {
         GrTexture* result = NULL;
 
-        if (this->useSWOnlyPath(drawState, elements)) {
+        // The top-left of the mask corresponds to the top-left corner of the bounds.
+        SkVector clipToMaskOffset = {
+            SkIntToScalar(-clipSpaceIBounds.fLeft),
+            SkIntToScalar(-clipSpaceIBounds.fTop)
+        };
+
+        if (this->useSWOnlyPath(drawState, clipToMaskOffset, elements)) {
             // The clip geometry is complex enough that it will be more efficient to create it
             // entirely in software
             result = this->createSoftwareClipMask(genID,
                                                   initialState,
                                                   elements,
+                                                  clipToMaskOffset,
                                                   clipSpaceIBounds);
         } else {
             result = this->createAlphaClipMask(genID,
                                                initialState,
                                                elements,
+                                               clipToMaskOffset,
                                                clipSpaceIBounds);
         }
 
@@ -337,6 +352,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 bool GrClipMaskManager::drawElement(GrDrawState* drawState,
+                                    const SkMatrix& viewMatrix,
                                     GrTexture* target,
                                     const SkClipStack::Element* element,
                                     GrPathRenderer* pr) {
@@ -357,15 +373,16 @@
             // TODO: Do rects directly to the accumulator using a aa-rect GrProcessor that covers
             // the entire mask bounds and writes 0 outside the rect.
             if (element->isAA()) {
+                SkRect devRect = element->getRect();
+                viewMatrix.mapRect(&devRect);
                 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
                                                                     drawState,
                                                                     color,
-                                                                    SkMatrix::I(),
+                                                                    viewMatrix,
                                                                     element->getRect(),
-                                                                    SkMatrix::I(),
-                                                                    element->getRect());
+                                                                    devRect);
             } else {
-                fClipTarget->drawSimpleRect(drawState, color, element->getRect());
+                fClipTarget->drawSimpleRect(drawState, color, viewMatrix, element->getRect());
             }
             return true;
         default: {
@@ -380,14 +397,14 @@
                 GrPathRendererChain::DrawType type;
                 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
                                          GrPathRendererChain::kColor_DrawType;
-                pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke,
-                                                         false, type);
+                pr = this->getContext()->getPathRenderer(fClipTarget, drawState, viewMatrix, path,
+                                                         stroke, false, type);
             }
             if (NULL == pr) {
                 return false;
             }
 
-            pr->drawPath(fClipTarget, drawState, color, path, stroke, element->isAA());
+            pr->drawPath(fClipTarget, drawState, color, viewMatrix, path, stroke, element->isAA());
             break;
         }
     }
@@ -414,8 +431,8 @@
         GrPathRendererChain::DrawType type = element->isAA() ?
             GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
             GrPathRendererChain::kStencilAndColor_DrawType;
-        *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, false,
-                                                  type);
+        *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, SkMatrix::I(), path,
+                                                  stroke, false, type);
         return SkToBool(*pr);
     }
 }
@@ -441,7 +458,7 @@
                                       GrTextureDomain::kDecal_Mode,
                                       GrTextureParams::kNone_FilterMode))->unref();
     // The color passed in here does not matter since the coverageSetOpXP won't read it.
-    fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound));
+    fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkMatrix::I(), SkRect::Make(dstBound));
 }
 
 GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
@@ -499,6 +516,7 @@
 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
                                                   GrReducedClip::InitialState initialState,
                                                   const GrReducedClip::ElementList& elements,
+                                                  const SkVector& clipToMaskOffset,
                                                   const SkIRect& clipSpaceIBounds) {
     SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
 
@@ -516,19 +534,15 @@
         return NULL;
     }
 
-    // The top-left of the mask corresponds to the top-left corner of the bounds.
-    SkVector clipToMaskOffset = {
-        SkIntToScalar(-clipSpaceIBounds.fLeft),
-        SkIntToScalar(-clipSpaceIBounds.fTop)
-    };
+    // Set the matrix so that rendered clip elements are transformed to mask space from clip
+    // space.
+    SkMatrix translate;
+    translate.setTranslate(clipToMaskOffset);
+
     // The texture may be larger than necessary, this rect represents the part of the texture
     // we populate with a rasterization of the clip.
     SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpaceIBounds.height());
 
-    // Set the matrix so that rendered clip elements are transformed to mask space from clip space.
-    SkMatrix translate;
-    translate.setTranslate(clipToMaskOffset);
-
     // The scratch texture that we are drawing into can be substantially larger than the mask. Only
     // clear the part that we care about.
     fClipTarget->clear(&maskSpaceIBounds,
@@ -549,7 +563,7 @@
         SkRegion::Op op = element->getOp();
         bool invert = element->isInverseFilled();
         if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
-            GrDrawState drawState(translate);
+            GrDrawState drawState;
             drawState.enableState(GrDrawState::kClip_StateBit);
 
             GrPathRenderer* pr = NULL;
@@ -600,7 +614,7 @@
                 set_coverage_drawing_xpf(op, invert, &drawState);
             }
 
-            if (!this->drawElement(&drawState, dst, element, pr)) {
+            if (!this->drawElement(&drawState, translate, dst, element, pr)) {
                 fAACache.reset();
                 return NULL;
             }
@@ -619,7 +633,7 @@
                                 maskSpaceIBounds,
                                 maskSpaceElementIBounds);
             } else {
-                GrDrawState backgroundDrawState(translate);
+                GrDrawState backgroundDrawState;
                 backgroundDrawState.enableState(GrDrawState::kClip_StateBit);
                 backgroundDrawState.setRenderTarget(result->asRenderTarget());
 
@@ -634,16 +648,17 @@
                                              0xffff);
                 backgroundDrawState.setStencil(kDrawOutsideElement);
                 // The color passed in here does not matter since the coverageSetOpXP won't read it.
-                fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, clipSpaceIBounds);
+                fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, translate,
+                                            clipSpaceIBounds);
             }
         } else {
-            GrDrawState drawState(translate);
+            GrDrawState drawState;
             drawState.enableState(GrDrawState::kClip_StateBit);
 
             // all the remaining ops can just be directly draw into the accumulation buffer
             set_coverage_drawing_xpf(op, false, &drawState);
             // The color passed in here does not matter since the coverageSetOpXP won't read it.
-            this->drawElement(&drawState, result, element);
+            this->drawElement(&drawState, translate, result, element);
         }
     }
 
@@ -676,8 +691,8 @@
             SkIntToScalar(clipSpaceToStencilOffset.fX),
             SkIntToScalar(clipSpaceToStencilOffset.fY)
         };
-        SkMatrix matrix;
-        matrix.setTranslate(translate);
+        SkMatrix viewMatrix;
+        viewMatrix.setTranslate(translate);
 
         // We set the current clip to the bounds so that our recursive draws are scissored to them.
         SkIRect stencilSpaceIBounds(clipSpaceIBounds);
@@ -697,7 +712,7 @@
         for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
             const Element* element = iter.get();
 
-            GrDrawState drawState(matrix);
+            GrDrawState drawState;
             drawState.setRenderTarget(rt);
             drawState.enableState(GrDrawState::kClip_StateBit);
 
@@ -732,6 +747,7 @@
                 }
                 pr = this->getContext()->getPathRenderer(fClipTarget,
                                                          &drawState,
+                                                         viewMatrix,
                                                          clipPath,
                                                          stroke,
                                                          false,
@@ -769,16 +785,17 @@
                                              0xffff);
                 if (Element::kRect_Type == element->getType()) {
                     *drawState.stencil() = gDrawToStencil;
-                    fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, element->getRect());
+                    fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, viewMatrix,
+                                                element->getRect());
                 } else {
                     if (!clipPath.isEmpty()) {
                         GrDrawTarget::AutoGeometryPush agp(fClipTarget);
                         if (canRenderDirectToStencil) {
                             *drawState.stencil() = gDrawToStencil;
-                            pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, clipPath, stroke,
-                                         false);
+                            pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, viewMatrix,
+                                         clipPath, stroke, false);
                         } else {
-                            pr->stencilPath(fClipTarget, &drawState, clipPath, stroke);
+                            pr->stencilPath(fClipTarget, &drawState, viewMatrix, clipPath, stroke);
                         }
                     }
                 }
@@ -793,16 +810,17 @@
 
                 if (canDrawDirectToClip) {
                     if (Element::kRect_Type == element->getType()) {
-                        fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE,
+                        fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, viewMatrix,
                                                     element->getRect());
                     } else {
                         GrDrawTarget::AutoGeometryPush agp(fClipTarget);
-                        pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, clipPath, stroke, false);
+                        pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, viewMatrix,
+                                     clipPath, stroke, false);
                     }
                 } else {
                     // The view matrix is setup to do clip space -> stencil space translation, so
                     // draw rect in clip space.
-                    fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE,
+                    fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, viewMatrix,
                                                 SkRect::Make(clipSpaceIBounds));
                 }
             }
@@ -989,6 +1007,7 @@
 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
                                                      GrReducedClip::InitialState initialState,
                                                      const GrReducedClip::ElementList& elements,
+                                                     const SkVector& clipToMaskOffset,
                                                      const SkIRect& clipSpaceIBounds) {
     SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
 
@@ -1003,11 +1022,12 @@
 
     GrSWMaskHelper helper(this->getContext());
 
-    SkMatrix matrix;
-    matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft),
-                        SkIntToScalar(-clipSpaceIBounds.fTop));
+    // Set the matrix so that rendered clip elements are transformed to mask space from clip
+    // space.
+    SkMatrix translate;
+    translate.setTranslate(clipToMaskOffset);
 
-    helper.init(maskSpaceIBounds, &matrix, false);
+    helper.init(maskSpaceIBounds, &translate, false);
     helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x00);
     SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
 
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index c17231e..fef47e4 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -113,12 +113,14 @@
     GrTexture* createAlphaClipMask(int32_t elementsGenID,
                                    GrReducedClip::InitialState initialState,
                                    const GrReducedClip::ElementList& elements,
+                                   const SkVector& clipToMaskOffset,
                                    const SkIRect& clipSpaceIBounds);
 
     // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture.
     GrTexture* createSoftwareClipMask(int32_t elementsGenID,
                                       GrReducedClip::InitialState initialState,
                                       const GrReducedClip::ElementList& elements,
+                                      const SkVector& clipToMaskOffset,
                                       const SkIRect& clipSpaceIBounds);
 
     // Returns the cached mask texture if it matches the elementsGenID and the clipSpaceIBounds.
@@ -131,12 +133,15 @@
                                 const SkIRect& clipSpaceIBounds,
                                 bool willUpload);
 
-    bool useSWOnlyPath(const GrDrawState*, const GrReducedClip::ElementList& elements);
+    bool useSWOnlyPath(const GrDrawState*,
+                       const SkVector& clipToMaskOffset,
+                       const GrReducedClip::ElementList& elements);
 
     // Draws a clip element into the target alpha mask. The caller should have already setup the
     // desired blend operation. Optionally if the caller already selected a path renderer it can
     // be passed. Otherwise the function will select one if the element is a path.
     bool drawElement(GrDrawState*,
+                     const SkMatrix& viewMatrix,
                      GrTexture* target,
                      const SkClipStack::Element*,
                      GrPathRenderer* pr = NULL);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 13de4fe..3c23032 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -315,7 +315,7 @@
         uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
                          GrDefaultGeoProcFactory::kLocalCoord_GPType;
         SkAutoTUnref<const GrGeometryProcessor> gp(
-                GrDefaultGeoProcFactory::Create(GrColor_WHITE, flags));
+                GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE));
 
         GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStride(),  0);
         SkASSERT(gp->getVertexStride() == 2 * sizeof(SkPoint));
@@ -540,7 +540,7 @@
 
     AutoCheckFlush acf(this);
     GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this);
-    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL, &acf);
+    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, &acf);
     if (NULL == target) {
         return;
     }
@@ -583,13 +583,13 @@
 
         AutoCheckFlush acf(this);
         GrDrawState drawState;
-        GrDrawTarget* target = this->prepareToDraw(&drawState, paint, &SkMatrix::I(), &acf);
+        GrDrawTarget* target = this->prepareToDraw(&drawState, paint, &acf);
         if (NULL == target) {
             return;
         }
 
         GR_CREATE_TRACE_MARKER("GrContext::drawPaintWithPerspective", target);
-        target->drawRect(&drawState, paint->getColor(), r, NULL, &localMatrix);
+        target->drawRect(&drawState, paint->getColor(), SkMatrix::I(), r, NULL, &localMatrix);
     }
 }
 
@@ -692,14 +692,13 @@
 
     AutoCheckFlush acf(this);
     GrDrawState drawState;
-    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
     if (NULL == target) {
         return;
     }
 
     GR_CREATE_TRACE_MARKER("GrContext::drawRect", target);
     SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth();
-    SkMatrix matrix = drawState.getViewMatrix();
 
     // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
     // cases where the RT is fully inside a stroke.
@@ -716,7 +715,7 @@
         // Does the clip contain the entire RT?
         if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpaceRTRect)) {
             SkMatrix invM;
-            if (!matrix.invert(&invM)) {
+            if (!viewMatrix.invert(&invM)) {
                 return;
             }
             // Does the rect bound the RT?
@@ -739,29 +738,26 @@
     GrColor color = paint.getColor();
     SkRect devBoundRect;
     bool needAA = paint.isAntiAlias() && !drawState.getRenderTarget()->isMultisampled();
-    bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, rect, width, matrix,
-                                           color);
+    bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, rect, width,
+                                           viewMatrix, color);
 
     if (doAA) {
-        SkMatrix invert;
-        if (!drawState.getViewMatrix().invert(&invert)) {
-            return;
-        }
-        GrDrawState::AutoViewMatrixRestore avmr(&drawState);
-
         if (width >= 0) {
             const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec();
             fAARectRenderer->strokeAARect(target,
                                           &drawState,
                                           color,
-                                          invert,
+                                          viewMatrix,
                                           rect,
-                                          matrix,
                                           devBoundRect,
                                           strokeRec);
         } else {
             // filled AA rect
-            fAARectRenderer->fillAARect(target, &drawState, color, invert, rect, matrix,
+            fAARectRenderer->fillAARect(target,
+                                        &drawState,
+                                        color,
+                                        viewMatrix,
+                                        rect,
                                         devBoundRect);
         }
         return;
@@ -773,7 +769,11 @@
         // unitSquareVertexBuffer()
 
         static const int worstCaseVertCount = 10;
-        SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create(color));
+        SkAutoTUnref<const GrGeometryProcessor> gp(
+                GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
+                                                color,
+                                                viewMatrix,
+                                                SkMatrix::I()));
         GrDrawTarget::AutoReleaseGeometry geo(target,
                                               worstCaseVertCount,
                                               gp->getVertexStride(),
@@ -807,7 +807,7 @@
         target->drawNonIndexed(&drawState, gp, primType, 0, vertCount);
     } else {
         // filled BW rect
-        target->drawSimpleRect(&drawState, color, rect);
+        target->drawSimpleRect(&drawState, color, viewMatrix, rect);
     }
 }
 
@@ -818,21 +818,22 @@
                                     const SkMatrix* localMatrix) {
     AutoCheckFlush acf(this);
     GrDrawState drawState;
-    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
     if (NULL == target) {
         return;
     }
 
     GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target);
 
-    target->drawRect(&drawState, paint.getColor(), rectToDraw, &localRect, localMatrix);
+    target->drawRect(&drawState, paint.getColor(), viewMatrix, rectToDraw, &localRect, localMatrix);
 }
 
 static const GrGeometryProcessor* set_vertex_attributes(const SkPoint* texCoords,
                                                         const GrColor* colors,
                                                         int* colorOffset,
                                                         int* texOffset,
-                                                        GrColor color) {
+                                                        GrColor color,
+                                                        const SkMatrix& viewMatrix) {
     *texOffset = -1;
     *colorOffset = -1;
     uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType;
@@ -848,7 +849,7 @@
         *colorOffset = sizeof(SkPoint);
         flags |= GrDefaultGeoProcFactory::kColor_GPType;
     }
-    return GrDefaultGeoProcFactory::Create(color, flags);
+    return GrDefaultGeoProcFactory::Create(flags, color, viewMatrix, SkMatrix::I());
 }
 
 void GrContext::drawVertices(const GrPaint& paint,
@@ -864,7 +865,7 @@
     GrDrawState drawState;
     GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope
 
-    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -873,7 +874,8 @@
 
     int colorOffset = -1, texOffset = -1;
     SkAutoTUnref<const GrGeometryProcessor> gp(
-            set_vertex_attributes(texCoords, colors, &colorOffset, &texOffset, paint.getColor()));
+            set_vertex_attributes(texCoords, colors, &colorOffset, &texOffset,
+                                  paint.getColor(), viewMatrix));
 
     size_t vertexStride = gp->getVertexStride();
     SkASSERT(vertexStride == sizeof(SkPoint) + (SkToBool(texCoords) ? sizeof(SkPoint) : 0)
@@ -928,7 +930,7 @@
 
     AutoCheckFlush acf(this);
     GrDrawState drawState;
-    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -938,7 +940,7 @@
     const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
 
     GrColor color = paint.getColor();
-    if (!fOvalRenderer->drawRRect(target, &drawState, color, paint.isAntiAlias(), rrect,
+    if (!fOvalRenderer->drawRRect(target, &drawState, color, viewMatrix, paint.isAntiAlias(), rrect,
                                   strokeRec)) {
         SkPath path;
         path.addRRect(rrect);
@@ -959,12 +961,12 @@
 
     AutoCheckFlush acf(this);
     GrDrawState drawState;
-    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
 
     GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target);
 
     GrColor color = paint.getColor();
-    if (!fOvalRenderer->drawDRRect(target, &drawState, color, paint.isAntiAlias(), outer, inner)) {
+    if (!fOvalRenderer->drawDRRect(target, &drawState, color, viewMatrix, paint.isAntiAlias(), outer, inner)) {
         SkPath path;
         path.addRRect(inner);
         path.addRRect(outer);
@@ -995,7 +997,7 @@
 
     AutoCheckFlush acf(this);
     GrDrawState drawState;
-    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -1005,7 +1007,8 @@
     const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
 
     GrColor color = paint.getColor();
-    if (!fOvalRenderer->drawOval(target, &drawState, color, paint.isAntiAlias(), oval, strokeRec)) {
+    if (!fOvalRenderer->drawOval(target, &drawState, color, viewMatrix, paint.isAntiAlias(), oval,
+                                 strokeRec)) {
         SkPath path;
         path.addOval(oval);
         this->internalDrawPath(target, &drawState, viewMatrix, color, paint.isAntiAlias(), path,
@@ -1017,6 +1020,7 @@
 static bool is_nested_rects(GrDrawTarget* target,
                             GrDrawState* drawState,
                             GrColor color,
+                            const SkMatrix& viewMatrix,
                             const SkPath& path,
                             const SkStrokeRec& stroke,
                             SkRect rects[2]) {
@@ -1028,7 +1032,7 @@
 
     // TODO: this restriction could be lifted if we were willing to apply
     // the matrix to all the points individually rather than just to the rect
-    if (!drawState->getViewMatrix().preservesAxisAlignment()) {
+    if (!viewMatrix.preservesAxisAlignment()) {
         return false;
     }
 
@@ -1088,13 +1092,13 @@
         if (path.isLine(pts)) {
             AutoCheckFlush acf(this);
             GrDrawState drawState;
-            GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+            GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
             if (NULL == target) {
                 return;
             }
 
-            if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, color, pts, paint,
-                                              strokeInfo)) {
+            if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, color, viewMatrix, pts,
+                                              paint, strokeInfo)) {
                 return;
             }
         }
@@ -1120,7 +1124,7 @@
     // OK.
     AutoCheckFlush acf(this);
     GrDrawState drawState;
-    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &viewMatrix, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -1135,17 +1139,8 @@
         // Concave AA paths are expensive - try to avoid them for special cases
         SkRect rects[2];
 
-        if (is_nested_rects(target, &drawState, color, path, strokeRec, rects)) {
-            SkMatrix origViewMatrix = drawState.getViewMatrix();
-
-            SkMatrix invert;
-            if (!drawState.getViewMatrix().invert(&invert)) {
-                return;
-            }
-            GrDrawState::AutoViewMatrixRestore avmr(&drawState);
-
-            fAARectRenderer->fillAANestedRects(target, &drawState, color, invert, rects,
-                                               origViewMatrix);
+        if (is_nested_rects(target, &drawState, color, viewMatrix, path, strokeRec, rects)) {
+            fAARectRenderer->fillAANestedRects(target, &drawState, color, viewMatrix,rects);
             return;
         }
     }
@@ -1153,9 +1148,9 @@
     SkRect ovalRect;
     bool isOval = path.isOval(&ovalRect);
 
-    if (!isOval || path.isInverseFillType()
-        || !fOvalRenderer->drawOval(target, &drawState, color, paint.isAntiAlias(), ovalRect,
-                                    strokeRec)) {
+    if (!isOval || path.isInverseFillType() ||
+        !fOvalRenderer->drawOval(target, &drawState, color, viewMatrix, paint.isAntiAlias(),
+                                 ovalRect, strokeRec)) {
         this->internalDrawPath(target, &drawState, viewMatrix, color, paint.isAntiAlias(), path,
                                strokeInfo);
     }
@@ -1191,7 +1186,8 @@
     SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec());
 
     // Try a 1st time without stroking the path and without allowing the SW renderer
-    GrPathRenderer* pr = this->getPathRenderer(target, drawState, *pathPtr, *stroke, false, type);
+    GrPathRenderer* pr = this->getPathRenderer(target, drawState, viewMatrix, *pathPtr, *stroke,
+                                               false, type);
 
     if (NULL == pr) {
         if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, NULL)) {
@@ -1206,7 +1202,7 @@
         }
 
         // This time, allow SW renderer
-        pr = this->getPathRenderer(target, drawState, *pathPtr, *stroke, true, type);
+        pr = this->getPathRenderer(target, drawState, viewMatrix, *pathPtr, *stroke, true, type);
     }
 
     if (NULL == pr) {
@@ -1216,7 +1212,7 @@
         return;
     }
 
-    pr->drawPath(target, drawState, color, *pathPtr, *stroke, useCoverageAA);
+    pr->drawPath(target, drawState, color, viewMatrix, *pathPtr, *stroke, useCoverageAA);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1351,14 +1347,14 @@
     // drawing a rect to the render target.
     // The bracket ensures we pop the stack if we wind up flushing below.
     {
-        GrDrawTarget* drawTarget = this->prepareToDraw(NULL, NULL, NULL, NULL);
+        GrDrawTarget* drawTarget = this->prepareToDraw(NULL, NULL, NULL);
         GrDrawTarget::AutoGeometryPush agp(drawTarget);
 
-        GrDrawState drawState(matrix);
+        GrDrawState drawState;
         drawState.addColorProcessor(fp);
         drawState.setRenderTarget(renderTarget);
-        drawTarget->drawSimpleRect(&drawState, GrColor_WHITE,SkRect::MakeWH(SkIntToScalar(width),
-                                                                            SkIntToScalar(height)));
+        drawTarget->drawSimpleRect(&drawState, GrColor_WHITE, matrix,
+                                   SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)));
     }
 
     if (kFlushWrites_PixelOp & pixelOpsFlags) {
@@ -1479,7 +1475,7 @@
 
                     drawState.setRenderTarget(tempTexture->asRenderTarget());
                     SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
-                    fDrawBuffer->drawSimpleRect(&drawState, GrColor_WHITE, rect);
+                    fDrawBuffer->drawSimpleRect(&drawState, GrColor_WHITE, SkMatrix::I(), rect);
                     // we want to read back from the scratch's origin
                     left = 0;
                     top = 0;
@@ -1532,7 +1528,7 @@
     SkASSERT(renderTarget);
     ASSERT_OWNED_RESOURCE(renderTarget);
     AutoCheckFlush acf(this);
-    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL, &acf);
+    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, &acf);
     if (NULL == target) {
         return;
     }
@@ -1550,7 +1546,7 @@
     // Since we're going to the draw target and not GPU, no need to check kNoFlush
     // here.
 
-    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL, NULL);
+    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL);
     if (NULL == target) {
         return;
     }
@@ -1569,7 +1565,6 @@
 
 GrDrawTarget* GrContext::prepareToDraw(GrDrawState* ds,
                                        const GrPaint* paint,
-                                       const SkMatrix* viewMatrix,
                                        const AutoCheckFlush* acf) {
     if (NULL == fGpu) {
         return NULL;
@@ -1577,10 +1572,9 @@
 
     ASSERT_OWNED_RESOURCE(fRenderTarget.get());
     if (ds) {
-        SkASSERT(viewMatrix);
         if (paint) {
             SkASSERT(acf);
-            ds->setFromPaint(*paint, *viewMatrix, fRenderTarget.get());
+            ds->setFromPaint(*paint, fRenderTarget.get());
 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK
             if ((paint->hasMask()) &&
                 !fDrawState->canUseFracCoveragePrimProc(paint.getColor(), fGpu->caps())) {
@@ -1588,7 +1582,7 @@
             }
 #endif
         } else {
-            ds->reset(*viewMatrix);
+            ds->reset();
             ds->setRenderTarget(fRenderTarget.get());
         }
         ds->setState(GrDrawState::kClip_StateBit, fClip && !fClip->fClipStack->isWideOpen());
@@ -1605,6 +1599,7 @@
  */
 GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
                                            const GrDrawState* drawState,
+                                           const SkMatrix& viewMatrix,
                                            const SkPath& path,
                                            const SkStrokeRec& stroke,
                                            bool allowSW,
@@ -1617,6 +1612,7 @@
 
     GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target,
                                                              drawState,
+                                                             viewMatrix,
                                                              path,
                                                              stroke,
                                                              drawType,
@@ -1674,7 +1670,7 @@
 }
 
 GrDrawTarget* GrContext::getTextTarget() {
-    return this->prepareToDraw(NULL, NULL, NULL, NULL);
+    return this->prepareToDraw(NULL, NULL, NULL);
 }
 
 const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index 7f557b5..2c5117b 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -21,10 +21,18 @@
 
 class DefaultGeoProc : public GrGeometryProcessor {
 public:
-    static GrGeometryProcessor* Create(GrColor color, uint8_t coverage, uint32_t gpTypeFlags,
-                                       bool opaqueVertexColors, const SkMatrix& localMatrix) {
-        return SkNEW_ARGS(DefaultGeoProc, (color, coverage, gpTypeFlags, opaqueVertexColors,
-                                           localMatrix));
+    static GrGeometryProcessor* Create(uint32_t gpTypeFlags,
+                                       GrColor color,
+                                       const SkMatrix& viewMatrix,
+                                       const SkMatrix& localMatrix,
+                                       bool opaqueVertexColors,
+                                       uint8_t coverage) {
+        return SkNEW_ARGS(DefaultGeoProc, (gpTypeFlags,
+                                           color,
+                                           viewMatrix,
+                                           localMatrix,
+                                           opaqueVertexColors,
+                                           coverage));
     }
 
     virtual const char* name() const SK_OVERRIDE { return "DefaultGeometryProcessor"; }
@@ -166,9 +174,13 @@
     }
 
 private:
-    DefaultGeoProc(GrColor color, uint8_t coverage, uint32_t gpTypeFlags, bool opaqueVertexColors,
-                   const SkMatrix& localMatrix)
-        : INHERITED(color, opaqueVertexColors, localMatrix)
+    DefaultGeoProc(uint32_t gpTypeFlags,
+                   GrColor color,
+                   const SkMatrix& viewMatrix,
+                   const SkMatrix& localMatrix,
+                   bool opaqueVertexColors,
+                   uint8_t coverage)
+        : INHERITED(color, viewMatrix, localMatrix, opaqueVertexColors)
         , fInPosition(NULL)
         , fInColor(NULL)
         , fInLocalCoords(NULL)
@@ -246,15 +258,24 @@
         flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
     }
 
-    return DefaultGeoProc::Create(GrRandomColor(random), GrRandomCoverage(random),
-                                  flags, random->nextBool(),
-                                  GrProcessorUnitTest::TestMatrix(random));
+    return DefaultGeoProc::Create(flags,
+                                  GrRandomColor(random),
+                                  GrProcessorUnitTest::TestMatrix(random),
+                                  GrProcessorUnitTest::TestMatrix(random),
+                                  random->nextBool(),
+                                  GrRandomCoverage(random));
 }
 
-const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(GrColor color,
-                                                           uint32_t gpTypeFlags,
+const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags,
+                                                           GrColor color,
+                                                           const SkMatrix& viewMatrix,
+                                                           const SkMatrix& localMatrix,
                                                            bool opaqueVertexColors,
-                                                           uint8_t coverage,
-                                                           const SkMatrix& localMatrix) {
-    return DefaultGeoProc::Create(color, coverage, gpTypeFlags, opaqueVertexColors, localMatrix);
+                                                           uint8_t coverage) {
+    return DefaultGeoProc::Create(gpTypeFlags,
+                                  color,
+                                  viewMatrix,
+                                  localMatrix,
+                                  opaqueVertexColors,
+                                  coverage);
 }
diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h
index b7db74d..91c6f5d 100644
--- a/src/gpu/GrDefaultGeoProcFactory.h
+++ b/src/gpu/GrDefaultGeoProcFactory.h
@@ -80,17 +80,13 @@
      *
      * You must unref the return from Create.
      */
-    static const GrGeometryProcessor* Create(GrColor,
-                                             uint32_t gpTypeFlags = 0,
+    // TODO clean this up
+    static const GrGeometryProcessor* Create(uint32_t gpTypeFlags,
+                                             GrColor,
+                                             const SkMatrix& viewMatrix = SkMatrix::I(),
+                                             const SkMatrix& localMatrix = SkMatrix::I(),
                                              bool opaqueVertexColors = false,
-                                             uint8_t coverage = 0xff,
-                                             const SkMatrix& localMatrix = SkMatrix::I());
-
-    static const GrGeometryProcessor* Create(GrColor color,
-                                             uint32_t gpTypeFlags,
-                                             const SkMatrix& localMatrix) {
-        return Create(color, gpTypeFlags, false, 0xff, localMatrix);
-    }
+                                             uint8_t coverage = 0xff);
 
     static size_t DefaultVertexStride() { return sizeof(PositionAttr); }
 };
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index e7c678d..79e9f15 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -329,16 +329,15 @@
 bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
                                              GrDrawState* drawState,
                                              GrColor color,
+                                             const SkMatrix& viewMatrix,
                                              const SkPath& path,
                                              const SkStrokeRec& origStroke,
                                              bool stencilOnly) {
-    SkMatrix viewM = drawState->getViewMatrix();
     SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
 
     SkScalar hairlineCoverage;
     uint8_t newCoverage = 0xff;
-    if (IsStrokeHairlineOrEquivalent(*stroke, drawState->getViewMatrix(),
-                                     &hairlineCoverage)) {
+    if (IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, &hairlineCoverage)) {
         newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
 
         if (!stroke->isHairlineStyle()) {
@@ -347,7 +346,7 @@
     }
 
     SkScalar tol = SK_Scalar1;
-    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
+    tol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds());
 
     int vertexCnt;
     int indexCnt;
@@ -462,7 +461,7 @@
     }
 
     SkRect devBounds;
-    GetPathDevBounds(path, drawState->getRenderTarget(), viewM, &devBounds);
+    GetPathDevBounds(path, drawState->getRenderTarget(), viewMatrix, &devBounds);
 
     for (int p = 0; p < passCount; ++p) {
         drawState->setDrawFace(drawFace[p]);
@@ -474,8 +473,6 @@
             // Reset the XP Factory on drawState
             drawState->setXPFactory(backupXPFactory);
             SkRect bounds;
-            GrDrawState::AutoViewMatrixRestore avmr;
-            const SkMatrix& viewMatrix = drawState->getViewMatrix();
             SkMatrix localMatrix = SkMatrix::I();
             if (reverse) {
                 SkASSERT(drawState->getRenderTarget());
@@ -483,28 +480,30 @@
                 bounds = devBounds;
                 SkMatrix vmi;
                 // mapRect through persp matrix may not be correct
-                if (!drawState->getViewMatrix().hasPerspective() &&
-                    drawState->getViewInverse(&vmi)) {
+                if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
                     vmi.mapRect(&bounds);
                 } else {
                     if (!viewMatrix.invert(&localMatrix)) {
                         return false;
                     }
-                    avmr.setIdentity(drawState);
                 }
             } else {
                 bounds = path.getBounds();
             }
             GrDrawTarget::AutoGeometryPush agp(target);
-            target->drawRect(drawState, color, bounds, NULL, &localMatrix);
+            const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() :
+                                                                               viewMatrix;
+            target->drawRect(drawState, color, viewM, bounds, NULL, &localMatrix);
         } else {
             if (passCount > 1) {
                 drawState->setDisableColorXPFactory();
             }
             GrDrawState::AutoRestoreEffects are(drawState);
             SkAutoTUnref<const GrGeometryProcessor> gp(
-                    GrDefaultGeoProcFactory::Create(color,
-                                                    GrDefaultGeoProcFactory::kPosition_GPType,
+                    GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
+                                                    color,
+                                                    viewMatrix,
+                                                    SkMatrix::I(),
                                                     false,
                                                     newCoverage));
             if (indexCnt) {
@@ -526,25 +525,27 @@
 
 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target,
                                         const GrDrawState* drawState,
+                                        const SkMatrix& viewMatrix,
                                         const SkPath& path,
                                         const SkStrokeRec& stroke,
                                         bool antiAlias) const {
     // this class can draw any path with any fill but doesn't do any anti-aliasing.
 
     return !antiAlias && !(SkPath::kConic_SegmentMask & path.getSegmentMasks()) &&
-        (stroke.isFillStyle() ||
-         IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(), NULL));
+        (stroke.isFillStyle() || IsStrokeHairlineOrEquivalent(stroke, viewMatrix, NULL));
 }
 
 bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target,
                                        GrDrawState* drawState,
                                        GrColor color,
+                                       const SkMatrix& viewMatrix,
                                        const SkPath& path,
                                        const SkStrokeRec& stroke,
                                        bool antiAlias) {
     return this->internalDrawPath(target,
                                   drawState,
                                   color,
+                                  viewMatrix,
                                   path,
                                   stroke,
                                   false);
@@ -552,9 +553,10 @@
 
 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target,
                                           GrDrawState* drawState,
+                                          const SkMatrix& viewMatrix,
                                           const SkPath& path,
                                           const SkStrokeRec& stroke) {
     SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType());
     SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType());
-    this->internalDrawPath(target, drawState, GrColor_WHITE, path, stroke, true);
+    this->internalDrawPath(target, drawState, GrColor_WHITE, viewMatrix, path, stroke, true);
 }
diff --git a/src/gpu/GrDefaultPathRenderer.h b/src/gpu/GrDefaultPathRenderer.h
index aa481e5..e1eea88 100644
--- a/src/gpu/GrDefaultPathRenderer.h
+++ b/src/gpu/GrDefaultPathRenderer.h
@@ -21,6 +21,7 @@
 
     virtual bool canDrawPath(const GrDrawTarget*,
                              const GrDrawState*,
+                             const SkMatrix& viewMatrix,
                              const SkPath&,
                              const SkStrokeRec&,
                              bool antiAlias) const SK_OVERRIDE;
@@ -35,18 +36,21 @@
     virtual bool onDrawPath(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
+                            const SkMatrix& viewMatrix,
                             const SkPath&,
                             const SkStrokeRec&,
                             bool antiAlias) SK_OVERRIDE;
 
     virtual void onStencilPath(GrDrawTarget*,
                                GrDrawState*,
+                               const SkMatrix& viewMatrix,
                                const SkPath&,
                                const SkStrokeRec&) SK_OVERRIDE;
 
     bool internalDrawPath(GrDrawTarget*,
                           GrDrawState*,
                           GrColor,
+                          const SkMatrix& viewMatrix,
                           const SkPath&,
                           const SkStrokeRec&,
                           bool stencilOnly);
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 8d993fa..69dcaa7 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -407,11 +407,13 @@
     // see if we need to create a new effect
     if (textureUniqueID != fEffectTextureUniqueID ||
         filteredColor != fEffectColor ||
-        flags != fEffectFlags) {
+        flags != fEffectFlags ||
+        !fCachedGeometryProcessor->viewMatrix().cheapEqualTo(fViewMatrix)) {
         GrColor color = fPaint.getColor();
         if (fUseLCDText) {
             GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
             fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(color,
+                                                                                   fViewMatrix,
                                                                                    fCurrTexture,
                                                                                    params,
                                                                                    fGammaTexture,
@@ -425,6 +427,7 @@
             U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.gamma(),
                                                                 filteredColor);
             fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(color,
+                                                                                fViewMatrix,
                                                                                 fCurrTexture,
                                                                                 params,
                                                                                 fGammaTexture,
@@ -434,6 +437,7 @@
                                                                                 opaque));
 #else
             fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color,
+                                                                                       fViewMatrix,
                                                                                        fCurrTexture,
                                                                                        params,
                                                                                        flags,
@@ -633,7 +637,7 @@
 
     if (fCurrVertex > 0) {
         GrDrawState drawState;
-        drawState.setFromPaint(fPaint, fViewMatrix, fContext->getRenderTarget());
+        drawState.setFromPaint(fPaint, fContext->getRenderTarget());
 
         // setup our sampler state for our text texture/atlas
         SkASSERT(SkIsAlign4(fCurrVertex));
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 6694100..36042e1 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -18,7 +18,6 @@
     if (this->getRenderTarget() != that.getRenderTarget() ||
         this->fColorStages.count() != that.fColorStages.count() ||
         this->fCoverageStages.count() != that.fCoverageStages.count() ||
-        !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
         this->fFlagBits != that.fFlagBits ||
         this->fStencilSettings != that.fStencilSettings ||
         this->fDrawFace != that.fDrawFace) {
@@ -47,7 +46,6 @@
 
 GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
     fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
-    fViewMatrix = that.fViewMatrix;
     fFlagBits = that.fFlagBits;
     fStencilSettings = that.fStencilSettings;
     fDrawFace = that.fDrawFace;
@@ -70,7 +68,7 @@
     return *this;
 }
 
-void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
+void GrDrawState::onReset() {
     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
     fRenderTarget.reset(NULL);
 
@@ -78,11 +76,6 @@
     fColorStages.reset();
     fCoverageStages.reset();
 
-    if (NULL == initialViewMatrix) {
-        fViewMatrix.reset();
-    } else {
-        fViewMatrix = *initialViewMatrix;
-    }
     fFlagBits = 0x0;
     fStencilSettings.setDisabled();
     fDrawFace = kBoth_DrawFace;
@@ -97,7 +90,7 @@
     fCoveragePrimProc = NULL;
 }
 
-void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
+void GrDrawState::setFromPaint(const GrPaint& paint, GrRenderTarget* rt) {
     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
 
     fColorStages.reset();
@@ -115,8 +108,6 @@
 
     this->setRenderTarget(rt);
 
-    fViewMatrix = vm;
-
     // These have no equivalent in GrPaint, set them to defaults
     fDrawFace = kBoth_DrawFace;
     fStencilSettings.setDisabled();
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index b552e77..ce29e6c 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -35,11 +35,6 @@
         this->reset();
     }
 
-    GrDrawState(const SkMatrix& initialViewMatrix) {
-        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
-        this->reset(initialViewMatrix);
-    }
-
     /**
      * Copies another draw state.
      **/
@@ -53,9 +48,7 @@
     /**
      * Resets to the default state. GrProcessors will be removed from all stages.
      */
-    void reset() { this->onReset(NULL); }
-
-    void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
+    void reset() { this->onReset(); }
 
     /**
      * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
@@ -63,7 +56,7 @@
      * equivalents are set to default values with the exception of vertex attribute state which
      * is unmodified by this function and clipping which will be enabled.
      */
-    void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
+    void setFromPaint(const GrPaint&, GrRenderTarget*);
 
     /// @}
 
@@ -268,73 +261,6 @@
 
     /// @}
 
-    ///////////////////////////////////////////////////////////////////////////
-    /// @name View Matrix
-    ////
-
-    /**
-     * Retrieves the current view matrix
-     * @return the current view matrix.
-     */
-    const SkMatrix& getViewMatrix() const { return fViewMatrix; }
-
-    /**
-     *  Retrieves the inverse of the current view matrix.
-     *
-     *  If the current view matrix is invertible, return true, and if matrix
-     *  is non-null, copy the inverse into it. If the current view matrix is
-     *  non-invertible, return false and ignore the matrix parameter.
-     *
-     * @param matrix if not null, will receive a copy of the current inverse.
-     */
-    bool getViewInverse(SkMatrix* matrix) const {
-        SkMatrix inverse;
-        if (fViewMatrix.invert(&inverse)) {
-            if (matrix) {
-                *matrix = inverse;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Sets the viewmatrix to identity and restores it in the destructor.
-     * TODO remove vm off of drawstate
-     */
-    class AutoViewMatrixRestore : public ::SkNoncopyable {
-    public:
-        AutoViewMatrixRestore() {
-            fDrawState = NULL;
-        }
-
-        AutoViewMatrixRestore(GrDrawState* ds) {
-            SkASSERT(ds);
-            fDrawState = ds;
-            fViewMatrix = fDrawState->fViewMatrix;
-            fDrawState->fViewMatrix = SkMatrix::I();
-        }
-
-        void setIdentity(GrDrawState* ds) {
-            SkASSERT(ds);
-            fDrawState = ds;
-            fViewMatrix = fDrawState->fViewMatrix;
-            fDrawState->fViewMatrix = SkMatrix::I();
-        }
-
-        ~AutoViewMatrixRestore() {
-            if (fDrawState) {
-                fDrawState->fViewMatrix = fViewMatrix;
-            }
-        }
-
-    private:
-        GrDrawState*                                           fDrawState;
-        SkMatrix                                               fViewMatrix;
-    };
-
 
     /// @}
 
@@ -514,7 +440,7 @@
      */
     void calcCoverageInvariantOutput(GrColor) const;
 
-    void onReset(const SkMatrix* initialViewMatrix);
+    void onReset();
 
     // Some of the auto restore objects assume that no effects are removed during their lifetime.
     // This is used to assert that this condition holds.
@@ -523,7 +449,6 @@
     typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
 
     SkAutoTUnref<GrRenderTarget>            fRenderTarget;
-    SkMatrix                                fViewMatrix;
     uint32_t                                fFlagBits;
     GrStencilSettings                       fStencilSettings;
     DrawFace                                fDrawFace;
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 1b641d8..5faf00f 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -449,7 +449,7 @@
         GrScissorState scissorState;
         GrDrawState::AutoRestoreEffects are;
         GrDrawState::AutoRestoreStencil ars;
-        if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
+        if (!this->setupClip(ds, &are, &ars, &scissorState, devBounds)) {
             return;
         }
 
@@ -492,7 +492,7 @@
         GrScissorState scissorState;
         GrDrawState::AutoRestoreEffects are;
         GrDrawState::AutoRestoreStencil ars;
-        if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
+        if (!this->setupClip(ds, &are, &ars, &scissorState, devBounds)) {
             return;
         }
 
@@ -571,7 +571,7 @@
     GrScissorState scissorState;
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
-    if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) {
+    if (!this->setupClip(ds, &are, &ars, &scissorState, NULL)) {
         return;
     }
 
@@ -594,14 +594,13 @@
     SkASSERT(ds);
 
     SkRect devBounds = path->getBounds();
-    SkMatrix viewM = ds->getViewMatrix();
-    viewM.mapRect(&devBounds);
+    pathProc->viewMatrix().mapRect(&devBounds);
 
     // Setup clip
     GrScissorState scissorState;
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
-    if (!this->setupClip(&devBounds, &are, &ars, ds, &scissorState)) {
+    if (!this->setupClip(ds, &are, &ars, &scissorState, &devBounds)) {
        return;
     }
 
@@ -641,7 +640,7 @@
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
 
-    if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) {
+    if (!this->setupClip(ds, &are, &ars, &scissorState, NULL)) {
         return;
     }
 
@@ -682,7 +681,7 @@
         GrDrawState drawState;
         drawState.setRenderTarget(renderTarget);
 
-        this->drawSimpleRect(&drawState, color, *rect);
+        this->drawSimpleRect(&drawState, color, SkMatrix::I(), *rect);
     } else {       
         this->onClear(rect, color, canIgnoreRect, renderTarget);
     }
@@ -751,7 +750,7 @@
     GrScissorState scissorState;
     GrDrawState::AutoRestoreEffects are;
     GrDrawState::AutoRestoreStencil ars;
-    if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
+    if (!this->setupClip(ds, &are, &ars, &scissorState, devBounds)) {
         return;
     }
 
@@ -769,7 +768,7 @@
 
     // TODO: We should continue with incorrect blending.
     GrDeviceCoordTexture dstCopy;
-    if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy,devBounds)) {
+    if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy, devBounds)) {
         return;
     }
 
@@ -951,7 +950,7 @@
                                         clippedDstPoint.fY,
                                         clippedSrcRect.width(),
                                         clippedSrcRect.height());
-    this->drawSimpleRect(&drawState, GrColor_WHITE, dstRect);
+    this->drawSimpleRect(&drawState, GrColor_WHITE, SkMatrix::I(), dstRect);
     return true;
 }
 
@@ -1212,11 +1211,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-bool GrClipTarget::setupClip(const SkRect* devBounds,
+bool GrClipTarget::setupClip(GrDrawState* ds,
                              GrDrawState::AutoRestoreEffects* are,
                              GrDrawState::AutoRestoreStencil* ars,
-                             GrDrawState* ds,
-                             GrScissorState* scissorState) {
+                             GrScissorState* scissorState,
+                             const SkRect* devBounds) {
     return fClipMaskManager.setupClipping(ds,
                                           are,
                                           ars,
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index d2c20a1..b1d1492 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -310,22 +310,24 @@
      */
     void drawRect(GrDrawState* ds,
                   GrColor color,
+                  const SkMatrix& viewMatrix,
                   const SkRect& rect,
                   const SkRect* localRect,
                   const SkMatrix* localMatrix) {
         AutoGeometryPush agp(this);
-        this->onDrawRect(ds, color, rect, localRect, localMatrix);
+        this->onDrawRect(ds, color, viewMatrix, rect, localRect, localMatrix);
     }
 
     /**
      * Helper for drawRect when the caller doesn't need separate local rects or matrices.
      */
-    void drawSimpleRect(GrDrawState* ds, GrColor color, const SkRect& rect) {
-        this->drawRect(ds, color, rect, NULL, NULL);
+    void drawSimpleRect(GrDrawState* ds, GrColor color, const SkMatrix& viewM, const SkRect& rect) {
+        this->drawRect(ds, color, viewM, rect, NULL, NULL);
     }
-    void drawSimpleRect(GrDrawState* ds, GrColor color, const SkIRect& irect) {
+    void drawSimpleRect(GrDrawState* ds, GrColor color, const SkMatrix& viewM,
+                        const SkIRect& irect) {
         SkRect rect = SkRect::Make(irect);
-        this->drawRect(ds, color, rect, NULL, NULL);
+        this->drawRect(ds, color, viewM, rect, NULL, NULL);
     }
 
     /**
@@ -707,6 +709,7 @@
     // TODO copy in order drawbuffer onDrawRect to here
     virtual void onDrawRect(GrDrawState*,
                             GrColor color,
+                            const SkMatrix& viewMatrix,
                             const SkRect& rect,
                             const SkRect* localRect,
                             const SkMatrix* localMatrix) = 0;
@@ -786,11 +789,11 @@
                                            const GrStencilBuffer*,
                                            GrStencilSettings*);
     virtual GrClipMaskManager* clipMaskManager() = 0;
-    virtual bool setupClip(const SkRect* devBounds,
+    virtual bool setupClip(GrDrawState*,
                            GrDrawState::AutoRestoreEffects* are,
                            GrDrawState::AutoRestoreStencil* ars,
-                           GrDrawState*,
-                           GrScissorState* scissorState) = 0;
+                           GrScissorState* scissorState,
+                           const SkRect* devBounds) = 0;
 
     enum {
         kPreallocGeoSrcStateStackCnt = 4,
@@ -846,11 +849,11 @@
 private:
     GrClipMaskManager* clipMaskManager() SK_OVERRIDE { return &fClipMaskManager; }
 
-    virtual bool setupClip(const SkRect* devBounds,
+    virtual bool setupClip(GrDrawState*,
                            GrDrawState::AutoRestoreEffects* are,
                            GrDrawState::AutoRestoreStencil* ars,
-                           GrDrawState*,
-                           GrScissorState* scissorState) SK_OVERRIDE;
+                           GrScissorState* scissorState,
+                           const SkRect* devBounds) SK_OVERRIDE;
 
     typedef GrDrawTarget INHERITED;
 };
diff --git a/src/gpu/GrGeometryProcessor.cpp b/src/gpu/GrGeometryProcessor.cpp
index d47f687..01ea85a 100644
--- a/src/gpu/GrGeometryProcessor.cpp
+++ b/src/gpu/GrGeometryProcessor.cpp
@@ -119,8 +119,10 @@
     typedef GrGLGeometryProcessor INHERITED;
 };
 
-GrPathProcessor::GrPathProcessor(GrColor color, const SkMatrix& localMatrix)
-    : INHERITED(localMatrix)
+GrPathProcessor::GrPathProcessor(GrColor color,
+                                 const SkMatrix& viewMatrix,
+                                 const SkMatrix& localMatrix)
+    : INHERITED(viewMatrix, localMatrix)
     , fColor(color) {
     this->initClassID<GrPathProcessor>();
 }
@@ -155,6 +157,10 @@
         return false;
     }
 
+    if (!this->viewMatrix().cheapEqualTo(that.viewMatrix())) {
+        return false;
+    }
+
     const PathBatchTracker& mine = m.cast<PathBatchTracker>();
     const PathBatchTracker& theirs = t.cast<PathBatchTracker>();
     return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h
index fb2300e..d88f3e6 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -92,6 +92,7 @@
 public:
     // TODO let the PrimProc itself set this in its setData call, this should really live on the
     // bundle of primitive data
+    const SkMatrix& viewMatrix() const { return fViewMatrix; }
     const SkMatrix& localMatrix() const { return fLocalMatrix; }
 
     /*
@@ -135,7 +136,9 @@
     virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const = 0;
 
 protected:
-    GrPrimitiveProcessor(const SkMatrix& localMatrix) : fLocalMatrix(localMatrix) {}
+    GrPrimitiveProcessor(const SkMatrix& viewMatrix, const SkMatrix& localMatrix)
+        : fViewMatrix(viewMatrix)
+        , fLocalMatrix(localMatrix) {}
 
     /*
      * CanCombineOutput will return true if two draws are 'batchable' from a color perspective.
@@ -168,6 +171,7 @@
     }
 
 private:
+    SkMatrix fViewMatrix;
     SkMatrix fLocalMatrix;
 
     typedef GrProcessor INHERITED;
@@ -185,9 +189,10 @@
     // TODO the Hint can be handled in a much more clean way when we have deferred geometry or
     // atleast bundles
     GrGeometryProcessor(GrColor color,
-                        bool opaqueVertexColors = false,
-                        const SkMatrix& localMatrix = SkMatrix::I())
-        : INHERITED(localMatrix)
+                        const SkMatrix& viewMatrix = SkMatrix::I(),
+                        const SkMatrix& localMatrix = SkMatrix::I(),
+                        bool opaqueVertexColors = false)
+        : INHERITED(viewMatrix, localMatrix)
         , fVertexStride(0)
         , fColor(color)
         , fOpaqueVertexColors(opaqueVertexColors)
@@ -237,6 +242,11 @@
             return false;
         }
 
+        // TODO let the GPs decide this
+        if (!this->viewMatrix().cheapEqualTo(that.viewMatrix())) {
+            return false;
+        }
+
         // TODO remove the hint
         const GrGeometryProcessor& other = that.cast<GrGeometryProcessor>();
         if (fHasVertexColor && fOpaqueVertexColors != other.fOpaqueVertexColors) {
@@ -342,8 +352,10 @@
  */
 class GrPathProcessor : public GrPrimitiveProcessor {
 public:
-    static GrPathProcessor* Create(GrColor color, const SkMatrix& localMatrix = SkMatrix::I()) {
-        return SkNEW_ARGS(GrPathProcessor, (color, localMatrix));
+    static GrPathProcessor* Create(GrColor color,
+                                   const SkMatrix& viewMatrix = SkMatrix::I(),
+                                   const SkMatrix& localMatrix = SkMatrix::I()) {
+        return SkNEW_ARGS(GrPathProcessor, (color, viewMatrix, localMatrix));
     }
     
     void initBatchTracker(GrBatchTracker*, const InitBT&) const SK_OVERRIDE;
@@ -366,7 +378,7 @@
     virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
 
 private:
-    GrPathProcessor(GrColor color, const SkMatrix& localMatrix);
+    GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
     GrColor fColor;
 
     typedef GrPrimitiveProcessor INHERITED;
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 1f49035..e6e7b80 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -69,10 +69,11 @@
                      GrDefaultGeoProcFactory::kColor_GPType;
     flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
     if (localMatrix) {
-        return GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color), 0xff,
-                                               *localMatrix);
+        return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix,
+                                               GrColorIsOpaque(color));
     } else {
-        return GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color));
+        return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I(),
+                                               GrColorIsOpaque(color));
     }
 }
 
@@ -115,20 +116,20 @@
 
 void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
                                      GrColor color,
+                                     const SkMatrix& viewMatrix,
                                      const SkRect& rect,
                                      const SkRect* localRect,
                                      const SkMatrix* localMatrix) {
     GrDrawState::AutoRestoreEffects are(ds);
 
     // Go to device coords to allow batching across matrix changes
-    SkMatrix matrix = ds->getViewMatrix();
     SkMatrix invert = SkMatrix::I();
 
     // if we have a local rect, then we apply the localMatrix directly to the localRect to generate
     // vertex local coords
     bool hasExplicitLocalCoords = SkToBool(localRect);
     if (!hasExplicitLocalCoords) {
-        if (!matrix.isIdentity() && !matrix.invert(&invert)) {
+        if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
             SkDebugf("Could not invert\n");
             return;
         }
@@ -151,15 +152,14 @@
         return;
     }
 
+    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
+    viewMatrix.mapPointsWithStride(geo.positions(), vstride, 4);
+
     // When the caller has provided an explicit source rect for a stage then we don't want to
     // modify that stage's matrix. Otherwise if the effect is generating its source rect from
-    // the vertex positions then we have to account for the view matrix change.
-    GrDrawState::AutoViewMatrixRestore avmr(ds);
-
-    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
-    matrix.mapPointsWithStride(geo.positions(), vstride, 4);
-
+    // the vertex positions then we have to account for the view matrix
     SkRect devBounds;
+
     // since we already computed the dev verts, set the bounds hint. This will help us avoid
     // unnecessary clipping in our onDraw().
     get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
@@ -275,7 +275,7 @@
                                                (path, ds.getRenderTarget()));
     sp->fScissor = scissorState;
     sp->fUseHWAA = ds.isHWAntialias();
-    sp->fViewMatrix = ds.getViewMatrix();
+    sp->fViewMatrix = pathProc->viewMatrix();
     sp->fStencil = stencilSettings;
     this->recordTraceMarkersIfNecessary();
 }
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index ec73e4c..5a616e1 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -202,6 +202,7 @@
                 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
     void onDrawRect(GrDrawState*,
                     GrColor,
+                    const SkMatrix& viewMatrix,
                     const SkRect& rect,
                     const SkRect* localRect,
                     const SkMatrix* localMatrix) SK_OVERRIDE;
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index eea0222..80f2278 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -73,7 +73,7 @@
     fRenderTarget.reset(drawState.fRenderTarget.get());
     SkASSERT(fRenderTarget);
     fScissorState = scissorState;
-    fViewMatrix = drawState.getViewMatrix();
+    fViewMatrix = fPrimitiveProcessor->viewMatrix();
     fStencilSettings = drawState.getStencil();
     fDrawFace = drawState.getDrawFace();
     // TODO move this out of optDrawState
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index ac088b9..06b2e11 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -175,7 +175,7 @@
 
 private:
     CircleEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix)
-        : INHERITED(color, false, localMatrix) {
+        : INHERITED(color, SkMatrix::I(), localMatrix) {
         this->initClassID<CircleEdgeEffect>();
         fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
         fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge",
@@ -213,7 +213,8 @@
                                                   GrContext* context,
                                                   const GrDrawTargetCaps&,
                                                   GrTexture* textures[]) {
-    return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool(),
+    return CircleEdgeEffect::Create(GrRandomColor(random),
+                                    random->nextBool(),
                                     GrProcessorUnitTest::TestMatrix(random));
 }
 
@@ -363,7 +364,7 @@
 
 private:
     EllipseEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix)
-        : INHERITED(color, false, localMatrix) {
+        : INHERITED(color, SkMatrix::I(), localMatrix) {
         this->initClassID<EllipseEdgeEffect>();
         fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
         fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset",
@@ -404,7 +405,8 @@
                                                    GrContext* context,
                                                    const GrDrawTargetCaps&,
                                                    GrTexture* textures[]) {
-    return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool(),
+    return EllipseEdgeEffect::Create(GrRandomColor(random),
+                                     random->nextBool(),
                                      GrProcessorUnitTest::TestMatrix(random));
 }
 
@@ -423,8 +425,8 @@
 public:
     enum Mode { kStroke = 0, kHairline, kFill };
 
-    static GrGeometryProcessor* Create(GrColor color, Mode mode) {
-        return SkNEW_ARGS(DIEllipseEdgeEffect, (color, mode));
+    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, Mode mode) {
+        return SkNEW_ARGS(DIEllipseEdgeEffect, (color, viewMatrix, mode));
     }
 
     virtual ~DIEllipseEdgeEffect() {}
@@ -571,7 +573,8 @@
     }
 
 private:
-    DIEllipseEdgeEffect(GrColor color, Mode mode) : INHERITED(color) {
+    DIEllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, Mode mode)
+        : INHERITED(color, viewMatrix) {
         this->initClassID<DIEllipseEdgeEffect>();
         fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
         fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffsets0",
@@ -612,7 +615,9 @@
                                                      GrContext* context,
                                                      const GrDrawTargetCaps&,
                                                      GrTexture* textures[]) {
-    return DIEllipseEdgeEffect::Create(GrRandomColor(random), (Mode)(random->nextRangeU(0,2)));
+    return DIEllipseEdgeEffect::Create(GrRandomColor(random),
+                                       GrProcessorUnitTest::TestMatrix(random),
+                                       (Mode)(random->nextRangeU(0,2)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -625,6 +630,7 @@
 bool GrOvalRenderer::drawOval(GrDrawTarget* target,
                               GrDrawState* drawState,
                               GrColor color,
+                              const SkMatrix& viewMatrix,
                               bool useAA,
                               const SkRect& oval,
                               const SkStrokeRec& stroke)
@@ -637,18 +643,16 @@
         return false;
     }
 
-    const SkMatrix& vm = drawState->getViewMatrix();
-
     // we can draw circles
-    if (SkScalarNearlyEqual(oval.width(), oval.height())
-        && circle_stays_circle(vm)) {
-        this->drawCircle(target, drawState, color, useCoverageAA, oval, stroke);
+    if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(viewMatrix)) {
+        this->drawCircle(target, drawState, color, viewMatrix, useCoverageAA, oval, stroke);
     // if we have shader derivative support, render as device-independent
     } else if (target->caps()->shaderDerivativeSupport()) {
-        return this->drawDIEllipse(target, drawState, color, useCoverageAA, oval, stroke);
+        return this->drawDIEllipse(target, drawState, color, viewMatrix, useCoverageAA, oval,
+                                   stroke);
     // otherwise axis-aligned ellipses only
-    } else if (vm.rectStaysRect()) {
-        return this->drawEllipse(target, drawState, color, useCoverageAA, oval, stroke);
+    } else if (viewMatrix.rectStaysRect()) {
+        return this->drawEllipse(target, drawState, color, viewMatrix, useCoverageAA, oval, stroke);
     } else {
         return false;
     }
@@ -661,23 +665,20 @@
 void GrOvalRenderer::drawCircle(GrDrawTarget* target,
                                 GrDrawState* drawState,
                                 GrColor color,
+                                const SkMatrix& viewMatrix,
                                 bool useCoverageAA,
                                 const SkRect& circle,
-                                const SkStrokeRec& stroke)
-{
-    const SkMatrix& vm = drawState->getViewMatrix();
+                                const SkStrokeRec& stroke) {
     SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY());
-    vm.mapPoints(&center, 1);
-    SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width()));
-    SkScalar strokeWidth = vm.mapRadius(stroke.getWidth());
+    viewMatrix.mapPoints(&center, 1);
+    SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width()));
+    SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth());
 
     SkMatrix invert;
-    if (!vm.invert(&invert)) {
+    if (!viewMatrix.invert(&invert)) {
         return;
     }
 
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
-
     SkStrokeRec::Style style = stroke.getStyle();
     bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
                         SkStrokeRec::kHairline_Style == style;
@@ -700,7 +701,7 @@
     }
 
     SkAutoTUnref<GrGeometryProcessor> gp(
-            CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0, invert));
+            CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0,invert));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(),  0);
     SkASSERT(gp->getVertexStride() == sizeof(CircleVertex));
@@ -757,34 +758,35 @@
 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
                                  GrDrawState* drawState,
                                  GrColor color,
+                                 const SkMatrix& viewMatrix,
                                  bool useCoverageAA,
                                  const SkRect& ellipse,
-                                 const SkStrokeRec& stroke)
-{
+                                 const SkStrokeRec& stroke) {
 #ifdef SK_DEBUG
     {
         // we should have checked for this previously
-        bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect();
+        bool isAxisAlignedEllipse = viewMatrix.rectStaysRect();
         SkASSERT(useCoverageAA && isAxisAlignedEllipse);
     }
 #endif
 
     // do any matrix crunching before we reset the draw state for device coords
-    const SkMatrix& vm = drawState->getViewMatrix();
     SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
-    vm.mapPoints(&center, 1);
+    viewMatrix.mapPoints(&center, 1);
     SkScalar ellipseXRadius = SkScalarHalf(ellipse.width());
     SkScalar ellipseYRadius = SkScalarHalf(ellipse.height());
-    SkScalar xRadius = SkScalarAbs(vm[SkMatrix::kMScaleX]*ellipseXRadius +
-                                   vm[SkMatrix::kMSkewY]*ellipseYRadius);
-    SkScalar yRadius = SkScalarAbs(vm[SkMatrix::kMSkewX]*ellipseXRadius +
-                                   vm[SkMatrix::kMScaleY]*ellipseYRadius);
+    SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*ellipseXRadius +
+                                   viewMatrix[SkMatrix::kMSkewY]*ellipseYRadius);
+    SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*ellipseXRadius +
+                                   viewMatrix[SkMatrix::kMScaleY]*ellipseYRadius);
 
     // do (potentially) anisotropic mapping of stroke
     SkVector scaledStroke;
     SkScalar strokeWidth = stroke.getWidth();
-    scaledStroke.fX = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMScaleX] + vm[SkMatrix::kMSkewY]));
-    scaledStroke.fY = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMSkewX] + vm[SkMatrix::kMScaleY]));
+    scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] +
+                                               viewMatrix[SkMatrix::kMSkewY]));
+    scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] +
+                                               viewMatrix[SkMatrix::kMScaleY]));
 
     SkStrokeRec::Style style = stroke.getStyle();
     bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
@@ -823,14 +825,13 @@
     }
 
     SkMatrix invert;
-    if (!vm.invert(&invert)) {
+    if (!viewMatrix.invert(&invert)) {
         return false;
     }
 
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
-
     SkAutoTUnref<GrGeometryProcessor> gp(
-            EllipseEdgeEffect::Create(color, isStrokeOnly && innerXRadius > 0 && innerYRadius > 0,
+            EllipseEdgeEffect::Create(color,
+                                      isStrokeOnly && innerXRadius > 0 && innerYRadius > 0,
                                       invert));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(),  0);
@@ -891,12 +892,10 @@
 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
                                    GrDrawState* drawState,
                                    GrColor color,
+                                   const SkMatrix& viewMatrix,
                                    bool useCoverageAA,
                                    const SkRect& ellipse,
-                                   const SkStrokeRec& stroke)
-{
-    const SkMatrix& vm = drawState->getViewMatrix();
-
+                                   const SkStrokeRec& stroke) {
     SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
     SkScalar xRadius = SkScalarHalf(ellipse.width());
     SkScalar yRadius = SkScalarHalf(ellipse.height());
@@ -946,7 +945,7 @@
     SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
     SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
 
-    SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(color, mode));
+    SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(color, viewMatrix, mode));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(),  0);
     SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex));
@@ -958,10 +957,10 @@
     DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
 
     // This expands the outer rect so that after CTM we end up with a half-pixel border
-    SkScalar a = vm[SkMatrix::kMScaleX];
-    SkScalar b = vm[SkMatrix::kMSkewX];
-    SkScalar c = vm[SkMatrix::kMSkewY];
-    SkScalar d = vm[SkMatrix::kMScaleY];
+    SkScalar a = viewMatrix[SkMatrix::kMScaleX];
+    SkScalar b = viewMatrix[SkMatrix::kMSkewX];
+    SkScalar c = viewMatrix[SkMatrix::kMSkewY];
+    SkScalar d = viewMatrix[SkMatrix::kMScaleY];
     SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
     SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
     // This adjusts the "radius" to include the half-pixel border
@@ -1046,6 +1045,7 @@
 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
                                 GrDrawState* drawState,
                                 GrColor color,
+                                const SkMatrix& viewMatrix,
                                 bool useAA,
                                 const SkRRect& origOuter,
                                 const SkRRect& origInner) {
@@ -1055,8 +1055,8 @@
     GrDrawState::AutoRestoreEffects are;
     if (!origInner.isEmpty()) {
         SkTCopyOnFirstWrite<SkRRect> inner(origInner);
-        if (!drawState->getViewMatrix().isIdentity()) {
-            if (!origInner.transform(drawState->getViewMatrix(), inner.writable())) {
+        if (!viewMatrix.isIdentity()) {
+            if (!origInner.transform(viewMatrix, inner.writable())) {
                 return false;
             }
         }
@@ -1073,14 +1073,14 @@
     }
 
     SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle);
-    if (this->drawRRect(target, drawState, color, useAA, origOuter, fillRec)) {
+    if (this->drawRRect(target, drawState, color, viewMatrix, useAA, origOuter, fillRec)) {
         return true;
     }
 
     SkASSERT(!origOuter.isEmpty());
     SkTCopyOnFirstWrite<SkRRect> outer(origOuter);
-    if (!drawState->getViewMatrix().isIdentity()) {
-        if (!origOuter.transform(drawState->getViewMatrix(), outer.writable())) {
+    if (!viewMatrix.isIdentity()) {
+        if (!origOuter.transform(viewMatrix, outer.writable())) {
             return false;
         }
     }
@@ -1095,28 +1095,29 @@
     }
 
     SkMatrix invert;
-    if (!drawState->getViewMatrix().invert(&invert)) {
+    if (!viewMatrix.invert(&invert)) {
         return false;
     }
 
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
     drawState->addCoverageProcessor(effect)->unref();
     SkRect bounds = outer->getBounds();
     if (applyAA) {
         bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
     }
-    target->drawRect(drawState, color, bounds, NULL, &invert);
+    target->drawRect(drawState, color, SkMatrix::I(), bounds, NULL, &invert);
     return true;
 }
 
 bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
                                GrDrawState* drawState,
                                GrColor color,
+                               const SkMatrix& viewMatrix,
                                bool useAA,
                                const SkRRect& rrect,
                                const SkStrokeRec& stroke) {
     if (rrect.isOval()) {
-        return this->drawOval(target, drawState, color, useAA, rrect.getBounds(), stroke);
+        return this->drawOval(target, drawState, color, viewMatrix, useAA, rrect.getBounds(),
+                              stroke);
     }
 
     bool useCoverageAA = useAA &&
@@ -1128,22 +1129,20 @@
         return false;
     }
 
-    const SkMatrix& vm = drawState->getViewMatrix();
-
-    if (!vm.rectStaysRect() || !rrect.isSimple()) {
+    if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) {
         return false;
     }
 
     // do any matrix crunching before we reset the draw state for device coords
     const SkRect& rrectBounds = rrect.getBounds();
     SkRect bounds;
-    vm.mapRect(&bounds, rrectBounds);
+    viewMatrix.mapRect(&bounds, rrectBounds);
 
     SkVector radii = rrect.getSimpleRadii();
-    SkScalar xRadius = SkScalarAbs(vm[SkMatrix::kMScaleX]*radii.fX +
-                                   vm[SkMatrix::kMSkewY]*radii.fY);
-    SkScalar yRadius = SkScalarAbs(vm[SkMatrix::kMSkewX]*radii.fX +
-                                   vm[SkMatrix::kMScaleY]*radii.fY);
+    SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX +
+                                   viewMatrix[SkMatrix::kMSkewY]*radii.fY);
+    SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX +
+                                   viewMatrix[SkMatrix::kMScaleY]*radii.fY);
 
     SkStrokeRec::Style style = stroke.getStyle();
 
@@ -1159,10 +1158,10 @@
         if (SkStrokeRec::kHairline_Style == style) {
             scaledStroke.set(1, 1);
         } else {
-            scaledStroke.fX = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMScaleX] +
-                                                       vm[SkMatrix::kMSkewY]));
-            scaledStroke.fY = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMSkewX] +
-                                                       vm[SkMatrix::kMScaleY]));
+            scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] +
+                                                       viewMatrix[SkMatrix::kMSkewY]));
+            scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] +
+                                                       viewMatrix[SkMatrix::kMScaleY]));
         }
 
         // if half of strokewidth is greater than radius, we don't handle that right now
@@ -1182,13 +1181,11 @@
 
     // reset to device coordinates
     SkMatrix invert;
-    if (!vm.invert(&invert)) {
+    if (!viewMatrix.invert(&invert)) {
         SkDebugf("Failed to invert\n");
         return false;
     }
 
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
-
     GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly);
     if (NULL == indexBuffer) {
         SkDebugf("Failed to create index buffer!\n");
@@ -1216,7 +1213,8 @@
 
         isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
 
-        SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color, isStrokeOnly,
+        SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color,
+                                                                          isStrokeOnly,
                                                                           invert));
 
         GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(),  0);
@@ -1316,7 +1314,8 @@
 
         isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
 
-        SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color, isStrokeOnly,
+        SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color,
+                                                                           isStrokeOnly,
                                                                            invert));
 
         GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(),  0);
diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h
index c67815c..16c1248 100644
--- a/src/gpu/GrOvalRenderer.h
+++ b/src/gpu/GrOvalRenderer.h
@@ -37,18 +37,21 @@
     bool drawOval(GrDrawTarget*,
                   GrDrawState*,
                   GrColor,
+                  const SkMatrix& viewMatrix,
                   bool useAA,
                   const SkRect& oval,
                   const SkStrokeRec& stroke);
     bool drawRRect(GrDrawTarget*,
                    GrDrawState*,
                    GrColor,
+                   const SkMatrix& viewMatrix,
                    bool useAA,
                    const SkRRect& rrect,
                    const SkStrokeRec& stroke);
     bool drawDRRect(GrDrawTarget* target,
                     GrDrawState*,
                     GrColor,
+                    const SkMatrix& viewMatrix,
                     bool useAA,
                     const SkRRect& outer,
                     const SkRRect& inner);
@@ -57,18 +60,21 @@
     bool drawEllipse(GrDrawTarget* target,
                      GrDrawState*,
                      GrColor,
+                     const SkMatrix& viewMatrix,
                      bool useCoverageAA,
                      const SkRect& ellipse,
                      const SkStrokeRec& stroke);
     bool drawDIEllipse(GrDrawTarget* target,
                        GrDrawState*,
                        GrColor,
+                       const SkMatrix& viewMatrix,
                        bool useCoverageAA,
                        const SkRect& ellipse,
                        const SkStrokeRec& stroke);
     void drawCircle(GrDrawTarget* target,
                     GrDrawState*,
                     GrColor,
+                    const SkMatrix& viewMatrix,
                     bool useCoverageAA,
                     const SkRect& circle,
                     const SkStrokeRec& stroke);
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 4d38aa0..6f087b4 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -94,15 +94,18 @@
      * caller to fallback to another path renderer This function is called when searching for a path
      * renderer capable of rendering a path.
      *
+     * @param target     The target that the path will be rendered to
+     * @param drawState  The drawState
+     * @param viewMatrix The viewMatrix
      * @param path       The path to draw
      * @param stroke     The stroke information (width, join, cap)
-     * @param target     The target that the path will be rendered to
      * @param antiAlias  True if anti-aliasing is required.
      *
      * @return  true if the path can be drawn by this object, false otherwise.
      */
     virtual bool canDrawPath(const GrDrawTarget* target,
                              const GrDrawState* drawState,
+                             const SkMatrix& viewMatrix,
                              const SkPath& path,
                              const SkStrokeRec& rec,
                              bool antiAlias) const = 0;
@@ -110,23 +113,26 @@
      * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
      * the subclass must respect the stencil settings of the target's draw state.
      *
+     * @param target                The target that the path will be rendered to
+     * @param drawState             The drawState
+     * @param viewMatrix            The viewMatrix
      * @param path                  the path to draw.
      * @param stroke                the stroke information (width, join, cap)
-     * @param target                target that the path will be rendered to
      * @param antiAlias             true if anti-aliasing is required.
      */
     bool drawPath(GrDrawTarget* target,
                   GrDrawState* ds,
                   GrColor color,
+                  const SkMatrix& viewMatrix,
                   const SkPath& path,
                   const SkStrokeRec& stroke,
                   bool antiAlias) {
         SkASSERT(!path.isEmpty());
-        SkASSERT(this->canDrawPath(target, ds, path, stroke, antiAlias));
+        SkASSERT(this->canDrawPath(target, ds, viewMatrix, path, stroke, antiAlias));
         SkASSERT(ds->getStencil().isDisabled() ||
                  kNoRestriction_StencilSupport == this->getStencilSupport(target, ds, path,
                                                                           stroke));
-        return this->onDrawPath(target, ds, color, path, stroke, antiAlias);
+        return this->onDrawPath(target, ds, color, viewMatrix, path, stroke, antiAlias);
     }
 
     /**
@@ -139,11 +145,12 @@
      */
     void stencilPath(GrDrawTarget* target,
                      GrDrawState* ds,
+                     const SkMatrix& viewMatrix,
                      const SkPath& path,
                      const SkStrokeRec& stroke) {
         SkASSERT(!path.isEmpty());
         SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(target, ds, path, stroke));
-        this->onStencilPath(target, ds, path, stroke);
+        this->onStencilPath(target, ds, viewMatrix, path, stroke);
     }
 
     // Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
@@ -177,6 +184,7 @@
     virtual bool onDrawPath(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
+                            const SkMatrix& viewMatrix,
                             const SkPath&,
                             const SkStrokeRec&,
                             bool antiAlias) = 0;
@@ -187,6 +195,7 @@
      */
     virtual void onStencilPath(GrDrawTarget* target,
                                GrDrawState* drawState,
+                               const SkMatrix& viewMatrix,
                                const SkPath& path,
                                const SkStrokeRec& stroke) {
         GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil,
@@ -198,7 +207,7 @@
                                      0xffff);
         drawState->setStencil(kIncrementStencil);
         drawState->setDisableColorXPFactory();
-        this->drawPath(target, drawState, GrColor_WHITE,  path, stroke, false);
+        this->drawPath(target, drawState, GrColor_WHITE, viewMatrix, path, stroke, false);
     }
 
     // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index 5c3f1c9..0ba9364 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -33,6 +33,7 @@
 
 GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrDrawTarget* target,
                                                      const GrDrawState* drawState,
+                                                     const SkMatrix& viewMatrix,
                                                      const SkPath& path,
                                                      const SkStrokeRec& stroke,
                                                      DrawType drawType,
@@ -59,7 +60,7 @@
 
 
     for (int i = 0; i < fChain.count(); ++i) {
-        if (fChain[i]->canDrawPath(target, drawState, path, stroke, antiAlias)) {
+        if (fChain[i]->canDrawPath(target, drawState, viewMatrix, path, stroke, antiAlias)) {
             if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
                 GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(target,
                                                                                       drawState,
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index b64d37b..21c9352 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -326,7 +326,7 @@
                                                  const SkStrokeRec& stroke,
                                                  const SkIRect& resultBounds,
                                                  bool antiAlias,
-                                                 SkMatrix* matrix) {
+                                                 const SkMatrix* matrix) {
     GrSWMaskHelper helper(context);
 
     if (!helper.init(resultBounds, matrix)) {
@@ -349,12 +349,12 @@
                                               GrDrawTarget* target,
                                               GrDrawState* drawState,
                                               GrColor color,
+                                              const SkMatrix& viewMatrix,
                                               const SkIRect& rect) {
     SkMatrix invert;
-    if (!drawState->getViewMatrix().invert(&invert)) {
+    if (!viewMatrix.invert(&invert)) {
         return;
     }
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
     GrDrawState::AutoRestoreEffects are(drawState);
 
     SkRect dstRect = SkRect::MakeLTRB(SK_Scalar1 * rect.fLeft,
@@ -375,5 +375,5 @@
                                                        GrTextureParams::kNone_FilterMode,
                                                        kDevice_GrCoordSet))->unref();
 
-    target->drawRect(drawState, color, dstRect, NULL, &invert);
+    target->drawRect(drawState, color, SkMatrix::I(), dstRect, NULL, &invert);
 }
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index 229b0e5..71dec63 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -78,7 +78,7 @@
                                             const SkStrokeRec& stroke,
                                             const SkIRect& resultBounds,
                                             bool antiAlias,
-                                            SkMatrix* matrix);
+                                            const SkMatrix* matrix);
 
     // This utility routine is used to add a path's mask to some other draw.
     // The ClipMaskManager uses it to accumulate clip masks while the
@@ -94,6 +94,7 @@
                                          GrDrawTarget* target,
                                          GrDrawState* drawState,
                                          GrColor,
+                                         const SkMatrix& viewMatrix,
                                          const SkIRect& rect);
 
 private:
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 8eb66d8..90b35f7 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 bool GrSoftwarePathRenderer::canDrawPath(const GrDrawTarget*,
                                          const GrDrawState*,
+                                         const SkMatrix& viewMatrix,
                                          const SkPath&,
                                          const SkStrokeRec&,
                                          bool antiAlias) const {
@@ -79,36 +80,34 @@
 void draw_around_inv_path(GrDrawTarget* target,
                           GrDrawState* drawState,
                           GrColor color,
+                          const SkMatrix& viewMatrix,
                           const SkIRect& devClipBounds,
                           const SkIRect& devPathBounds) {
-    const SkMatrix& matrix = drawState->getViewMatrix();
     SkMatrix invert;
-    if (!matrix.invert(&invert)) {
+    if (!viewMatrix.invert(&invert)) {
         return;
     }
 
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
-
     SkRect rect;
     if (devClipBounds.fTop < devPathBounds.fTop) {
         rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fTop);
-        target->drawRect(drawState, color, rect, NULL, &invert);
+        target->drawRect(drawState, color, SkMatrix::I(), rect, NULL, &invert);
     }
     if (devClipBounds.fLeft < devPathBounds.fLeft) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
                   devPathBounds.fLeft, devPathBounds.fBottom);
-        target->drawRect(drawState, color, rect, NULL, &invert);
+        target->drawRect(drawState, color, SkMatrix::I(), rect, NULL, &invert);
     }
     if (devClipBounds.fRight > devPathBounds.fRight) {
         rect.iset(devPathBounds.fRight, devPathBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fBottom);
-        target->drawRect(drawState, color, rect, NULL, &invert);
+        target->drawRect(drawState, color, SkMatrix::I(), rect, NULL, &invert);
     }
     if (devClipBounds.fBottom > devPathBounds.fBottom) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
                   devClipBounds.fRight, devClipBounds.fBottom);
-        target->drawRect(drawState, color, rect, NULL, &invert);
+        target->drawRect(drawState, color, SkMatrix::I(), rect, NULL, &invert);
     }
 }
 
@@ -119,6 +118,7 @@
 bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
                                         GrDrawState* drawState,
                                         GrColor color,
+                                        const SkMatrix& viewMatrix,
                                         const SkPath& path,
                                         const SkStrokeRec& stroke,
                                         bool antiAlias) {
@@ -127,13 +127,11 @@
         return false;
     }
 
-    SkMatrix vm = drawState->getViewMatrix();
-
     SkIRect devPathBounds, devClipBounds;
-    if (!get_path_and_clip_bounds(target, drawState, path, vm,
+    if (!get_path_and_clip_bounds(target, drawState, path, viewMatrix,
                                   &devPathBounds, &devClipBounds)) {
         if (path.isInverseFillType()) {
-            draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds);
+            draw_around_inv_path(target, drawState, color, viewMatrix, devClipBounds,devPathBounds);
         }
         return true;
     }
@@ -141,16 +139,17 @@
     SkAutoTUnref<GrTexture> texture(
             GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke,
                                                   devPathBounds,
-                                                  antiAlias, &vm));
+                                                  antiAlias, &viewMatrix));
     if (NULL == texture) {
         return false;
     }
 
     GrDrawState copy = *drawState;
-    GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, &copy, color, devPathBounds);
+    GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, &copy, color, viewMatrix,
+                                             devPathBounds);
 
     if (path.isInverseFillType()) {
-        draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds);
+        draw_around_inv_path(target, drawState, color, viewMatrix, devClipBounds, devPathBounds);
     }
 
     return true;
diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h
index 226cb35..43d5e55 100644
--- a/src/gpu/GrSoftwarePathRenderer.h
+++ b/src/gpu/GrSoftwarePathRenderer.h
@@ -25,6 +25,7 @@
 
     virtual bool canDrawPath(const GrDrawTarget*,
                              const GrDrawState*,
+                             const SkMatrix& viewMatrix,
                              const SkPath&,
                              const SkStrokeRec&,
                              bool antiAlias) const SK_OVERRIDE;
@@ -37,6 +38,7 @@
     virtual bool onDrawPath(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
+                            const SkMatrix& viewMatrix,
                             const SkPath&,
                             const SkStrokeRec&,
                             bool antiAlias) SK_OVERRIDE;
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp
index 2feea01..207194d 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp
@@ -52,6 +52,7 @@
 
 bool GrStencilAndCoverPathRenderer::canDrawPath(const GrDrawTarget* target,
                                                 const GrDrawState* drawState,
+                                                const SkMatrix& viewMatrix,
                                                 const SkPath& path,
                                                 const SkStrokeRec& stroke,
                                                 bool antiAlias) const {
@@ -82,10 +83,11 @@
 
 void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target,
                                                   GrDrawState* drawState,
+                                                  const SkMatrix& viewMatrix,
                                                   const SkPath& path,
                                                   const SkStrokeRec& stroke) {
     SkASSERT(!path.isInverseFillType());
-    SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE));
+    SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, viewMatrix));
     SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
     target->stencilPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
 }
@@ -93,6 +95,7 @@
 bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
                                                GrDrawState* drawState,
                                                GrColor color,
+                                               const SkMatrix& viewMatrix,
                                                const SkPath& path,
                                                const SkStrokeRec& stroke,
                                                bool antiAlias) {
@@ -118,29 +121,28 @@
         drawState->setStencil(kInvertedStencilPass);
 
         // fake inverse with a stencil and cover
-        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE));
+        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, viewMatrix));
         target->stencilPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
 
         SkMatrix invert = SkMatrix::I();
-        GrDrawState::AutoViewMatrixRestore avmr;
         SkRect bounds = SkRect::MakeLTRB(0, 0,
                                          SkIntToScalar(drawState->getRenderTarget()->width()),
                                          SkIntToScalar(drawState->getRenderTarget()->height()));
         SkMatrix vmi;
         // mapRect through persp matrix may not be correct
-        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
+        if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
             vmi.mapRect(&bounds);
             // theoretically could set bloat = 0, instead leave it because of matrix inversion
             // precision.
-            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
+            SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf;
             bounds.outset(bloat, bloat);
         } else {
-            if (!drawState->getViewMatrix().invert(&invert)) {
+            if (!viewMatrix.invert(&invert)) {
                 return false;
             }
-            avmr.setIdentity(drawState);
         }
-        target->drawRect(drawState, color, bounds, NULL, &invert);
+        const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix;
+        target->drawRect(drawState, color, viewM, bounds, NULL, &invert);
     } else {
         GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
             kZero_StencilOp,
@@ -151,7 +153,7 @@
             0xffff);
 
         drawState->setStencil(kStencilPass);
-        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(color));
+        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(color, viewMatrix));
         target->drawPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
     }
 
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.h b/src/gpu/GrStencilAndCoverPathRenderer.h
index be04c4a..1ea26c4 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.h
+++ b/src/gpu/GrStencilAndCoverPathRenderer.h
@@ -27,6 +27,7 @@
 
     virtual bool canDrawPath(const GrDrawTarget*,
                              const GrDrawState*,
+                             const SkMatrix& viewMatrix,
                              const SkPath&,
                              const SkStrokeRec&,
                              bool antiAlias) const SK_OVERRIDE;
@@ -40,12 +41,14 @@
     virtual bool onDrawPath(GrDrawTarget*,
                             GrDrawState*,
                             GrColor,
+                            const SkMatrix& viewMatrix,
                             const SkPath&,
                             const SkStrokeRec&,
                             bool antiAlias) SK_OVERRIDE;
 
     virtual void onStencilPath(GrDrawTarget*,
                                GrDrawState*,
+                               const SkMatrix& viewMatrix,
                                const SkPath&,
                                const SkStrokeRec&) SK_OVERRIDE;
 
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index b5ab523..59995d0 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -347,7 +347,7 @@
 
     fStateRestore.set(&fDrawState);
 
-    fDrawState.setFromPaint(fPaint, fViewMatrix, fContext->getRenderTarget());
+    fDrawState.setFromPaint(fPaint, fContext->getRenderTarget());
 
     GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
                                  kZero_StencilOp,
@@ -406,7 +406,9 @@
 
 void GrStencilAndCoverTextContext::flush() {
     if (fQueuedGlyphCount > 0) {
-        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor(), fLocalMatrix));
+        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor(),
+                                                                 fViewMatrix,
+                                                                 fLocalMatrix));
         fDrawTarget->drawPaths(&fDrawState, pp, fGlyphs,
                                fGlyphIndices, GrPathRange::kU16_PathIndexType,
                                get_xy_scalar_array(fGlyphPositions),
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index c90067d..4ab088c 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -183,9 +183,11 @@
     return SkNEW_ARGS(GrGLConicEffect, (*this, bt));
 }
 
-GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType,
-                             const SkMatrix& localMatrix)
-    : INHERITED(color, false, localMatrix), fCoverageScale(coverage), fEdgeType(edgeType) {
+GrConicEffect::GrConicEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
+                             GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix)
+    : INHERITED(color, viewMatrix, localMatrix)
+    , fCoverageScale(coverage)
+    , fEdgeType(edgeType) {
     this->initClassID<GrConicEffect>();
     fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
     fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
@@ -228,7 +230,8 @@
     do {
         GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
                                                     random->nextULessThan(kGrProcessorEdgeTypeCnt));
-        gp = GrConicEffect::Create(GrRandomColor(random), edgeType, caps,
+        gp = GrConicEffect::Create(GrRandomColor(random), GrProcessorUnitTest::TestMatrix(random),
+                                   edgeType, caps,
                                    GrProcessorUnitTest::TestMatrix(random));
     } while (NULL == gp);
     return gp;
@@ -395,9 +398,11 @@
     return SkNEW_ARGS(GrGLQuadEffect, (*this, bt));
 }
 
-GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType,
-                           const SkMatrix& localMatrix)
-    : INHERITED(color, false, localMatrix), fCoverageScale(coverage), fEdgeType(edgeType) {
+GrQuadEffect::GrQuadEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
+                           GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix)
+    : INHERITED(color, viewMatrix, localMatrix)
+    , fCoverageScale(coverage)
+    , fEdgeType(edgeType) {
     this->initClassID<GrQuadEffect>();
     fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
     fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
@@ -440,7 +445,9 @@
     do {
         GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
                 random->nextULessThan(kGrProcessorEdgeTypeCnt));
-        gp = GrQuadEffect::Create(GrRandomColor(random), edgeType, caps,
+        gp = GrQuadEffect::Create(GrRandomColor(random),
+                                  GrProcessorUnitTest::TestMatrix(random),
+                                  edgeType, caps,
                                   GrProcessorUnitTest::TestMatrix(random));
     } while (NULL == gp);
     return gp;
@@ -629,8 +636,9 @@
     return SkNEW_ARGS(GrGLCubicEffect, (*this, bt));
 }
 
-GrCubicEffect::GrCubicEffect(GrColor color, GrPrimitiveEdgeType edgeType)
-    : INHERITED(color), fEdgeType(edgeType) {
+GrCubicEffect::GrCubicEffect(GrColor color, const SkMatrix& viewMatrix,
+                             GrPrimitiveEdgeType edgeType)
+    : INHERITED(color, viewMatrix), fEdgeType(edgeType) {
     this->initClassID<GrCubicEffect>();
     fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
     fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
@@ -671,7 +679,8 @@
     do {
         GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
                                                     random->nextULessThan(kGrProcessorEdgeTypeCnt));
-        gp = GrCubicEffect::Create(GrRandomColor(random), edgeType, caps);
+        gp = GrCubicEffect::Create(GrRandomColor(random),
+                                   GrProcessorUnitTest::TestMatrix(random), edgeType, caps);
     } while (NULL == gp);
     return gp;
 }
diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h
index b985fec..1bd93b6 100644
--- a/src/gpu/effects/GrBezierEffect.h
+++ b/src/gpu/effects/GrBezierEffect.h
@@ -59,6 +59,7 @@
 class GrConicEffect : public GrGeometryProcessor {
 public:
     static GrGeometryProcessor* Create(GrColor color,
+                                       const SkMatrix& viewMatrix,
                                        const GrPrimitiveEdgeType edgeType,
                                        const GrDrawTargetCaps& caps,
                                        const SkMatrix& localMatrix,
@@ -68,17 +69,19 @@
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
-                return SkNEW_ARGS(GrConicEffect, (color, coverage, kFillAA_GrProcessorEdgeType,
+                return SkNEW_ARGS(GrConicEffect, (color, viewMatrix, coverage,
+                                                  kFillAA_GrProcessorEdgeType,
                                                   localMatrix));
             case kHairlineAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
-                return SkNEW_ARGS(GrConicEffect, (color, coverage,
+                return SkNEW_ARGS(GrConicEffect, (color, viewMatrix, coverage,
                                                   kHairlineAA_GrProcessorEdgeType,
                                                   localMatrix));
             case kFillBW_GrProcessorEdgeType:
-                return SkNEW_ARGS(GrConicEffect, (color, coverage, kFillBW_GrProcessorEdgeType,
+                return SkNEW_ARGS(GrConicEffect, (color, viewMatrix, coverage,
+                                                  kFillBW_GrProcessorEdgeType,
                                                   localMatrix));
             default:
                 return NULL;
@@ -107,7 +110,8 @@
                         const GrBatchTracker&) const SK_OVERRIDE;
 
 private:
-    GrConicEffect(GrColor, uint8_t coverage, GrPrimitiveEdgeType, const SkMatrix& localMatrix);
+    GrConicEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrPrimitiveEdgeType,
+                  const SkMatrix& localMatrix);
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
@@ -139,6 +143,7 @@
 class GrQuadEffect : public GrGeometryProcessor {
 public:
     static GrGeometryProcessor* Create(GrColor color,
+                                       const SkMatrix& viewMatrix,
                                        const GrPrimitiveEdgeType edgeType,
                                        const GrDrawTargetCaps& caps,
                                        const SkMatrix& localMatrix,
@@ -148,16 +153,19 @@
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
-                return SkNEW_ARGS(GrQuadEffect, (color, coverage, kFillAA_GrProcessorEdgeType,
+                return SkNEW_ARGS(GrQuadEffect, (color, viewMatrix, coverage,
+                                                 kFillAA_GrProcessorEdgeType,
                                                  localMatrix));
             case kHairlineAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
-                return SkNEW_ARGS(GrQuadEffect, (color, coverage, kHairlineAA_GrProcessorEdgeType,
+                return SkNEW_ARGS(GrQuadEffect, (color, viewMatrix, coverage,
+                                                 kHairlineAA_GrProcessorEdgeType,
                                                  localMatrix));
             case kFillBW_GrProcessorEdgeType:
-                return SkNEW_ARGS(GrQuadEffect, (color, coverage, kFillBW_GrProcessorEdgeType,
+                return SkNEW_ARGS(GrQuadEffect, (color, viewMatrix, coverage,
+                                                 kFillBW_GrProcessorEdgeType,
                                                  localMatrix));
             default:
                 return NULL;
@@ -186,7 +194,8 @@
                         const GrBatchTracker&) const SK_OVERRIDE;
 
 private:
-    GrQuadEffect(GrColor, uint8_t coverage, GrPrimitiveEdgeType, const SkMatrix& localMatrix);
+    GrQuadEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrPrimitiveEdgeType,
+                 const SkMatrix& localMatrix);
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
@@ -220,6 +229,7 @@
 class GrCubicEffect : public GrGeometryProcessor {
 public:
     static GrGeometryProcessor* Create(GrColor color,
+                                       const SkMatrix& viewMatrix,
                                        const GrPrimitiveEdgeType edgeType,
                                        const GrDrawTargetCaps& caps) {
         switch (edgeType) {
@@ -227,14 +237,16 @@
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
-                return SkNEW_ARGS(GrCubicEffect, (color, kFillAA_GrProcessorEdgeType));
+                return SkNEW_ARGS(GrCubicEffect, (color, viewMatrix, kFillAA_GrProcessorEdgeType));
             case kHairlineAA_GrProcessorEdgeType:
                 if (!caps.shaderDerivativeSupport()) {
                     return NULL;
                 }
-                return SkNEW_ARGS(GrCubicEffect, (color, kHairlineAA_GrProcessorEdgeType));
+                return SkNEW_ARGS(GrCubicEffect, (color, viewMatrix,
+                                                  kHairlineAA_GrProcessorEdgeType));
             case kFillBW_GrProcessorEdgeType:
-                return SkNEW_ARGS(GrCubicEffect, (color, kFillBW_GrProcessorEdgeType));
+                return SkNEW_ARGS(GrCubicEffect, (color, viewMatrix,
+                                                  kFillBW_GrProcessorEdgeType));
             default:
                 return NULL;
         }
@@ -262,7 +274,7 @@
                         const GrBatchTracker&) const SK_OVERRIDE;
 
 private:
-    GrCubicEffect(GrColor, GrPrimitiveEdgeType);
+    GrCubicEffect(GrColor, const SkMatrix& viewMatrix, GrPrimitiveEdgeType);
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 44de98a..936bf32 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -93,7 +93,7 @@
 GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture,
                                          const GrTextureParams& params, bool useColorAttrib,
                                          bool opaqueVertexColors, const SkMatrix& localMatrix)
-    : INHERITED(color, opaqueVertexColors, localMatrix)
+    : INHERITED(color, SkMatrix::I(), localMatrix, opaqueVertexColors)
     , fTextureAccess(texture, params)
     , fInColor(NULL) {
     this->initClassID<GrBitmapTextGeoProc>();
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index 339e44a..4788b3a 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -165,11 +165,9 @@
 }
 
 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState* drawState,
-                                   GrColor color, const SkPoint pts[2], const GrPaint& paint,
-                                   const GrStrokeInfo& strokeInfo) {
-    const SkMatrix& vm = drawState->getViewMatrix();
-
-    if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, vm)) {
+                                   GrColor color, const SkMatrix& viewMatrix, const SkPoint pts[2],
+                                   const GrPaint& paint, const GrStrokeInfo& strokeInfo) {
+    if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, viewMatrix)) {
         return false;
     }
 
@@ -204,7 +202,7 @@
     // Scale corrections of intervals and stroke from view matrix
     SkScalar parallelScale;
     SkScalar perpScale;
-    calc_dash_scaling(&parallelScale, &perpScale, vm, ptsRot);
+    calc_dash_scaling(&parallelScale, &perpScale, viewMatrix, ptsRot);
 
     bool hasCap = SkPaint::kButt_Cap != cap && 0 != srcStrokeWidth;
 
@@ -222,7 +220,7 @@
     SkScalar startAdj = 0;
 
     SkMatrix combinedMatrix = srcRotInv;
-    combinedMatrix.postConcat(vm);
+    combinedMatrix.postConcat(viewMatrix);
 
     bool lineDone = false;
     SkRect startRect;
@@ -328,7 +326,7 @@
         lineDone = true;
 
         SkPoint devicePts[2];
-        vm.mapPoints(devicePts, ptsRot, 2);
+        viewMatrix.mapPoints(devicePts, ptsRot, 2);
         SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]);
         if (hasCap) {
             lineLength += 2.f * halfDevStroke;
@@ -338,13 +336,11 @@
 
     // reset to device coordinates
     SkMatrix invert;
-    if (!vm.invert(&invert)) {
+    if (!viewMatrix.invert(&invert)) {
         SkDebugf("Failed to invert\n");
         return false;
     }
 
-    GrDrawState::AutoViewMatrixRestore avmr(drawState);
-
     SkAutoTUnref<const GrGeometryProcessor> gp;
     bool fullDash = devIntervals[1] > 0.f || useAA;
     if (fullDash) {
@@ -360,7 +356,9 @@
         gp.reset(GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType, invert));
     } else {
         // Set up the vertex data for the line and start/end dashes
-        gp.reset(GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory::kPosition_GPType,
+        gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
+                                                 color,
+                                                 SkMatrix::I(),
                                                  invert));
     }
 
@@ -388,7 +386,7 @@
     // Draw interior part of dashed line
     if (!lineDone) {
         SkPoint devicePts[2];
-        vm.mapPoints(devicePts, ptsRot, 2);
+        viewMatrix.mapPoints(devicePts, ptsRot, 2);
         SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]);
         if (hasCap) {
             lineLength += 2.f * halfDevStroke;
@@ -675,7 +673,7 @@
                                          const DashInfo& info,
                                          SkScalar radius,
                                          const SkMatrix& localMatrix)
-    : INHERITED(color, false, localMatrix), fEdgeType(edgeType) {
+    : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) {
     this->initClassID<DashingCircleEffect>();
     fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
     fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType));
@@ -728,7 +726,8 @@
     info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
     info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]);
 
-    return DashingCircleEffect::Create(GrRandomColor(random), edgeType, info, strokeWidth,
+    return DashingCircleEffect::Create(GrRandomColor(random),
+                                       edgeType, info, strokeWidth,
                                        GrProcessorUnitTest::TestMatrix(random));
 }
 
@@ -969,7 +968,7 @@
                                      const DashInfo& info,
                                      SkScalar strokeWidth,
                                      const SkMatrix& localMatrix)
-    : INHERITED(color, false, localMatrix), fEdgeType(edgeType) {
+    : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) {
     this->initClassID<DashingLineEffect>();
     fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
     fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType));
@@ -1022,7 +1021,8 @@
     info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
     info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fIntervals[1]);
 
-    return DashingLineEffect::Create(GrRandomColor(random), edgeType, info, strokeWidth,
+    return DashingLineEffect::Create(GrRandomColor(random),
+                                     edgeType, info, strokeWidth,
                                      GrProcessorUnitTest::TestMatrix(random));
 }
 
@@ -1036,7 +1036,8 @@
                                              const SkMatrix& localMatrix) {
     switch (cap) {
         case GrDashingEffect::kRound_DashCap:
-            return DashingCircleEffect::Create(color, edgeType, info, SkScalarHalf(strokeWidth),
+            return DashingCircleEffect::Create(color, edgeType, info,
+                                               SkScalarHalf(strokeWidth),
                                                localMatrix);
         case GrDashingEffect::kNonRound_DashCap:
             return DashingLineEffect::Create(color, edgeType, info, strokeWidth, localMatrix);
diff --git a/src/gpu/effects/GrDashingEffect.h b/src/gpu/effects/GrDashingEffect.h
index 61cba7e..651a240 100644
--- a/src/gpu/effects/GrDashingEffect.h
+++ b/src/gpu/effects/GrDashingEffect.h
@@ -24,8 +24,8 @@
 class SkPath;
 
 namespace GrDashingEffect {
-    bool DrawDashLine(GrGpu*, GrDrawTarget*, GrDrawState*, GrColor, const SkPoint pts[2],
-                      const GrPaint& paint, const GrStrokeInfo& strokeInfo);
+    bool DrawDashLine(GrGpu*, GrDrawTarget*, GrDrawState*, GrColor, const SkMatrix& viewMatrix,
+                      const SkPoint pts[2], const GrPaint& paint, const GrStrokeInfo& strokeInfo);
 
     enum DashCap {
         kRound_DashCap,
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index f5510d4..669a504 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -186,6 +186,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
+                                                           const SkMatrix& viewMatrix,
                                                            GrTexture* texture,
                                                            const GrTextureParams& params,
 #ifdef SK_GAMMA_APPLY_TO_A8
@@ -194,7 +195,7 @@
                                                            float luminance,
 #endif
                                                            uint32_t flags, bool opaqueVertexColors)
-    : INHERITED(color, opaqueVertexColors)
+    : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
     , fTextureAccess(texture, params)
 #ifdef SK_GAMMA_APPLY_TO_A8
     , fGammaTextureAccess(gamma, gammaParams)
@@ -289,7 +290,9 @@
                                                             GrTextureParams::kNone_FilterMode);
 #endif
 
-    return GrDistanceFieldTextureEffect::Create(GrRandomColor(random), textures[texIdx], params,
+    return GrDistanceFieldTextureEffect::Create(GrRandomColor(random),
+                                                GrProcessorUnitTest::TestMatrix(random),
+                                                textures[texIdx], params,
 #ifdef SK_GAMMA_APPLY_TO_A8
                                                 textures[texIdx2], params2,
                                                 random->nextF(),
@@ -443,11 +446,12 @@
 
 GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(
         GrColor color,
+        const SkMatrix& viewMatrix,
         GrTexture* texture,
         const GrTextureParams& params,
         uint32_t flags,
         bool opaqueVertexColors)
-    : INHERITED(color, opaqueVertexColors)
+    : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
     , fTextureAccess(texture, params)
     , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
     , fInColor(NULL) {
@@ -525,7 +529,9 @@
     GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode 
                                                          : GrTextureParams::kNone_FilterMode);
 
-    return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random), textures[texIdx],
+    return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random),
+                                                       GrProcessorUnitTest::TestMatrix(random),
+                                                       textures[texIdx],
                                                        params,
         random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool());
 }
@@ -748,12 +754,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
-                                                  GrColor color,
+                                                  GrColor color, const SkMatrix& viewMatrix,
                                                   GrTexture* texture, const GrTextureParams& params,
                                                   GrTexture* gamma, const GrTextureParams& gParams,
                                                   SkColor textColor,
                                                   uint32_t flags)
-    : INHERITED(color)
+    : INHERITED(color, viewMatrix, SkMatrix::I())
     , fTextureAccess(texture, params)
     , fGammaTextureAccess(gamma, gParams)
     , fTextColor(textColor)
@@ -839,7 +845,9 @@
     uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
     flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
     flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
-    return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), textures[texIdx], params,
+    return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random),
+                                                   GrProcessorUnitTest::TestMatrix(random),
+                                                   textures[texIdx], params,
                                                    textures[texIdx2], params2,
                                                    textColor,
                                                    flags);
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h
index 7acd279..1be06df 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -47,16 +47,19 @@
 class GrDistanceFieldTextureEffect : public GrGeometryProcessor {
 public:
 #ifdef SK_GAMMA_APPLY_TO_A8
-    static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
+    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
+                                       const GrTextureParams& params,
                                        GrTexture* gamma, const GrTextureParams& gammaParams,
                                        float lum, uint32_t flags, bool opaqueVertexColors) {
-       return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, gamma, gammaParams, lum,
+       return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, tex, params, gamma,
+                                                        gammaParams, lum,
                                                         flags, opaqueVertexColors));
     }
 #else
-    static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
+    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
+                                       const GrTextureParams& params,
                                        uint32_t flags, bool opaqueVertexColors) {
-        return  SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, flags,
+        return  SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, tex, params, flags,
                                                           opaqueVertexColors));
     }
 #endif
@@ -86,7 +89,8 @@
                         const GrBatchTracker&) const SK_OVERRIDE;
 
 private:
-    GrDistanceFieldTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params,
+    GrDistanceFieldTextureEffect(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
+                                 const GrTextureParams& params,
 #ifdef SK_GAMMA_APPLY_TO_A8
                                  GrTexture* gamma, const GrTextureParams& gammaParams, float lum,
 #endif
@@ -120,10 +124,11 @@
 */
 class GrDistanceFieldNoGammaTextureEffect : public GrGeometryProcessor {
 public:
-    static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
+    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
+                                       const GrTextureParams& params,
                                        uint32_t flags, bool opaqueVertexColors) {
-        return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (color, tex, params, flags,
-                                                                opaqueVertexColors));
+        return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (color, viewMatrix, tex, params,
+                                                                flags, opaqueVertexColors));
     }
 
     virtual ~GrDistanceFieldNoGammaTextureEffect() {}
@@ -148,8 +153,9 @@
                         const GrBatchTracker&) const SK_OVERRIDE;
 
 private:
-    GrDistanceFieldNoGammaTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params,
-                                        uint32_t flags, bool opaqueVertexColors);
+    GrDistanceFieldNoGammaTextureEffect(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
+                                        const GrTextureParams& params, uint32_t flags,
+                                        bool opaqueVertexColors);
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
@@ -174,11 +180,12 @@
  */
 class GrDistanceFieldLCDTextureEffect : public GrGeometryProcessor {
 public:
-    static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
-                                       GrTexture* gamma, const GrTextureParams& gammaParams,
+    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
+                                       const GrTextureParams& params, GrTexture* gamma,
+                                       const GrTextureParams& gammaParams,
                                        SkColor textColor, uint32_t flags) {
         return SkNEW_ARGS(GrDistanceFieldLCDTextureEffect,
-                          (color, tex, params, gamma, gammaParams, textColor, flags));
+                          (color, viewMatrix, tex, params, gamma, gammaParams, textColor, flags));
     }
 
     virtual ~GrDistanceFieldLCDTextureEffect() {}
@@ -203,10 +210,10 @@
                         const GrBatchTracker&) const SK_OVERRIDE;
 
 private:
-    GrDistanceFieldLCDTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params,
+    GrDistanceFieldLCDTextureEffect(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
+                                    const GrTextureParams& params,
                                     GrTexture* gamma, const GrTextureParams& gammaParams,
-                                    SkColor textColor,
-                                    uint32_t flags);
+                                    SkColor textColor, uint32_t flags);
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;