Recalculate Transform type after obtaining an inverse Transform
When getting the inverse of a Transform, the type can change. For
example, the inverse of a ROT_90 transform is a ROT_270 transform. We
need to recalculate the type of the inverse Transform.
Bug: 200794735
Bug: 179274888
Test: atest Transform_test
Change-Id: I10c8613e34edf8e76a5692c01bc58ce7e498cf4b
diff --git a/libs/ui/Transform.cpp b/libs/ui/Transform.cpp
index cd68c1c..b34d906 100644
--- a/libs/ui/Transform.cpp
+++ b/libs/ui/Transform.cpp
@@ -396,6 +396,11 @@
result.mMatrix[1][0] = -b*idet;
result.mMatrix[1][1] = a*idet;
result.mType = mType;
+ if (getOrientation() & ROT_90) {
+ // Recalculate the type if there is a 90-degree rotation component, since the inverse
+ // of ROT_90 is ROT_270 and vice versa.
+ result.mType |= UNKNOWN_TYPE;
+ }
vec2 T(-x, -y);
T = result.transform(T);
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index a87740a..0ee15f2 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -27,28 +27,40 @@
name: "Region_test",
shared_libs: ["libui"],
srcs: ["Region_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
cc_test {
name: "colorspace_test",
shared_libs: ["libui"],
srcs: ["colorspace_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
cc_test {
name: "DisplayId_test",
shared_libs: ["libui"],
srcs: ["DisplayId_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
cc_test {
name: "FlattenableHelpers_test",
shared_libs: ["libui"],
srcs: ["FlattenableHelpers_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
cc_test {
@@ -68,7 +80,10 @@
"GraphicBufferAllocator_test.cpp",
"mock/MockGrallocAllocator.cpp",
],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
cc_test {
@@ -83,14 +98,20 @@
"libutils",
],
srcs: ["GraphicBuffer_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
// This test has a main method, and requires a separate binary to be built.
cc_test {
name: "GraphicBufferOverBinder_test",
srcs: ["GraphicBufferOverBinder_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
shared_libs: [
"libbinder",
"libgui",
@@ -105,7 +126,10 @@
test_suites: ["device-tests"],
shared_libs: ["libui"],
srcs: ["Rect_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
cc_test {
@@ -113,7 +137,10 @@
test_suites: ["device-tests"],
shared_libs: ["libui"],
srcs: ["Size_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
cc_test {
@@ -121,6 +148,18 @@
shared_libs: ["libui"],
static_libs: ["libgmock"],
srcs: ["MockFence_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
}
+cc_test {
+ name: "Transform_test",
+ shared_libs: ["libui"],
+ srcs: ["Transform_test.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+}
diff --git a/libs/ui/tests/Transform_test.cpp b/libs/ui/tests/Transform_test.cpp
new file mode 100644
index 0000000..6964284
--- /dev/null
+++ b/libs/ui/tests/Transform_test.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ui/Transform.h>
+
+#include <gtest/gtest.h>
+
+namespace android::ui {
+
+TEST(TransformTest, inverseRotation_hasCorrectType) {
+ const auto testRotationFlagsForInverse = [](Transform::RotationFlags rotation,
+ Transform::RotationFlags expectedInverse,
+ bool isRotation) {
+ const Transform t(rotation, 0, 0);
+ EXPECT_EQ(t.getOrientation(), rotation);
+ const Transform inverse = t.inverse();
+ EXPECT_EQ(inverse.getOrientation(), expectedInverse);
+
+ if (isRotation) {
+ EXPECT_TRUE(t.getType() & Transform::ROTATE);
+ EXPECT_TRUE(inverse.getType() & Transform::ROTATE);
+ } else {
+ EXPECT_FALSE(t.getType() & Transform::ROTATE);
+ EXPECT_FALSE(inverse.getType() & Transform::ROTATE);
+ }
+ };
+
+ testRotationFlagsForInverse(Transform::ROT_0, Transform::ROT_0, false);
+ testRotationFlagsForInverse(Transform::ROT_90, Transform::ROT_270, true);
+ testRotationFlagsForInverse(Transform::ROT_180, Transform::ROT_180, true);
+ testRotationFlagsForInverse(Transform::ROT_270, Transform::ROT_90, true);
+ testRotationFlagsForInverse(Transform::FLIP_H, Transform::FLIP_H, false);
+ testRotationFlagsForInverse(Transform::FLIP_V, Transform::FLIP_V, false);
+}
+
+} // namespace android::ui