diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 13d44f39b..baff5ba59 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -90,6 +90,7 @@ DisplayDevice::DisplayDevice( { mNativeWindow = new Surface(producer, false); ANativeWindow* const window = mNativeWindow.get(); + char property[PROPERTY_VALUE_MAX]; /* * Create our display's surface @@ -140,6 +141,11 @@ DisplayDevice::DisplayDevice( break; } + 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(DisplayState::eOrientationDefault, mViewport, mFrame); } @@ -402,6 +408,11 @@ status_t DisplayDevice::orientationToTransfrom( 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 8695a44ec..f492a427a 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -126,6 +126,10 @@ public: int32_t getHwcDisplayId() const { return mHwcDisplayId; } const wp& 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; @@ -209,7 +213,7 @@ private: /* * Transaction state */ - static status_t orientationToTransfrom(int orientation, + status_t orientationToTransfrom(int orientation, int w, int h, Transform* tr); uint32_t mLayerStack; @@ -226,6 +230,8 @@ private: 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 3b4330d15..c5e50e88c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3306,6 +3306,12 @@ void SurfaceFlinger::renderScreenImplLocked( // 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); @@ -3508,8 +3514,16 @@ bool SurfaceFlinger::updateLayerVisibleNonTransparentRegion(const int& /*dpy*/, const Layer::State& s(layer->getDrawingState()); // only consider the layers on the given layer stack - if (s.layerStack != layerStack) + if (s.layerStack != layerStack) { + /* set the visible region as empty since we have removed the + * layerstack check in rebuildLayerStack() function + */ + Region visibleNonTransRegion; + visibleNonTransRegion.set(Rect(0,0)); + layer->setVisibleNonTransparentRegion(visibleNonTransRegion); + return true; + } return false; }