ViewMatrix uniform upload moved to GeometryProcessor

BUG=skia:

Review URL: https://codereview.chromium.org/827973002
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 47b68ed..ed6bc63 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -541,9 +541,12 @@
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), qe.inPosition()->fName);
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), qe.inPosition()->fName);
 
+            // setup uniform viewMatrix
+            this->addUniformViewMatrix(pb);
+
             // setup position varying
             vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), qe.inPosition()->fName);
+                                   this->uViewM(), qe.inPosition()->fName);
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 
@@ -582,6 +585,8 @@
         virtual void setData(const GrGLProgramDataManager& pdman,
                              const GrPrimitiveProcessor& gp,
                              const GrBatchTracker& bt) SK_OVERRIDE {
+            this->setUniformViewMatrix(pdman, gp.viewMatrix());
+
             const BatchTracker& local = bt.cast<BatchTracker>();
             if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
                 GrGLfloat c[4];
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index 2c5117b..b64c456 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -103,8 +103,11 @@
                 vs->codeAppendf("%s = %s;", vs->localCoords(), gp.inPosition()->fName);
             }
 
+            // setup uniform viewMatrix
+            this->addUniformViewMatrix(pb);
+
             // setup position varying
-            vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(),
+            vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), this->uViewM(),
                             gp.inPosition()->fName);
 
             // Setup coverage as pass through
@@ -141,6 +144,8 @@
         virtual void setData(const GrGLProgramDataManager& pdman,
                              const GrPrimitiveProcessor& gp,
                              const GrBatchTracker& bt) SK_OVERRIDE {
+            this->setUniformViewMatrix(pdman, gp.viewMatrix());
+
             const BatchTracker& local = bt.cast<BatchTracker>();
             if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
                 GrGLfloat c[4];
diff --git a/src/gpu/GrGeometryProcessor.cpp b/src/gpu/GrGeometryProcessor.cpp
index 01ea85a..6bd6b2b 100644
--- a/src/gpu/GrGeometryProcessor.cpp
+++ b/src/gpu/GrGeometryProcessor.cpp
@@ -56,6 +56,25 @@
     }
 }
 
+void GrGLGeometryProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) {
+    fViewMatrixUniform = pb->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+                                        kMat33f_GrSLType, kDefault_GrSLPrecision,
+                                        "uViewM",
+                                        &fViewMatrixName);
+}
+
+void GrGLGeometryProcessor::setUniformViewMatrix(const GrGLProgramDataManager& pdman,
+                                                 const SkMatrix& viewMatrix) {
+    if (!fViewMatrix.cheapEqualTo(viewMatrix)) {
+        SkASSERT(fViewMatrixUniform.isValid());
+        fViewMatrix = viewMatrix;
+
+        GrGLfloat viewMatrix[3 * 3];
+        GrGLGetMatrix<3>(viewMatrix, fViewMatrix);
+        pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 struct PathBatchTracker {
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index 80f2278..2365f1e 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -66,14 +66,12 @@
         // indicate that this can be skipped.
         fFlags = 0;
         fDrawFace = GrDrawState::kInvalid_DrawFace;
-        fViewMatrix.reset();
         return;
     }
 
     fRenderTarget.reset(drawState.fRenderTarget.get());
     SkASSERT(fRenderTarget);
     fScissorState = scissorState;
-    fViewMatrix = fPrimitiveProcessor->viewMatrix();
     fStencilSettings = drawState.getStencil();
     fDrawFace = drawState.getDrawFace();
     // TODO move this out of optDrawState
@@ -180,7 +178,6 @@
         this->fFragmentStages.count() != that.fFragmentStages.count() ||
         this->fNumColorStages != that.fNumColorStages ||
         this->fScissorState != that.fScissorState ||
-        !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
         this->fDrawType != that.fDrawType ||
         this->fFlags != that.fFlags ||
         this->fStencilSettings != that.fStencilSettings ||
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index 111f920..fa79314 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -85,18 +85,6 @@
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
-    /// @name View Matrix
-    ////
-
-    /**
-     * Retrieves the current view matrix
-     * @return the current view matrix.
-     */
-    const SkMatrix& getViewMatrix() const { return fViewMatrix; }
-
-    /// @}
-
-    ///////////////////////////////////////////////////////////////////////////
     /// @name Render Target
     ////
 
@@ -186,7 +174,6 @@
     typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
     RenderTarget                        fRenderTarget;
     GrScissorState                      fScissorState;
-    SkMatrix                            fViewMatrix;
     GrStencilSettings                   fStencilSettings;
     GrDrawState::DrawFace               fDrawFace;
     GrDeviceCoordTexture                fDstCopy;
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 06b2e11..b43c485 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -101,9 +101,12 @@
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ce.inPosition()->fName);
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ce.inPosition()->fName);
 
+            // setup uniform viewMatrix
+            this->addUniformViewMatrix(pb);
+
             // setup position varying
             vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), ce.inPosition()->fName);
+                                   this->uViewM(), ce.inPosition()->fName);
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
@@ -131,6 +134,8 @@
         virtual void setData(const GrGLProgramDataManager& pdman,
                              const GrPrimitiveProcessor& gp,
                              const GrBatchTracker& bt) SK_OVERRIDE {
+            this->setUniformViewMatrix(pdman, gp.viewMatrix());
+
             const BatchTracker& local = bt.cast<BatchTracker>();
             if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
                 GrGLfloat c[4];
@@ -274,9 +279,12 @@
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName);
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName);
 
+            // setup uniform viewMatrix
+            this->addUniformViewMatrix(pb);
+
             // setup position varying
             vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), ee.inPosition()->fName);
+                                   this->uViewM(), ee.inPosition()->fName);
 
             // for outer curve
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -319,6 +327,8 @@
         virtual void setData(const GrGLProgramDataManager& pdman,
                              const GrPrimitiveProcessor& gp,
                              const GrBatchTracker& bt) SK_OVERRIDE {
+            this->setUniformViewMatrix(pdman, gp.viewMatrix());
+
             const BatchTracker& local = bt.cast<BatchTracker>();
             if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
                 GrGLfloat c[4];
@@ -469,9 +479,12 @@
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.inPosition()->fName);
             vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPosition()->fName);
 
+            // setup uniform viewMatrix
+            this->addUniformViewMatrix(pb);
+
             // setup position varying
             vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), ee.inPosition()->fName);
+                                   this->uViewM(), ee.inPosition()->fName);
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             SkAssertResult(fsBuilder->enableFeature(
@@ -529,6 +542,8 @@
         virtual void setData(const GrGLProgramDataManager& pdman,
                              const GrPrimitiveProcessor& gp,
                              const GrBatchTracker& bt) SK_OVERRIDE {
+            this->setUniformViewMatrix(pdman, gp.viewMatrix());
+
             const BatchTracker& local = bt.cast<BatchTracker>();
             if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
                 GrGLfloat c[4];
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 4ab088c..e846b79 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -32,8 +32,10 @@
                               GrProcessorKeyBuilder*);
 
     virtual void setData(const GrGLProgramDataManager& pdman,
-                         const GrPrimitiveProcessor&,
+                         const GrPrimitiveProcessor& primProc,
                          const GrBatchTracker& bt) SK_OVERRIDE {
+        this->setUniformViewMatrix(pdman, primProc.viewMatrix());
+
         const ConicBatchTracker& local = bt.cast<ConicBatchTracker>();
         if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
             GrGLfloat c[4];
@@ -82,8 +84,11 @@
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
 
+    // setup uniform viewMatrix
+    this->addUniformViewMatrix(pb);
+
     // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
+    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
                            gp.inPosition()->fName);
 
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -261,8 +266,10 @@
                               GrProcessorKeyBuilder*);
 
     virtual void setData(const GrGLProgramDataManager& pdman,
-                         const GrPrimitiveProcessor&,
+                         const GrPrimitiveProcessor& primProc,
                          const GrBatchTracker& bt) SK_OVERRIDE {
+        this->setUniformViewMatrix(pdman, primProc.viewMatrix());
+
         const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
         if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
             GrGLfloat c[4];
@@ -311,8 +318,11 @@
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
 
+    // setup uniform viewMatrix
+    this->addUniformViewMatrix(pb);
+
     // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
+    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
                            gp.inPosition()->fName);
 
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@@ -476,8 +486,10 @@
                               GrProcessorKeyBuilder*);
 
     virtual void setData(const GrGLProgramDataManager& pdman,
-                         const GrPrimitiveProcessor&,
+                         const GrPrimitiveProcessor& primProc,
                          const GrBatchTracker& bt) SK_OVERRIDE {
+        this->setUniformViewMatrix(pdman, primProc.viewMatrix());
+
         const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
         if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
             GrGLfloat c[4];
@@ -519,8 +531,11 @@
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
 
+    // setup uniform viewMatrix
+    this->addUniformViewMatrix(args.fPB);
+
     // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
+    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
                            gp.inPosition()->fName);
 
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 936bf32..5f44d32 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -44,9 +44,12 @@
         vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), cte.inPosition()->fName);
         vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), cte.inPosition()->fName);
 
+        // setup uniform viewMatrix
+        this->addUniformViewMatrix(pb);
+
         // setup position varying
-        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), cte.inPosition()->fName);
+        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
+                               cte.inPosition()->fName);
 
         GrGLGPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
         fsBuilder->codeAppendf("%s = ", args.fOutputCoverage);
@@ -57,6 +60,8 @@
     virtual void setData(const GrGLProgramDataManager& pdman,
                          const GrPrimitiveProcessor& gp,
                          const GrBatchTracker& bt) SK_OVERRIDE {
+        this->setUniformViewMatrix(pdman, gp.viewMatrix());
+
         const BitmapTextBatchTracker& local = bt.cast<BitmapTextBatchTracker>();
         if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
             GrGLfloat c[4];
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index 4788b3a..47b8d65 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -583,8 +583,11 @@
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), dce.inPosition()->fName);
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), dce.inPosition()->fName);
 
+    // setup uniform viewMatrix
+    this->addUniformViewMatrix(pb);
+
     // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
+    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
                            dce.inPosition()->fName);
 
     // transforms all points so that we can compare them to our test circle
@@ -608,6 +611,8 @@
 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman,
                                     const GrPrimitiveProcessor& processor,
                                     const GrBatchTracker& bt) {
+    this->setUniformViewMatrix(pdman, processor.viewMatrix());
+
     const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>();
     SkScalar radius = dce.getRadius();
     SkScalar centerX = dce.getCenterX();
@@ -871,8 +876,11 @@
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), de.inPosition()->fName);
     vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), de.inPosition()->fName);
 
+    // setup uniform viewMatrix
+    this->addUniformViewMatrix(pb);
+
     // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
+    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
                            de.inPosition()->fName);
 
     // transforms all points so that we can compare them to our test rect
@@ -903,6 +911,8 @@
 void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman,
                                   const GrPrimitiveProcessor& processor,
                                   const GrBatchTracker& bt) {
+    this->setUniformViewMatrix(pdman, processor.viewMatrix());
+
     const DashingLineEffect& de = processor.cast<DashingLineEffect>();
     const SkRect& rect = de.getRect();
     SkScalar intervalLength = de.getIntervalLength();
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index 669a504..21fbb30 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -53,9 +53,12 @@
         this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
                                     dfTexEffect.inColor(), &fColorUniform);
 
+        // setup uniform viewMatrix
+        this->addUniformViewMatrix(pb);
+
         // setup position varying
         vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), dfTexEffect.inPosition()->fName);
+                               this->uViewM(), dfTexEffect.inPosition()->fName);
 
         // setup output coords
         vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(),
@@ -150,6 +153,8 @@
         }
 #endif
 
+        this->setUniformViewMatrix(pdman, proc.viewMatrix());
+
         const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
         if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
             GrGLfloat c[4];
@@ -343,9 +348,12 @@
         vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(),
                                dfTexEffect.inPosition()->fName);
 
+        // setup uniform viewMatrix
+        this->addUniformViewMatrix(pb);
+
         // setup position varying
         vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), dfTexEffect.inPosition()->fName);
+                               this->uViewM(), dfTexEffect.inPosition()->fName);
 
         const char* textureSizeUniName = NULL;
         fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@@ -410,6 +418,8 @@
                         SkIntToScalar(fTextureSize.height()));
         }
 
+        this->setUniformViewMatrix(pdman, proc.viewMatrix());
+
         const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoGammaBatchTracker>();
         if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
             GrGLfloat c[4];
@@ -573,9 +583,12 @@
         vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(),
                                dfTexEffect.inPosition()->fName);
 
+        // setup uniform viewMatrix
+        this->addUniformViewMatrix(pb);
+
         // setup position varying
-        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), dfTexEffect.inPosition()->fName);
+        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
+                               dfTexEffect.inPosition()->fName);
 
         const char* textureSizeUniName = NULL;
         // width, height, 1/(3*width)
@@ -717,6 +730,8 @@
             fTextColor = textColor;
         }
 
+        this->setUniformViewMatrix(pdman, processor.viewMatrix());
+
         const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
         if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
             GrGLfloat c[4];
diff --git a/src/gpu/gl/GrGLGeometryProcessor.h b/src/gpu/gl/GrGLGeometryProcessor.h
index a9f5ead..0b24144 100644
--- a/src/gpu/gl/GrGLGeometryProcessor.h
+++ b/src/gpu/gl/GrGLGeometryProcessor.h
@@ -20,7 +20,7 @@
  */
 class GrGLGeometryProcessor {
 public:
-    GrGLGeometryProcessor() {}
+    GrGLGeometryProcessor() : fViewMatrixName(NULL) { fViewMatrix = SkMatrix::InvalidMatrix(); }
     virtual ~GrGLGeometryProcessor() {}
 
     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
@@ -74,7 +74,23 @@
                                const GrGeometryProcessor::GrAttribute* colorAttr,
                                UniformHandle* colorUniform);
 
+    const char* uViewM() const { return fViewMatrixName; }
+
+    /** a helper function to setup the uniform handle for the uniform view matrix */
+    void addUniformViewMatrix(GrGLGPBuilder*);
+
+
+    /** a helper function to upload a uniform viewmatrix.
+     * TODO we can remove this function when we have deferred geometry in place
+     */
+    void setUniformViewMatrix(const GrGLProgramDataManager&,
+                              const SkMatrix& viewMatrix);
+
 private:
+    UniformHandle fViewMatrixUniform;
+    SkMatrix fViewMatrix;
+    const char* fViewMatrixName;
+
     typedef GrGLProcessor INHERITED;
 };
 
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 7bf6ce6..35c4b82 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -339,8 +339,8 @@
 }
 
 void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
-                                  const SkISize& renderTargetSize,
-                                  GrSurfaceOrigin renderTargetOrigin) {
+                                            const SkISize& renderTargetSize,
+                                            GrSurfaceOrigin renderTargetOrigin) {
 
     SkASSERT(fGpu->glCaps().pathRenderingSupport());
 
diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h
index ee4011d..0ebf470 100644
--- a/src/gpu/gl/GrGLPathRendering.h
+++ b/src/gpu/gl/GrGLPathRendering.h
@@ -126,10 +126,42 @@
                          GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
                          GrGLenum transformType, const GrGLfloat *transformValues);
 
+    struct MatrixState {
+        SkMatrix        fViewMatrix;
+        SkISize         fRenderTargetSize;
+        GrSurfaceOrigin fRenderTargetOrigin;
+
+        MatrixState() { this->invalidate(); }
+        void invalidate() {
+            fViewMatrix = SkMatrix::InvalidMatrix();
+            fRenderTargetSize.fWidth = -1;
+            fRenderTargetSize.fHeight = -1;
+            fRenderTargetOrigin = (GrSurfaceOrigin) -1;
+        }
+
+        /**
+         * Gets a matrix that goes from local coordinates to GL normalized device coords.
+         */
+        template<int Size> void getRTAdjustedGLMatrix(GrGLfloat* destMatrix) {
+            SkMatrix combined;
+            if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
+                combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
+                                0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
+                                0, 0, 1);
+            } else {
+                combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
+                                0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
+                                0, 0, 1);
+            }
+            combined.preConcat(fViewMatrix);
+            GrGLGetMatrix<Size>(destMatrix, combined);
+        }
+    };
+
     GrGLGpu* fGpu;
     SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator;
     Caps fCaps;
-    GrGLProgram::MatrixState fHWProjectionMatrixState;
+    MatrixState fHWProjectionMatrixState;
     GrStencilSettings fHWPathStencilSettings;
     struct PathTexGenData {
         GrGLenum  fMode;
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 60d97a2..9400e54 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -132,7 +132,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrGLProgram::setData(const GrOptDrawState& optState) {
-    this->setMatrixAndRenderTargetHeight(optState);
+    this->setRenderTargetState(optState);
 
     const GrDeviceCoordTexture* dstCopy = optState.getDstCopy();
     if (dstCopy) {
@@ -205,37 +205,29 @@
     SkASSERT(!GrGpu::IsPathRenderingDrawType(drawType));
 }
 
-void GrGLProgram::setMatrixAndRenderTargetHeight(const GrOptDrawState& optState) {
+void GrGLProgram::setRenderTargetState(const GrOptDrawState& optState) {
     // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
     if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
-        fMatrixState.fRenderTargetSize.fHeight != optState.getRenderTarget()->height()) {
+        fRenderTargetState.fRenderTargetSize.fHeight != optState.getRenderTarget()->height()) {
         fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
                                    SkIntToScalar(optState.getRenderTarget()->height()));
     }
 
     // call subclasses to set the actual view matrix
-    this->onSetMatrixAndRenderTargetHeight(optState);
+    this->onSetRenderTargetState(optState);
 }
 
-void GrGLProgram::onSetMatrixAndRenderTargetHeight(const GrOptDrawState& optState) {
+void GrGLProgram::onSetRenderTargetState(const GrOptDrawState& optState) {
     const GrRenderTarget* rt = optState.getRenderTarget();
     SkISize size;
     size.set(rt->width(), rt->height());
-    if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
-        fMatrixState.fRenderTargetSize != size ||
-        !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) {
-        SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid());
-
-        fMatrixState.fViewMatrix = optState.getViewMatrix();
-        fMatrixState.fRenderTargetSize = size;
-        fMatrixState.fRenderTargetOrigin = rt->origin();
-
-        GrGLfloat viewMatrix[3 * 3];
-        fMatrixState.getGLMatrix<3>(viewMatrix);
-        fProgramDataManager.setMatrix3f(fBuiltinUniformHandles.fViewMatrixUni, viewMatrix);
+    if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
+        fRenderTargetState.fRenderTargetSize != size) {
+        fRenderTargetState.fRenderTargetSize = size;
+        fRenderTargetState.fRenderTargetOrigin = rt->origin();
 
         GrGLfloat rtAdjustmentVec[4];
-        fMatrixState.getRTAdjustmentVec(rtAdjustmentVec);
+        fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
         fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
     }
 }
@@ -254,12 +246,13 @@
                 xferProcessor, fragmentProcessors) {
 }
 
-void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(const GrOptDrawState& optState) {
+void GrGLNvprProgramBase::onSetRenderTargetState(const GrOptDrawState& optState) {
     SkASSERT(GrGpu::IsPathRenderingDrawType(optState.drawType()));
     const GrRenderTarget* rt = optState.getRenderTarget();
     SkISize size;
     size.set(rt->width(), rt->height());
-    fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin());
+    fGpu->glPathRendering()->setProjectionMatrix(optState.getPrimitiveProcessor()->viewMatrix(),
+                                                 size, rt->origin());
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 3ee71b8..6e7e22b 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -60,50 +60,22 @@
     virtual bool hasVertexShader() const { return true; }
 
     /**
-     * The GrDrawState's view matrix along with the aspects of the render target determine the
-     * matrix sent to GL. The size of the render target affects the GL matrix because we must
-     * convert from Skia device coords to GL's normalized coords. Also the origin of the render
-     * target may require us to perform a mirror-flip.
+     * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
+     * space and to make device space positions have the correct origin for processors that require
+     * them.
      */
-    struct MatrixState {
-        SkMatrix        fViewMatrix;
+    struct RenderTargetState {
         SkISize         fRenderTargetSize;
         GrSurfaceOrigin fRenderTargetOrigin;
 
-        MatrixState() { this->invalidate(); }
+        RenderTargetState() { this->invalidate(); }
         void invalidate() {
-            fViewMatrix = SkMatrix::InvalidMatrix();
             fRenderTargetSize.fWidth = -1;
             fRenderTargetSize.fHeight = -1;
             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
         }
 
         /**
-         * Gets a matrix that goes from local coords to Skia's device coordinates.
-         */
-        template<int Size> void getGLMatrix(GrGLfloat* destMatrix) {
-            GrGLGetMatrix<Size>(destMatrix, fViewMatrix);
-        }
-
-        /**
-         * Gets a matrix that goes from local coordinates to GL normalized device coords.
-         */
-        template<int Size> void getRTAdjustedGLMatrix(GrGLfloat* destMatrix) {
-            SkMatrix combined;
-            if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
-                combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
-                                0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1,
-                                0, 0, 1);
-            } else {
-                combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
-                                0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
-                                0, 0, 1);
-            }
-            combined.preConcat(fViewMatrix);
-            GrGLGetMatrix<Size>(destMatrix, combined);
-        }
-
-        /**
          * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
          * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
          * applied as such:
@@ -162,11 +134,11 @@
     virtual void didSetData(GrGpu::DrawType);
 
     // Helper for setData() that sets the view matrix and loads the render target height uniform
-    void setMatrixAndRenderTargetHeight(const GrOptDrawState&);
-    virtual void onSetMatrixAndRenderTargetHeight(const GrOptDrawState&);
+    void setRenderTargetState(const GrOptDrawState&);
+    virtual void onSetRenderTargetState(const GrOptDrawState&);
 
     // these reflect the current values of uniforms (GL uniform values travel with program)
-    MatrixState fMatrixState;
+    RenderTargetState fRenderTargetState;
     GrColor fColor;
     uint8_t fCoverage;
     int fDstCopyTexUnit;
@@ -204,7 +176,7 @@
                         GrGLInstalledGeoProc*,
                         GrGLInstalledXferProc* xferProcessor,
                         GrGLInstalledFragProcs* fragmentProcessors);
-    virtual void onSetMatrixAndRenderTargetHeight(const GrOptDrawState&);
+    virtual void onSetRenderTargetState(const GrOptDrawState&);
 
     typedef GrGLProgram INHERITED;
 };
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index c414aba..0c41781 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -178,8 +178,6 @@
 
 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) {
     if (fOptState.hasGeometryProcessor()) {
-        fVS.setupUniformViewMatrix();
-
         fVS.codeAppend("gl_PointSize = 1.0;");
 
         // Setup position
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 032fa57..fd1d6c8 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -240,7 +240,6 @@
 
     // Handles for program uniforms (other than per-effect uniforms)
     struct BuiltinUniformHandles {
-        UniformHandle       fViewMatrixUni;
         UniformHandle       fRTAdjustmentUni;
 
         // We use the render target height to provide a y-down frag coord when specifying
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
index 2ff9782..fd79abb 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -26,13 +26,6 @@
     v->fVsOut = fOutputs.back().getName().c_str();
 }
 
-void GrGLVertexBuilder::setupUniformViewMatrix() {
-    fProgramBuilder->fUniformHandles.fViewMatrixUni =
-            fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
-                                        kMat33f_GrSLType, kDefault_GrSLPrecision,
-                                        this->uViewM());
-}
-
 void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) {
     const GrGeometryProcessor::VertexAttribArray& v = gp.getAttribs();
     int vaCount = v.count();
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
index dbff24f..ba978a8 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -21,10 +21,6 @@
     const char* positionCoords() const { return "position"; }
     const char* localCoords() const { return "localCoords"; }
 
-    /** returns the expected uviewM matrix */
-    // TODO all of this fixed function stuff can live on the GP/PP
-    const char* uViewM() const { return "uViewM"; }
-
     void addAttribute(const GrGeometryProcessor::GrAttribute* attr) {
         this->addAttribute(GrShaderVar(attr->fName,
                                        GrVertexAttribTypeToSLType(attr->fType),
@@ -41,8 +37,6 @@
      * private helpers for compilation by GrGLProgramBuilder
      */
     void transformToNormalizedDeviceSpace();
-    //TODO GP itself should setup the uniform view matrix
-    void setupUniformViewMatrix();
     void emitAttributes(const GrGeometryProcessor& gp);
     void bindVertexAttributes(GrGLuint programID);
     bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;