From 168f6ccfce328a1224297ba5b7af2779fcee0d9a Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 7 Apr 2022 20:58:00 +0000 Subject: Set better defaults for layer stack and oriented display space When the device is not logically rotated and there is a 90 degree or 270 degree physical installation, then the content rectangle and bounds of the layer stack space and the oriented display space must be consistent with the framebuffer space and un-oriented display space. That is, if the framebuffer space and un-oriented display space are in portrait, then the layer stack space and the oriented display space should be in landscape without any cropping effects. Prior to this patch, devices with a rotated physical install orientation would have its boot animation cropped due to the mismatch in the logical display space and physical display space Bug: 203165976 Test: boot animation is not cropped Change-Id: I965b6c0578e982fe1b2a4dbdb18c24b5922388a9 --- services/surfaceflinger/DisplayDevice.cpp | 30 ++++++------- .../unittests/DisplayDevice_SetProjectionTest.cpp | 50 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 16 deletions(-) (limited to 'services/surfaceflinger') diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 3651c8b07f..65e7a7f79e 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -299,26 +299,24 @@ void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpace sPrimaryDisplayRotationFlags = ui::Transform::toRotationFlags(orientation); } + // We need to take care of display rotation for globalTransform for case if the panel is not + // installed aligned with device orientation. + const auto transformOrientation = orientation + mPhysicalOrientation; + + const auto& state = getCompositionDisplay()->getState(); + + // If the layer stack and destination frames have never been set, then configure them to be the + // same as the physical device, taking into account the total transform. if (!orientedDisplaySpaceRect.isValid()) { - // The destination frame can be invalid if it has never been set, - // in that case we assume the whole display size. - orientedDisplaySpaceRect = - getCompositionDisplay()->getState().displaySpace.getBoundsAsRect(); + ui::Size bounds = state.displaySpace.getBounds(); + bounds.rotate(transformOrientation); + orientedDisplaySpaceRect = Rect(bounds); } - if (layerStackSpaceRect.isEmpty()) { - // The layerStackSpaceRect can be invalid if it has never been set, in that case - // we assume the whole framebuffer size. - layerStackSpaceRect = - getCompositionDisplay()->getState().framebufferSpace.getBoundsAsRect(); - if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) { - std::swap(layerStackSpaceRect.right, layerStackSpaceRect.bottom); - } + ui::Size bounds = state.framebufferSpace.getBounds(); + bounds.rotate(transformOrientation); + layerStackSpaceRect = Rect(bounds); } - - // We need to take care of display rotation for globalTransform for case if the panel is not - // installed aligned with device orientation. - const auto transformOrientation = orientation + mPhysicalOrientation; getCompositionDisplay()->setProjection(transformOrientation, layerStackSpaceRect, orientedDisplaySpaceRect); } diff --git a/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp index 3d24ecbf71..5734d34f81 100644 --- a/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp @@ -21,6 +21,7 @@ #include #include +#include namespace android { namespace { @@ -53,6 +54,11 @@ public: ui::Size swapWH(const ui::Size size) const { return ui::Size(size.height, size.width); } + void setDefaultProjection() { + // INVALID_RECT pulls from the physical display dimensions. + mDisplayDevice->setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT); + } + void setProjectionForRotation0() { // A logical rotation of 0 uses the SurfaceFlinger display size mDisplayDevice->setProjection(ui::ROTATION_0, Rect(mFlingerDisplaySize), @@ -79,6 +85,30 @@ public: Rect(swapWH(mFlingerDisplaySize))); } + void expectDefaultState() { + const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState(); + EXPECT_EQ(ui::Transform(ui::Transform::toRotationFlags(mPhysicalOrientation), + mHardwareDisplaySize.width, mHardwareDisplaySize.height), + compositionState.transform); + EXPECT_EQ(mPhysicalOrientation, compositionState.displaySpace.getOrientation()); + EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.displaySpace.getContent()); + EXPECT_EQ(mHardwareDisplaySize, compositionState.displaySpace.getBounds()); + EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.framebufferSpace.getContent()); + EXPECT_EQ(mHardwareDisplaySize, compositionState.framebufferSpace.getBounds()); + + const ui::Size expectedLogicalSize = (mPhysicalOrientation == ui::ROTATION_270 || + mPhysicalOrientation == ui::ROTATION_90) + ? swapWH(mHardwareDisplaySize) + : mHardwareDisplaySize; + + EXPECT_EQ(Rect(expectedLogicalSize), compositionState.orientedDisplaySpace.getContent()); + EXPECT_EQ(expectedLogicalSize, compositionState.orientedDisplaySpace.getBounds()); + EXPECT_EQ(Rect(expectedLogicalSize), compositionState.layerStackSpace.getContent()); + EXPECT_EQ(expectedLogicalSize, compositionState.layerStackSpace.getBounds()); + + EXPECT_EQ(false, compositionState.needsFiltering); + } + void expectStateForHardwareTransform0() { const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState(); EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_0, mHardwareDisplaySize.width, @@ -147,6 +177,11 @@ struct DisplayDeviceSetProjectionTest_Installed0 : public DisplayDeviceSetProjec ui::ROTATION_0) {} }; +TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkDefaultProjection) { + setDefaultProjection(); + expectDefaultState(); +} + TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith0OutputRotation) { setProjectionForRotation0(); expectStateForHardwareTransform0(); @@ -174,6 +209,11 @@ struct DisplayDeviceSetProjectionTest_Installed90 : public DisplayDeviceSetProje ui::ROTATION_90) {} }; +TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkDefaultProjection) { + setDefaultProjection(); + expectDefaultState(); +} + TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith0OutputRotation) { setProjectionForRotation0(); expectStateForHardwareTransform90(); @@ -201,6 +241,11 @@ struct DisplayDeviceSetProjectionTest_Installed180 : public DisplayDeviceSetProj ui::ROTATION_180) {} }; +TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkDefaultProjection) { + setDefaultProjection(); + expectDefaultState(); +} + TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith0OutputRotation) { setProjectionForRotation0(); expectStateForHardwareTransform180(); @@ -228,6 +273,11 @@ struct DisplayDeviceSetProjectionTest_Installed270 : public DisplayDeviceSetProj ui::ROTATION_270) {} }; +TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkDefaultProjection) { + setDefaultProjection(); + expectDefaultState(); +} + TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith0OutputRotation) { setProjectionForRotation0(); expectStateForHardwareTransform270(); -- cgit v1.2.3-59-g8ed1b