Merge "[Rounded Corners] Take display rotation into account."
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index b595904..faf6d2a 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -744,6 +744,9 @@
     // We separate the layer into 3 parts essentially, such that we only turn on blending for the
     // top rectangle and the bottom rectangle, and turn off blending for the middle rectangle.
     FloatRect bounds = layer.geometry.roundedCornersCrop;
+
+    // Firstly, we need to convert the coordination from layer native coordination space to
+    // device coordination space.
     const auto transformMatrix = display.globalTransform * layer.geometry.positionTransform;
     const vec4 leftTopCoordinate(bounds.left, bounds.top, 1.0, 1.0);
     const vec4 rightBottomCoordinate(bounds.right, bounds.bottom, 1.0, 1.0);
@@ -751,8 +754,28 @@
     const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate;
     bounds = FloatRect(leftTopCoordinateInBuffer[0], leftTopCoordinateInBuffer[1],
                        rightBottomCoordinateInBuffer[0], rightBottomCoordinateInBuffer[1]);
-    const int32_t radius = ceil(layer.geometry.roundedCornersRadius);
 
+    // Secondly, if the display is rotated, we need to undo the rotation on coordination and
+    // align the (left, top) and (right, bottom) coordination with the device coordination
+    // space.
+    switch (display.orientation) {
+        case ui::Transform::ROT_90:
+            std::swap(bounds.left, bounds.right);
+            break;
+        case ui::Transform::ROT_180:
+            std::swap(bounds.left, bounds.right);
+            std::swap(bounds.top, bounds.bottom);
+            break;
+        case ui::Transform::ROT_270:
+            std::swap(bounds.top, bounds.bottom);
+            break;
+        default:
+            break;
+    }
+
+    // Finally, we cut the layer into 3 parts, with top and bottom parts having rounded corners
+    // and the middle part without rounded corners.
+    const int32_t radius = ceil(layer.geometry.roundedCornersRadius);
     const Rect topRect(bounds.left, bounds.top, bounds.right, bounds.top + radius);
     setScissor(topRect);
     drawMesh(mesh);
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index af8de23..9c9884a 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -20,6 +20,7 @@
 #include <ui/GraphicTypes.h>
 #include <ui/Rect.h>
 #include <ui/Region.h>
+#include <ui/Transform.h>
 
 namespace android {
 namespace renderengine {
@@ -56,6 +57,9 @@
     // globalTransform, so that it will be in the same coordinate space as the
     // rendered layers.
     Region clearRegion = Region::INVALID_REGION;
+
+    // The orientation of the physical display.
+    uint32_t orientation = ui::Transform::ROT_0;
 };
 
 } // namespace renderengine
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3ac81f3..2ba55b5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3295,6 +3295,7 @@
         clientCompositionDisplay.clip = displayState.scissor;
         const ui::Transform& displayTransform = displayState.transform;
         clientCompositionDisplay.globalTransform = displayTransform.asMatrix4();
+        clientCompositionDisplay.orientation = displayState.orientation;
 
         const auto* profile = display->getDisplayColorProfile();
         Dataspace outputDataspace = Dataspace::UNKNOWN;