Fix camera orientation by swapping horizontal and vertical flips when needed.

Bug: 16637957

Change-Id: I66de597546fdc19e0af9e6150ca20460ab36bf8b
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cf49798..2bbb223 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -332,6 +332,14 @@
             if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
                 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
                         NATIVE_WINDOW_TRANSFORM_FLIP_H;
+                // If the transform has been rotated the axis of flip has been swapped
+                // so we need to swap which flip operations we are performing
+                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
+                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
+                if (is_h_flipped != is_v_flipped) {
+                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
+                }
             }
             // and apply to the current transform
             invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
@@ -411,13 +419,22 @@
          * the code below applies the display's inverse transform to the buffer
          */
         uint32_t invTransform = hw->getOrientationTransform();
+        uint32_t t_orientation = transform.getOrientation();
         // calculate the inverse transform
         if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
             invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
                     NATIVE_WINDOW_TRANSFORM_FLIP_H;
+            // If the transform has been rotated the axis of flip has been swapped
+            // so we need to swap which flip operations we are performing
+            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
+            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
+            if (is_h_flipped != is_v_flipped) {
+                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
+            }
         }
         // and apply to the current transform
-        transform = transform * Transform(invTransform);
+        transform = Transform(t_orientation) * Transform(invTransform);
     }
 
     // this gives us only the "orientation" component of the transform