Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1925963 authored by Peiyong Lin's avatar Peiyong Lin
Browse files

[Rounded Corners] Take display rotation into account.

Previously when we applied glScissor on the layer, we always assume after the
transformation, the layer already had the aligned coordinates. However, we
still need to take rotation into account such that the (left, top) and (right,
bottom) coordinates align with the display coordination space.

BUG: 129619488
Test: Build, flash and boot. Verify with different rotation.
Change-Id: I6db6d5465af3e1961477960d9cba5c7331fa1ba1
parent 945a7006
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -743,6 +743,9 @@ void GLESRenderEngine::handleRoundedCorners(const DisplaySettings& display,
    // 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);
@@ -750,8 +753,28 @@ void GLESRenderEngine::handleRoundedCorners(const DisplaySettings& display,
    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);
+4 −0
Original line number Diff line number Diff line
@@ -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 @@ struct DisplaySettings {
    // 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
+1 −0
Original line number Diff line number Diff line
@@ -3327,6 +3327,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice,
        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;