Add getGLMatrix method to MatrixState

Removes redundant code by consolidating it into a single method. No
change in functionality, this is strictly a refactoring.

R=bsalomon@google.com

Author: cdalton@nvidia.com

Review URL: https://chromiumcodereview.appspot.com/23767005

git-svn-id: http://skia.googlecode.com/svn/trunk/src@11112 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/gl/GrGLProgram.cpp b/gpu/gl/GrGLProgram.cpp
index d457a32..ac9794d 100644
--- a/gpu/gl/GrGLProgram.cpp
+++ b/gpu/gl/GrGLProgram.cpp
@@ -980,35 +980,13 @@
     if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
         !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) ||
         fMatrixState.fRenderTargetSize != size) {
-        SkMatrix m;
-        if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
-            m.setAll(
-                SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1,
-                0,-SkIntToScalar(2) / size.fHeight, SK_Scalar1,
-            0, 0, SkMatrix::I()[8]);
-        } else {
-            m.setAll(
-                SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1,
-                0, SkIntToScalar(2) / size.fHeight,-SK_Scalar1,
-            0, 0, SkMatrix::I()[8]);
-        }
-        m.setConcat(m, drawState.getViewMatrix());
 
-        // ES doesn't allow you to pass true to the transpose param so we do our own transpose.
-        GrGLfloat mt[]  = {
-            SkScalarToFloat(m[SkMatrix::kMScaleX]),
-            SkScalarToFloat(m[SkMatrix::kMSkewY]),
-            SkScalarToFloat(m[SkMatrix::kMPersp0]),
-            SkScalarToFloat(m[SkMatrix::kMSkewX]),
-            SkScalarToFloat(m[SkMatrix::kMScaleY]),
-            SkScalarToFloat(m[SkMatrix::kMPersp1]),
-            SkScalarToFloat(m[SkMatrix::kMTransX]),
-            SkScalarToFloat(m[SkMatrix::kMTransY]),
-            SkScalarToFloat(m[SkMatrix::kMPersp2])
-        };
-        fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt);
         fMatrixState.fViewMatrix = drawState.getViewMatrix();
         fMatrixState.fRenderTargetSize = size;
         fMatrixState.fRenderTargetOrigin = rt->origin();
+
+        GrGLfloat viewMatrix[3 * 3];
+        fMatrixState.getGLMatrix<3>(viewMatrix);
+        fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix);
     }
 }
diff --git a/gpu/gl/GrGLProgram.h b/gpu/gl/GrGLProgram.h
index 283ac03..4a16b0c 100644
--- a/gpu/gl/GrGLProgram.h
+++ b/gpu/gl/GrGLProgram.h
@@ -100,6 +100,20 @@
             fRenderTargetSize.fHeight = -1;
             fRenderTargetOrigin = (GrSurfaceOrigin) -1;
         }
+        template<int Size> void getGLMatrix(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, SkMatrix::I()[8]);
+            } else {
+                combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1,
+                                0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1,
+                                0, 0, SkMatrix::I()[8]);
+            }
+            combined.setConcat(combined, fViewMatrix);
+            GrGLGetMatrix<Size>(destMatrix, combined);
+        }
     };
 
     /**
diff --git a/gpu/gl/GrGLUtil.cpp b/gpu/gl/GrGLUtil.cpp
index 422f0c3..d6f5820 100644
--- a/gpu/gl/GrGLUtil.cpp
+++ b/gpu/gl/GrGLUtil.cpp
@@ -7,6 +7,7 @@
 
 
 #include "GrGLUtil.h"
+#include "SkMatrix.h"
 
 void GrGLClearErr(const GrGLInterface* gl) {
     while (GR_GL_NO_ERROR != gl->fGetError()) {}
@@ -236,3 +237,46 @@
     GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
     return GrGLGetVendorFromString((const char*) v);
 }
+
+template<> void GrGLGetMatrix<3>(GrGLfloat* dest, const SkMatrix& src) {
+    // Col 0
+    dest[0] = SkScalarToFloat(src[SkMatrix::kMScaleX]);
+    dest[1] = SkScalarToFloat(src[SkMatrix::kMSkewY]);
+    dest[2] = SkScalarToFloat(src[SkMatrix::kMPersp0]);
+
+    // Col 1
+    dest[3] = SkScalarToFloat(src[SkMatrix::kMSkewX]);
+    dest[4] = SkScalarToFloat(src[SkMatrix::kMScaleY]);
+    dest[5] = SkScalarToFloat(src[SkMatrix::kMPersp1]);
+
+    // Col 2
+    dest[6] = SkScalarToFloat(src[SkMatrix::kMTransX]);
+    dest[7] = SkScalarToFloat(src[SkMatrix::kMTransY]);
+    dest[8] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
+}
+
+template<> void GrGLGetMatrix<4>(GrGLfloat* dest, const SkMatrix& src) {
+    // Col 0
+    dest[0]  = SkScalarToFloat(src[SkMatrix::kMScaleX]);
+    dest[1]  = SkScalarToFloat(src[SkMatrix::kMSkewY]);
+    dest[2]  = 0;
+    dest[3]  = SkScalarToFloat(src[SkMatrix::kMPersp0]);
+
+    // Col 1
+    dest[4]  = SkScalarToFloat(src[SkMatrix::kMSkewX]);
+    dest[5]  = SkScalarToFloat(src[SkMatrix::kMScaleY]);
+    dest[6]  = 0;
+    dest[7]  = SkScalarToFloat(src[SkMatrix::kMPersp1]);
+
+    // Col 2
+    dest[8]  = 0;
+    dest[9]  = 0;
+    dest[10] = 1;
+    dest[11] = 0;
+
+    // Col 3
+    dest[12] = SkScalarToFloat(src[SkMatrix::kMTransX]);
+    dest[13] = SkScalarToFloat(src[SkMatrix::kMTransY]);
+    dest[14] = 0;
+    dest[15] = SkScalarToFloat(src[SkMatrix::kMPersp2]);
+}
diff --git a/gpu/gl/GrGLUtil.h b/gpu/gl/GrGLUtil.h
index 9a82b0b..686943b 100644
--- a/gpu/gl/GrGLUtil.h
+++ b/gpu/gl/GrGLUtil.h
@@ -11,6 +11,8 @@
 #include "gl/GrGLInterface.h"
 #include "GrGLDefines.h"
 
+class SkMatrix;
+
 ////////////////////////////////////////////////////////////////////////////////
 
 typedef uint32_t GrGLVersion;
@@ -91,6 +93,11 @@
 
 void GrGLClearErr(const GrGLInterface* gl);
 
+/**
+ * Helper for converting SkMatrix to a column-major GL float array
+ */
+template<int MatrixSize> void GrGLGetMatrix(GrGLfloat* dest, const SkMatrix& src);
+
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
diff --git a/gpu/gl/GrGpuGL_program.cpp b/gpu/gl/GrGpuGL_program.cpp
index 0795dfa..ce74303 100644
--- a/gpu/gl/GrGpuGL_program.cpp
+++ b/gpu/gl/GrGpuGL_program.cpp
@@ -212,46 +212,15 @@
     if (fHWProjectionMatrixState.fRenderTargetOrigin != rt->origin() ||
         !fHWProjectionMatrixState.fViewMatrix.cheapEqualTo(viewMatrix) ||
         fHWProjectionMatrixState.fRenderTargetSize!= size) {
-        // rescale the coords from skia's "device" coords to GL's normalized coords,
-        // and perform a y-flip if required.
-        SkMatrix m;
-        if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
-            m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height());
-            m.postTranslate(-SK_Scalar1, SK_Scalar1);
-        } else {
-            m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(2) / rt->height());
-            m.postTranslate(-SK_Scalar1, -SK_Scalar1);
-        }
-        m.preConcat(vm);
 
-        // GL wants a column-major 4x4.
-        GrGLfloat mv[]  = {
-            // col 0
-            SkScalarToFloat(m[SkMatrix::kMScaleX]),
-            SkScalarToFloat(m[SkMatrix::kMSkewY]),
-            0,
-            SkScalarToFloat(m[SkMatrix::kMPersp0]),
-
-            // col 1
-            SkScalarToFloat(m[SkMatrix::kMSkewX]),
-            SkScalarToFloat(m[SkMatrix::kMScaleY]),
-            0,
-            SkScalarToFloat(m[SkMatrix::kMPersp1]),
-
-            // col 2
-            0, 0, 0, 0,
-
-            // col3
-            SkScalarToFloat(m[SkMatrix::kMTransX]),
-            SkScalarToFloat(m[SkMatrix::kMTransY]),
-            0.0f,
-            SkScalarToFloat(m[SkMatrix::kMPersp2])
-        };
-        GL_CALL(MatrixMode(GR_GL_PROJECTION));
-        GL_CALL(LoadMatrixf(mv));
         fHWProjectionMatrixState.fViewMatrix = vm;
         fHWProjectionMatrixState.fRenderTargetSize = size;
         fHWProjectionMatrixState.fRenderTargetOrigin = rt->origin();
+
+        GrGLfloat projectionMatrix[4 * 4];
+        fHWProjectionMatrixState.getGLMatrix<4>(projectionMatrix);
+        GL_CALL(MatrixMode(GR_GL_PROJECTION));
+        GL_CALL(LoadMatrixf(projectionMatrix));
     }
 }