SF: Add support for inverse mounted panels

Add 180 rotation in SF to account for inverse mounted panels.
The framework will be unaffected and use policies for a 0 mounted
panel. SF changes the global transform and silently induces the H,V
flips. Similar flips are added to screenshots as well.

Change-Id: I6e9576ee734ee85097491eaa1e8e94cfb3731e0f
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index c166aaa..526feb6 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -134,6 +134,11 @@
     property_get("persist.panel.orientation", property, "0");
     panelOrientation = atoi(property) / 90;
 
+    mPanelInverseMounted = false;
+    // Check if panel is inverse mounted (contents show up HV flipped)
+    property_get("persist.panel.inversemounted", property, "0");
+    mPanelInverseMounted = !!atoi(property);
+
     // initialize the display orientation transform.
     setProjection(panelOrientation, mViewport, mFrame);
 }
@@ -408,6 +413,11 @@
     default:
         return BAD_VALUE;
     }
+
+    if (DISPLAY_PRIMARY == mHwcDisplayId && isPanelInverseMounted()) {
+        flags = flags ^ Transform::ROT_180;
+    }
+
     tr->set(flags, w, h);
     return NO_ERROR;
 }
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 76243f0..a1b6f64 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -126,6 +126,10 @@
     int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
     const wp<IBinder>&      getDisplayToken() const { return mDisplayToken; }
 
+    bool isPanelInverseMounted() const {
+        return mPanelInverseMounted;
+    }
+
     // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
     // machine happy without actually queueing a buffer if nothing has changed
     status_t beginFrame(bool mustRecompose) const;
@@ -215,7 +219,7 @@
     /*
      * Transaction state
      */
-    static status_t orientationToTransfrom(int orientation,
+    status_t orientationToTransfrom(int orientation,
             int w, int h, Transform* tr);
 
     uint32_t mLayerStack;
@@ -232,6 +236,8 @@
     int mPowerMode;
     // Current active config
     int mActiveConfig;
+    // Panel is inverse mounted
+    int mPanelInverseMounted;
 };
 
 }; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4b7d3a0..898bebc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3528,6 +3528,12 @@
     // make sure to clear all GL error flags
     engine.checkErrors();
 
+    if (DisplayDevice::DISPLAY_PRIMARY == hw->getDisplayType() &&
+                hw->isPanelInverseMounted()) {
+        rotation = (Transform::orientation_flags)
+                (rotation ^ Transform::ROT_180);
+    }
+
     // set-up our viewport
     engine.setViewportAndProjection(
         reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);