Ignore local transforms when mirroring a partial hierarchy
When mirroring a partial hierarchy remove the local transform
on the mirrored root. This is necessary because we are placing
the mirrored root under a new parent layer and its original
position relative to the old parent is no longer relevant. This
fixes offsets when mirroring a freeform window.
Flag: com.android.graphics.surfaceflinger.flags.detached_mirror
Fixes: 337845753
Test: atest libsurfaceflinger_unittest
Change-Id: I0453026217f62868a4f6d1362cdc8187baf3f9b0
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index ae9a89c..7c6cff0 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -1302,4 +1302,33 @@
EXPECT_EQ(getSnapshot(1221)->inputInfo.canOccludePresentation, true);
}
+TEST_F(LayerSnapshotTest, mirroredHierarchyIgnoresLocalTransform) {
+ SET_FLAG_FOR_TEST(flags::detached_mirror, true);
+ reparentLayer(12, UNASSIGNED_LAYER_ID);
+ setPosition(11, 2, 20);
+ setPosition(111, 20, 200);
+ mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
+ std::vector<uint32_t> expected = {1, 11, 111, 13, 14, 11, 111, 2};
+ UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
+
+ // mirror root has no position set
+ EXPECT_EQ(getSnapshot({.id = 11, .mirrorRootIds = 14u})->localTransform.tx(), 0);
+ EXPECT_EQ(getSnapshot({.id = 11, .mirrorRootIds = 14u})->localTransform.ty(), 0);
+ // original root still has a position
+ EXPECT_EQ(getSnapshot({.id = 11})->localTransform.tx(), 2);
+ EXPECT_EQ(getSnapshot({.id = 11})->localTransform.ty(), 20);
+
+ // mirror child still has the correct position
+ EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->localTransform.tx(), 20);
+ EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->localTransform.ty(), 200);
+ EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->geomLayerTransform.tx(), 20);
+ EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->geomLayerTransform.ty(), 200);
+
+ // original child still has the correct position including its parent's position
+ EXPECT_EQ(getSnapshot({.id = 111})->localTransform.tx(), 20);
+ EXPECT_EQ(getSnapshot({.id = 111})->localTransform.ty(), 200);
+ EXPECT_EQ(getSnapshot({.id = 111})->geomLayerTransform.tx(), 22);
+ EXPECT_EQ(getSnapshot({.id = 111})->geomLayerTransform.ty(), 220);
+}
+
} // namespace android::surfaceflinger::frontend