diff options
| -rw-r--r-- | libs/ui/include/ui/Size.h | 12 | ||||
| -rw-r--r-- | libs/ui/tests/Size_test.cpp | 32 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 30 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp | 50 |
4 files changed, 108 insertions, 16 deletions
diff --git a/libs/ui/include/ui/Size.h b/libs/ui/include/ui/Size.h index ecc192dcae..bdcbd569fc 100644 --- a/libs/ui/include/ui/Size.h +++ b/libs/ui/include/ui/Size.h @@ -23,6 +23,8 @@ #include <type_traits> #include <utility> +#include <ui/Rotation.h> + namespace android::ui { // A simple value type representing a two-dimensional size. @@ -61,6 +63,16 @@ struct Size { set(Size(w, h)); } + // Applies a rotation onto the size + void rotate(Rotation rotation) { + if (rotation == ROTATION_90 || rotation == ROTATION_270) { + transpose(); + } + } + + // Swaps the width and height, emulating a 90 degree rotation. + void transpose() { std::swap(width, height); } + // Sets the value to kInvalidSize void makeInvalid(); diff --git a/libs/ui/tests/Size_test.cpp b/libs/ui/tests/Size_test.cpp index acef47fb97..0a236e60e4 100644 --- a/libs/ui/tests/Size_test.cpp +++ b/libs/ui/tests/Size_test.cpp @@ -61,6 +61,38 @@ TEST(SizeTest, BasicLessThanComparison) { EXPECT_FALSE(Size(1, 1) < Size(1, 1)); } +TEST(SizeTest, Transpose) { + Size s(123, 456); + s.transpose(); + EXPECT_EQ(s, Size(456, 123)); +} + +TEST(SizeTest, Rotate) { + { + Size s(123, 456); + s.rotate(Rotation::Rotation0); + EXPECT_EQ(s, Size(123, 456)); + } + + { + Size s(123, 456); + s.rotate(Rotation::Rotation90); + EXPECT_EQ(s, Size(456, 123)); + } + + { + Size s(123, 456); + s.rotate(Rotation::Rotation180); + EXPECT_EQ(s, Size(123, 456)); + } + + { + Size s(123, 456); + s.rotate(Rotation::Rotation270); + EXPECT_EQ(s, Size(456, 123)); + } +} + TEST(SizeTest, ValidAndEmpty) { { Size s; 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 <gmock/gmock.h> #include <gtest/gtest.h> +#include <ui/Rotation.h> 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(); |