camera2: Undo mirror for front camera in legacy mode.

Bug: 16637957

- In Camera1 API, front facing camera preview is always mirrored across
  the vertical axis.  Undo this flip in the legacy mode Camera2 API
  sampling operation when copying from the texture drawn to with the
  Camera1 API preview buffers.

Change-Id: Ib8ae4fa97f4ad62a3e55ae7da7d474a8655e747d
diff --git a/core/java/android/hardware/camera2/legacy/GLThreadManager.java b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
index 06521cf..2c584ef 100644
--- a/core/java/android/hardware/camera2/legacy/GLThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
@@ -121,9 +121,10 @@
      * Create a new GL thread and renderer.
      *
      * @param cameraId the camera id for this thread.
+     * @param facing direction the camera is facing.
      */
-    public GLThreadManager(int cameraId) {
-        mTextureRenderer = new SurfaceTextureRenderer();
+    public GLThreadManager(int cameraId, int facing) {
+        mTextureRenderer = new SurfaceTextureRenderer(facing);
         TAG = String.format("CameraDeviceGLThread-%d", cameraId);
         mGLHandlerThread = new RequestHandlerThread(TAG, mGLHandlerCb);
     }
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index eb8debb..e6ff17b 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -399,7 +399,7 @@
 
         // TODO: Detect and optimize single-output paths here to skip stream teeing.
         if (mGLThreadManager == null) {
-            mGLThreadManager = new GLThreadManager(mCameraId);
+            mGLThreadManager = new GLThreadManager(mCameraId, facing);
             mGLThreadManager.start();
         }
         mGLThreadManager.waitUntilStarted();
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index b1b0f9b..a35883c 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -18,6 +18,7 @@
 import android.graphics.ImageFormat;
 import android.graphics.RectF;
 import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraCharacteristics;
 import android.os.Environment;
 import android.opengl.EGL14;
 import android.opengl.EGLConfig;
@@ -80,7 +81,18 @@
     private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
     private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
     private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
-    private final float[] mTriangleVerticesData = {
+
+    // Sampling is mirrored across the vertical axis to undo horizontal flip from the front camera
+    private static final float[] sFrontCameraTriangleVertices = {
+            // X, Y, Z, U, V
+            -1.0f, -1.0f, 0, 1.f, 0.f,
+            1.0f, -1.0f, 0, 0.f, 0.f,
+            -1.0f,  1.0f, 0, 1.f, 1.f,
+            1.0f,  1.0f, 0, 0.f, 1.f,
+    };
+
+    // Sampling is 1:1 for a straight copy for the back camera
+    private static final float[] sBackCameraTriangleVertices = {
             // X, Y, Z, U, V
             -1.0f, -1.0f, 0, 0.f, 0.f,
             1.0f, -1.0f, 0, 1.f, 0.f,
@@ -135,10 +147,16 @@
     private PerfMeasurement mPerfMeasurer = null;
     private static final String LEGACY_PERF_PROPERTY = "persist.camera.legacy_perf";
 
-    public SurfaceTextureRenderer() {
-        mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length *
-                FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
-        mTriangleVertices.put(mTriangleVerticesData).position(0);
+    public SurfaceTextureRenderer(int facing) {
+        if (facing == CameraCharacteristics.LENS_FACING_BACK) {
+            mTriangleVertices = ByteBuffer.allocateDirect(sBackCameraTriangleVertices.length *
+                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+            mTriangleVertices.put(sBackCameraTriangleVertices).position(0);
+        } else {
+            mTriangleVertices = ByteBuffer.allocateDirect(sFrontCameraTriangleVertices.length *
+                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+            mTriangleVertices.put(sFrontCameraTriangleVertices).position(0);
+        }
         Matrix.setIdentityM(mSTMatrix, 0);
     }