Add rotation to surfaceflingers screen cap.

+ This is needed so that activity manager does not
  have to do cpu side rotations when capturing recents
  thumbnails.

Change-Id: If998008e675ad01305db8399fd643cf4608b7025
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index d1e324c..c2768f3 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -21,6 +21,7 @@
 
 #include <utils/String8.h>
 #include <cutils/compiler.h>
+#include <gui/ISurfaceComposer.h>
 
 #include "GLES11RenderEngine.h"
 #include "Mesh.h"
@@ -74,7 +75,8 @@
 }
 
 void GLES11RenderEngine::setViewportAndProjection(
-        size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) {
+        size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
+        Transform::orientation_flags rotation) {
     glViewport(0, 0, vpw, vph);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
@@ -91,6 +93,23 @@
     } else {
         glOrthof(l, r, b, t, 0, 1);
     }
+
+    switch (rotation) {
+        case Transform::ROT_0:
+            break;
+        case Transform::ROT_90:
+            glRotatef(90, 0, 0, 1);
+            break;
+        case Transform::ROT_180:
+            glRotatef(180, 0, 0, 1);
+            break;
+        case Transform::ROT_270:
+            glRotatef(270, 0, 0, 1);
+            break;
+        default:
+            break;
+    }
+
     glMatrixMode(GL_MODELVIEW);
 }
 
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 1a94592..87eb3e4 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 
 #include <GLES/gl.h>
+#include <Transform.h>
 
 #include "RenderEngine.h"
 
@@ -50,7 +51,7 @@
 
     virtual void dump(String8& result);
     virtual void setViewportAndProjection(size_t vpw, size_t vph,
-            Rect sourceCrop, size_t hwh, bool yswap);
+            Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
     virtual void setupDimLayerBlending(int alpha);
     virtual void setupLayerTexturing(const Texture& texture);
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 8c1f04e..8ebafbc 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -25,6 +25,8 @@
 #include <utils/Trace.h>
 
 #include <cutils/compiler.h>
+#include <gui/ISurfaceComposer.h>
+#include <math.h>
 
 #include "GLES20RenderEngine.h"
 #include "Program.h"
@@ -80,7 +82,8 @@
 }
 
 void GLES20RenderEngine::setViewportAndProjection(
-        size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) {
+        size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
+        Transform::orientation_flags rotation) {
 
     size_t l = sourceCrop.left;
     size_t r = sourceCrop.right;
@@ -96,6 +99,24 @@
         m = mat4::ortho(l, r, b, t, 0, 1);
     }
 
+    // Apply custom rotation to the projection.
+    float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
+    switch (rotation) {
+        case Transform::ROT_0:
+            break;
+        case Transform::ROT_90:
+            m = mat4::rotate(rot90InRadians, vec3(0,0,1)) * m;
+            break;
+        case Transform::ROT_180:
+            m = mat4::rotate(rot90InRadians * 2.0f, vec3(0,0,1)) * m;
+            break;
+        case Transform::ROT_270:
+            m = mat4::rotate(rot90InRadians * 3.0f, vec3(0,0,1)) * m;
+            break;
+        default:
+            break;
+    }
+
     glViewport(0, 0, vpw, vph);
     mState.setProjectionMatrix(m);
     mVpWidth = vpw;
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index b6d32fc..3d6243e 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 
 #include <GLES2/gl2.h>
+#include <Transform.h>
 
 #include "RenderEngine.h"
 #include "ProgramCache.h"
@@ -65,7 +66,7 @@
 
     virtual void dump(String8& result);
     virtual void setViewportAndProjection(size_t vpw, size_t vph,
-            Rect sourceCrop, size_t hwh, bool yswap);
+            Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
     virtual void setupDimLayerBlending(int alpha);
     virtual void setupLayerTexturing(const Texture& texture);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index a2d8242..acbff9b 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -24,6 +24,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <ui/mat4.h>
+#include <Transform.h>
 
 #define EGL_NO_CONFIG ((EGLConfig)0)
 
@@ -90,7 +91,7 @@
     // set-up
     virtual void checkErrors() const;
     virtual void setViewportAndProjection(size_t vpw, size_t vph,
-            Rect sourceCrop, size_t hwh, bool yswap) = 0;
+            Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0;
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
     virtual void setupDimLayerBlending(int alpha) = 0;
     virtual void setupLayerTexturing(const Texture& texture) = 0;