Optimize shader binding changes.

This change also cleans up the internal API a little bit by using mat4
everywhere instead of float[16] (for the ortho matrix for instance.)

Change-Id: I35924c7dc17bad17f30307118d5ed437c2ed37e0
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b783d3f..117fccd 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -118,6 +118,7 @@
 
     mDrawColorShader = new DrawColorProgram;
     mDrawTextureShader = new DrawTextureProgram;
+    mCurrentShader = mDrawTextureShader;
 
     memcpy(mDrawTextureVertices, gDrawTextureVertices, sizeof(gDrawTextureVertices));
 }
@@ -136,9 +137,7 @@
 void OpenGLRenderer::setViewport(int width, int height) {
     glViewport(0, 0, width, height);
 
-    mat4 ortho;
-    ortho.loadOrtho(0, width, height, 0, -1, 1);
-    ortho.copyTo(mOrthoMatrix);
+    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
 
     mWidth = width;
     mHeight = height;
@@ -208,7 +207,7 @@
     sp<Snapshot> previous = mSnapshot->previous;
 
     if (restoreOrtho) {
-        memcpy(mOrthoMatrix, current->orthoMatrix, sizeof(mOrthoMatrix));
+        mOrthoMatrix.load(current->orthoMatrix);
     }
 
     if (restoreLayer) {
@@ -333,12 +332,10 @@
 
     mSnapshot->flags = Snapshot::kFlagDirtyTransform | Snapshot::kFlagDirtyOrtho |
             Snapshot::kFlagClipSet;
-    memcpy(mSnapshot->orthoMatrix, mOrthoMatrix, sizeof(mOrthoMatrix));
+    mSnapshot->orthoMatrix.load(mOrthoMatrix);
 
     // Change the ortho projection
-    mat4 ortho;
-    ortho.loadOrtho(0.0f, right - left, bottom - top, 0.0f, 0.0f, 1.0f);
-    ortho.copyTo(mOrthoMatrix);
+    mOrthoMatrix.loadOrtho(0.0f, right - left, bottom - top, 0.0f, 0.0f, 1.0f);
 
     return true;
 }
@@ -511,7 +508,8 @@
     mModelView.loadTranslate(left, top, 0.0f);
     mModelView.scale(right - left, bottom - top, 1.0f);
 
-    mDrawColorShader->use(&mOrthoMatrix[0], mModelView, mSnapshot->transform);
+    useShader(mDrawColorShader);
+    mDrawColorShader->set(mOrthoMatrix, mModelView, mSnapshot->transform);
 
     const GLvoid* p = &gDrawColorVertices[0].position[0];
 
@@ -548,7 +546,8 @@
     mModelView.loadTranslate(left, top, 0.0f);
     mModelView.scale(right - left, bottom - top, 1.0f);
 
-    mDrawTextureShader->use(&mOrthoMatrix[0], mModelView, mSnapshot->transform);
+    useShader(mDrawTextureShader);
+    mDrawTextureShader->set(mOrthoMatrix, mModelView, mSnapshot->transform);
 
     chooseBlending(blend || alpha < 1.0f, mode, isPremultiplied);
 
@@ -606,6 +605,14 @@
     mBlend = blend;
 }
 
+void OpenGLRenderer::useShader(const sp<Program>& shader) {
+    if (!shader->isInUse()) {
+        mCurrentShader->remove();
+        shader->use();
+        mCurrentShader = shader;
+    }
+}
+
 void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) {
     TextureVertex* v = &mDrawTextureVertices[0];
     TextureVertex::setUV(v++, u1, v1);