Loading services/surfaceflinger/Layer.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1820,7 +1820,7 @@ bool Layer::reparent(const sp<IBinder>& newParentHandle) { onRemovedFromCurrentState(); } if (callSetTransactionFlags || attachChildren()) { if (attachChildren() || callSetTransactionFlags) { setTransactionFlags(eTransactionNeeded); } return true; Loading Loading @@ -1848,9 +1848,9 @@ bool Layer::attachChildren() { if (client != nullptr && parentClient != client) { if (child->mLayerDetached) { child->mLayerDetached = false; child->attachChildren(); changed = true; } changed |= child->attachChildren(); } } Loading services/surfaceflinger/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ cc_test { "CommonTypes_test.cpp", "Credentials_test.cpp", "DereferenceSurfaceControl_test.cpp", "DetachChildren_test.cpp", "DisplayConfigs_test.cpp", "EffectLayer_test.cpp", "InvalidHandles_test.cpp", Loading services/surfaceflinger/tests/DetachChildren_test.cpp 0 → 100644 +322 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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. */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" #include "LayerTransactionTest.h" namespace android { class DetachChildren : public LayerTransactionTest { protected: virtual void SetUp() { LayerTransactionTest::SetUp(); mMainSurface = createLayer(String8("Main Test Surface"), mMainSurfaceBounds.width(), mMainSurfaceBounds.height(), 0, mBlackBgSurface.get()); ASSERT_TRUE(mMainSurface != nullptr); ASSERT_TRUE(mMainSurface->isValid()); TransactionUtils::fillSurfaceRGBA8(mMainSurface, mMainSurfaceColor); asTransaction([&](Transaction& t) { t.setLayer(mMainSurface, INT32_MAX - 1) .setPosition(mMainSurface, mMainSurfaceBounds.left, mMainSurfaceBounds.top) .show(mMainSurface); }); } virtual void TearDown() { LayerTransactionTest::TearDown(); mMainSurface = 0; } sp<SurfaceControl> mMainSurface; Color mMainSurfaceColor = {195, 63, 63, 255}; Rect mMainSurfaceBounds = Rect(64, 64, 128, 128); std::unique_ptr<ScreenCapture> mCapture; }; TEST_F(DetachChildren, RelativesAreNotDetached) { Color relativeColor = {10, 10, 10, 255}; Rect relBounds = Rect(64, 64, 74, 74); sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), relBounds.width(), relBounds.height(), 0); TransactionUtils::fillSurfaceRGBA8(relative, relativeColor); Transaction{} .setRelativeLayer(relative, mMainSurface->getHandle(), 1) .setPosition(relative, relBounds.left, relBounds.top) .apply(); { // The relative should be on top of the FG control. mCapture = screenshot(); mCapture->expectColor(relBounds, relativeColor); } Transaction{}.detachChildren(mMainSurface).apply(); { // Nothing should change at this point. mCapture = screenshot(); mCapture->expectColor(relBounds, relativeColor); } Transaction{}.hide(relative).apply(); { // Ensure that the relative was actually hidden, rather than // being left in the detached but visible state. mCapture = screenshot(); mCapture->expectColor(mMainSurfaceBounds, mMainSurfaceColor); } } TEST_F(DetachChildren, DetachChildrenSameClient) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceControl> child = createLayer(String8("Child surface"), childBounds.width(), childBounds.height(), 0, mMainSurface.get()); ASSERT_TRUE(child->isValid()); TransactionUtils::fillSurfaceRGBA8(child, childColor); asTransaction([&](Transaction& t) { t.show(child); t.setPosition(child, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top); }); { mCapture = screenshot(); // Expect main color around the child surface mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } asTransaction([&](Transaction& t) { t.detachChildren(mMainSurface); }); asTransaction([&](Transaction& t) { t.hide(child); }); // Since the child has the same client as the parent, it will not get // detached and will be hidden. { mCapture = screenshot(); mCapture->expectColor(mMainSurfaceBounds, mMainSurfaceColor); } } TEST_F(DetachChildren, DetachChildrenDifferentClient) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); asTransaction([&](Transaction& t) { t.show(childNewClient); t.setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top); }); { mCapture = screenshot(); // Expect main color around the child surface mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } asTransaction([&](Transaction& t) { t.detachChildren(mMainSurface); }); asTransaction([&](Transaction& t) { t.hide(childNewClient); }); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } } TEST_F(DetachChildren, DetachChildrenThenAttach) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); Transaction() .show(childNewClient) .setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top) .apply(); { mCapture = screenshot(); // Expect main color around the child surface mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } Transaction().detachChildren(mMainSurface).apply(); Transaction().hide(childNewClient).apply(); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } Color newParentColor = Color::RED; Rect newParentBounds = Rect(20, 20, 52, 52); sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), newParentBounds.width(), newParentBounds.height(), 0); TransactionUtils::fillSurfaceRGBA8(newParentSurface, newParentColor); Transaction() .setLayer(newParentSurface, INT32_MAX - 1) .show(newParentSurface) .setPosition(newParentSurface, newParentBounds.left, newParentBounds.top) .reparent(childNewClient, newParentSurface->getHandle()) .apply(); { mCapture = screenshot(); // Child is now hidden. mCapture->expectColor(newParentBounds, newParentColor); } } TEST_F(DetachChildren, DetachChildrenWithDeferredTransaction) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); Transaction() .show(childNewClient) .setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top) .apply(); { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } Transaction() .deferTransactionUntil_legacy(childNewClient, mMainSurface->getHandle(), mMainSurface->getSurface()->getNextFrameNumber()) .apply(); Transaction().detachChildren(mMainSurface).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mMainSurface, Color::RED, mMainSurfaceBounds.width(), mMainSurfaceBounds.height())); // BufferLayer can still dequeue buffers even though there's a detached layer with a // deferred transaction. { SCOPED_TRACE("new buffer"); mCapture = screenshot(); mCapture->expectBorder(childBounds, Color::RED); mCapture->expectColor(childBounds, childColor); } } TEST_F(DetachChildren, ReparentParentLayerOfDetachedChildren) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 94, 94); Color grandchildColor = Color::RED; Rect grandchildBounds = Rect(80, 80, 90, 90); sp<SurfaceComposerClient> newClient1 = new SurfaceComposerClient; sp<SurfaceComposerClient> newClient2 = new SurfaceComposerClient; sp<SurfaceControl> childSurface = createSurface(newClient1, "Child surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); sp<SurfaceControl> grandchildSurface = createSurface(newClient2, "Grandchild Surface", grandchildBounds.width(), grandchildBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, childSurface.get()); TransactionUtils::fillSurfaceRGBA8(childSurface, childColor); TransactionUtils::fillSurfaceRGBA8(grandchildSurface, grandchildColor); Transaction() .show(childSurface) .show(grandchildSurface) .setPosition(childSurface, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top) .setPosition(grandchildSurface, grandchildBounds.left - childBounds.left, grandchildBounds.top - childBounds.top) .apply(); { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectBorder(grandchildBounds, childColor); mCapture->expectColor(grandchildBounds, grandchildColor); } Transaction().detachChildren(childSurface).apply(); // Remove main surface offscreen Transaction().reparent(mMainSurface, nullptr).apply(); { mCapture = screenshot(); mCapture->expectColor(mMainSurfaceBounds, Color::BLACK); } Transaction().reparent(mMainSurface, mBlackBgSurface->getHandle()).apply(); { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectBorder(grandchildBounds, childColor); mCapture->expectColor(grandchildBounds, grandchildColor); } Transaction().hide(grandchildSurface).apply(); // grandchild is still detached so it will not hide { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectBorder(grandchildBounds, childColor); mCapture->expectColor(grandchildBounds, grandchildColor); } } } // namespace android No newline at end of file services/surfaceflinger/tests/LayerUpdate_test.cpp +0 −203 Original line number Diff line number Diff line Loading @@ -103,41 +103,6 @@ protected: sp<SurfaceControl> mSyncSurfaceControl; }; TEST_F(LayerUpdateTest, RelativesAreNotDetached) { std::unique_ptr<ScreenCapture> sc; sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), 10, 10, 0); TransactionUtils::fillSurfaceRGBA8(relative, 10, 10, 10); waitForPostedBuffers(); Transaction{} .setRelativeLayer(relative, mFGSurfaceControl->getHandle(), 1) .setPosition(relative, 64, 64) .apply(); { // The relative should be on top of the FG control. ScreenCapture::captureScreen(&sc); sc->checkPixel(64, 64, 10, 10, 10); } Transaction{}.detachChildren(mFGSurfaceControl).apply(); { // Nothing should change at this point. ScreenCapture::captureScreen(&sc); sc->checkPixel(64, 64, 10, 10, 10); } Transaction{}.hide(relative).apply(); { // Ensure that the relative was actually hidden, rather than // being left in the detached but visible state. ScreenCapture::captureScreen(&sc); sc->expectFGColor(64, 64); } } class GeometryLatchingTest : public LayerUpdateTest { protected: void EXPECT_INITIAL_STATE(const char* trace) { Loading Loading @@ -588,174 +553,6 @@ TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) { } } TEST_F(ChildLayerTest, DetachChildrenSameClient) { asTransaction([&](Transaction& t) { t.show(mChild); t.setPosition(mChild, 10, 10); t.setPosition(mFGSurfaceControl, 64, 64); }); { mCapture = screenshot(); // Top left of foreground must now be visible mCapture->expectFGColor(64, 64); // But 10 pixels in we should see the child surface mCapture->expectChildColor(74, 74); // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); }); asTransaction([&](Transaction& t) { t.hide(mChild); }); // Since the child has the same client as the parent, it will not get // detached and will be hidden. { mCapture = screenshot(); mCapture->expectFGColor(64, 64); mCapture->expectFGColor(74, 74); mCapture->expectFGColor(84, 84); } } TEST_F(ChildLayerTest, DetachChildrenDifferentClient) { sp<SurfaceComposerClient> mNewComposerClient = new SurfaceComposerClient; sp<SurfaceControl> mChildNewClient = createSurface(mNewComposerClient, "New Child Test Surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(mChildNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(mChildNewClient, 200, 200, 200); asTransaction([&](Transaction& t) { t.hide(mChild); t.show(mChildNewClient); t.setPosition(mChildNewClient, 10, 10); t.setPosition(mFGSurfaceControl, 64, 64); }); { mCapture = screenshot(); // Top left of foreground must now be visible mCapture->expectFGColor(64, 64); // But 10 pixels in we should see the child surface mCapture->expectChildColor(74, 74); // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); }); asTransaction([&](Transaction& t) { t.hide(mChildNewClient); }); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectFGColor(64, 64); mCapture->expectChildColor(74, 74); mCapture->expectFGColor(84, 84); } } TEST_F(ChildLayerTest, DetachChildrenThenAttach) { sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(childNewClient != nullptr); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200); Transaction() .hide(mChild) .show(childNewClient) .setPosition(childNewClient, 10, 10) .setPosition(mFGSurfaceControl, 64, 64) .apply(); { mCapture = screenshot(); // Top left of foreground must now be visible mCapture->expectFGColor(64, 64); // But 10 pixels in we should see the child surface mCapture->expectChildColor(74, 74); // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } Transaction().detachChildren(mFGSurfaceControl).apply(); Transaction().hide(childNewClient).apply(); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectFGColor(64, 64); mCapture->expectChildColor(74, 74); mCapture->expectFGColor(84, 84); } sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), 32, 32, 0); fillLayerColor(ISurfaceComposerClient::eFXSurfaceBufferQueue, newParentSurface, Color::RED, 32, 32); Transaction() .setLayer(newParentSurface, INT32_MAX - 1) .show(newParentSurface) .setPosition(newParentSurface, 20, 20) .reparent(childNewClient, newParentSurface->getHandle()) .apply(); { mCapture = screenshot(); // Child is now hidden. mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED); } } TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) { sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(childNewClient != nullptr); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200); Transaction() .hide(mChild) .show(childNewClient) .setPosition(childNewClient, 10, 10) .setPosition(mFGSurfaceControl, 64, 64) .apply(); { mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color{195, 63, 63, 255}); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } Transaction() .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(), mFGSurfaceControl->getSurface()->getNextFrameNumber()) .apply(); Transaction().detachChildren(mFGSurfaceControl).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32)); // BufferLayer can still dequeue buffers even though there's a detached layer with a // deferred transaction. { SCOPED_TRACE("new buffer"); mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color::RED); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } } TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) { asTransaction([&](Transaction& t) { t.show(mChild); Loading Loading
services/surfaceflinger/Layer.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1820,7 +1820,7 @@ bool Layer::reparent(const sp<IBinder>& newParentHandle) { onRemovedFromCurrentState(); } if (callSetTransactionFlags || attachChildren()) { if (attachChildren() || callSetTransactionFlags) { setTransactionFlags(eTransactionNeeded); } return true; Loading Loading @@ -1848,9 +1848,9 @@ bool Layer::attachChildren() { if (client != nullptr && parentClient != client) { if (child->mLayerDetached) { child->mLayerDetached = false; child->attachChildren(); changed = true; } changed |= child->attachChildren(); } } Loading
services/surfaceflinger/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ cc_test { "CommonTypes_test.cpp", "Credentials_test.cpp", "DereferenceSurfaceControl_test.cpp", "DetachChildren_test.cpp", "DisplayConfigs_test.cpp", "EffectLayer_test.cpp", "InvalidHandles_test.cpp", Loading
services/surfaceflinger/tests/DetachChildren_test.cpp 0 → 100644 +322 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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. */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" #include "LayerTransactionTest.h" namespace android { class DetachChildren : public LayerTransactionTest { protected: virtual void SetUp() { LayerTransactionTest::SetUp(); mMainSurface = createLayer(String8("Main Test Surface"), mMainSurfaceBounds.width(), mMainSurfaceBounds.height(), 0, mBlackBgSurface.get()); ASSERT_TRUE(mMainSurface != nullptr); ASSERT_TRUE(mMainSurface->isValid()); TransactionUtils::fillSurfaceRGBA8(mMainSurface, mMainSurfaceColor); asTransaction([&](Transaction& t) { t.setLayer(mMainSurface, INT32_MAX - 1) .setPosition(mMainSurface, mMainSurfaceBounds.left, mMainSurfaceBounds.top) .show(mMainSurface); }); } virtual void TearDown() { LayerTransactionTest::TearDown(); mMainSurface = 0; } sp<SurfaceControl> mMainSurface; Color mMainSurfaceColor = {195, 63, 63, 255}; Rect mMainSurfaceBounds = Rect(64, 64, 128, 128); std::unique_ptr<ScreenCapture> mCapture; }; TEST_F(DetachChildren, RelativesAreNotDetached) { Color relativeColor = {10, 10, 10, 255}; Rect relBounds = Rect(64, 64, 74, 74); sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), relBounds.width(), relBounds.height(), 0); TransactionUtils::fillSurfaceRGBA8(relative, relativeColor); Transaction{} .setRelativeLayer(relative, mMainSurface->getHandle(), 1) .setPosition(relative, relBounds.left, relBounds.top) .apply(); { // The relative should be on top of the FG control. mCapture = screenshot(); mCapture->expectColor(relBounds, relativeColor); } Transaction{}.detachChildren(mMainSurface).apply(); { // Nothing should change at this point. mCapture = screenshot(); mCapture->expectColor(relBounds, relativeColor); } Transaction{}.hide(relative).apply(); { // Ensure that the relative was actually hidden, rather than // being left in the detached but visible state. mCapture = screenshot(); mCapture->expectColor(mMainSurfaceBounds, mMainSurfaceColor); } } TEST_F(DetachChildren, DetachChildrenSameClient) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceControl> child = createLayer(String8("Child surface"), childBounds.width(), childBounds.height(), 0, mMainSurface.get()); ASSERT_TRUE(child->isValid()); TransactionUtils::fillSurfaceRGBA8(child, childColor); asTransaction([&](Transaction& t) { t.show(child); t.setPosition(child, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top); }); { mCapture = screenshot(); // Expect main color around the child surface mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } asTransaction([&](Transaction& t) { t.detachChildren(mMainSurface); }); asTransaction([&](Transaction& t) { t.hide(child); }); // Since the child has the same client as the parent, it will not get // detached and will be hidden. { mCapture = screenshot(); mCapture->expectColor(mMainSurfaceBounds, mMainSurfaceColor); } } TEST_F(DetachChildren, DetachChildrenDifferentClient) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); asTransaction([&](Transaction& t) { t.show(childNewClient); t.setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top); }); { mCapture = screenshot(); // Expect main color around the child surface mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } asTransaction([&](Transaction& t) { t.detachChildren(mMainSurface); }); asTransaction([&](Transaction& t) { t.hide(childNewClient); }); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } } TEST_F(DetachChildren, DetachChildrenThenAttach) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); Transaction() .show(childNewClient) .setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top) .apply(); { mCapture = screenshot(); // Expect main color around the child surface mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } Transaction().detachChildren(mMainSurface).apply(); Transaction().hide(childNewClient).apply(); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } Color newParentColor = Color::RED; Rect newParentBounds = Rect(20, 20, 52, 52); sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), newParentBounds.width(), newParentBounds.height(), 0); TransactionUtils::fillSurfaceRGBA8(newParentSurface, newParentColor); Transaction() .setLayer(newParentSurface, INT32_MAX - 1) .show(newParentSurface) .setPosition(newParentSurface, newParentBounds.left, newParentBounds.top) .reparent(childNewClient, newParentSurface->getHandle()) .apply(); { mCapture = screenshot(); // Child is now hidden. mCapture->expectColor(newParentBounds, newParentColor); } } TEST_F(DetachChildren, DetachChildrenWithDeferredTransaction) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 84, 84); sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); Transaction() .show(childNewClient) .setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top) .apply(); { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectColor(childBounds, childColor); } Transaction() .deferTransactionUntil_legacy(childNewClient, mMainSurface->getHandle(), mMainSurface->getSurface()->getNextFrameNumber()) .apply(); Transaction().detachChildren(mMainSurface).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mMainSurface, Color::RED, mMainSurfaceBounds.width(), mMainSurfaceBounds.height())); // BufferLayer can still dequeue buffers even though there's a detached layer with a // deferred transaction. { SCOPED_TRACE("new buffer"); mCapture = screenshot(); mCapture->expectBorder(childBounds, Color::RED); mCapture->expectColor(childBounds, childColor); } } TEST_F(DetachChildren, ReparentParentLayerOfDetachedChildren) { Color childColor = {200, 200, 200, 255}; Rect childBounds = Rect(74, 74, 94, 94); Color grandchildColor = Color::RED; Rect grandchildBounds = Rect(80, 80, 90, 90); sp<SurfaceComposerClient> newClient1 = new SurfaceComposerClient; sp<SurfaceComposerClient> newClient2 = new SurfaceComposerClient; sp<SurfaceControl> childSurface = createSurface(newClient1, "Child surface", childBounds.width(), childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); sp<SurfaceControl> grandchildSurface = createSurface(newClient2, "Grandchild Surface", grandchildBounds.width(), grandchildBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, childSurface.get()); TransactionUtils::fillSurfaceRGBA8(childSurface, childColor); TransactionUtils::fillSurfaceRGBA8(grandchildSurface, grandchildColor); Transaction() .show(childSurface) .show(grandchildSurface) .setPosition(childSurface, childBounds.left - mMainSurfaceBounds.left, childBounds.top - mMainSurfaceBounds.top) .setPosition(grandchildSurface, grandchildBounds.left - childBounds.left, grandchildBounds.top - childBounds.top) .apply(); { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectBorder(grandchildBounds, childColor); mCapture->expectColor(grandchildBounds, grandchildColor); } Transaction().detachChildren(childSurface).apply(); // Remove main surface offscreen Transaction().reparent(mMainSurface, nullptr).apply(); { mCapture = screenshot(); mCapture->expectColor(mMainSurfaceBounds, Color::BLACK); } Transaction().reparent(mMainSurface, mBlackBgSurface->getHandle()).apply(); { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectBorder(grandchildBounds, childColor); mCapture->expectColor(grandchildBounds, grandchildColor); } Transaction().hide(grandchildSurface).apply(); // grandchild is still detached so it will not hide { mCapture = screenshot(); mCapture->expectBorder(childBounds, mMainSurfaceColor); mCapture->expectBorder(grandchildBounds, childColor); mCapture->expectColor(grandchildBounds, grandchildColor); } } } // namespace android No newline at end of file
services/surfaceflinger/tests/LayerUpdate_test.cpp +0 −203 Original line number Diff line number Diff line Loading @@ -103,41 +103,6 @@ protected: sp<SurfaceControl> mSyncSurfaceControl; }; TEST_F(LayerUpdateTest, RelativesAreNotDetached) { std::unique_ptr<ScreenCapture> sc; sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), 10, 10, 0); TransactionUtils::fillSurfaceRGBA8(relative, 10, 10, 10); waitForPostedBuffers(); Transaction{} .setRelativeLayer(relative, mFGSurfaceControl->getHandle(), 1) .setPosition(relative, 64, 64) .apply(); { // The relative should be on top of the FG control. ScreenCapture::captureScreen(&sc); sc->checkPixel(64, 64, 10, 10, 10); } Transaction{}.detachChildren(mFGSurfaceControl).apply(); { // Nothing should change at this point. ScreenCapture::captureScreen(&sc); sc->checkPixel(64, 64, 10, 10, 10); } Transaction{}.hide(relative).apply(); { // Ensure that the relative was actually hidden, rather than // being left in the detached but visible state. ScreenCapture::captureScreen(&sc); sc->expectFGColor(64, 64); } } class GeometryLatchingTest : public LayerUpdateTest { protected: void EXPECT_INITIAL_STATE(const char* trace) { Loading Loading @@ -588,174 +553,6 @@ TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) { } } TEST_F(ChildLayerTest, DetachChildrenSameClient) { asTransaction([&](Transaction& t) { t.show(mChild); t.setPosition(mChild, 10, 10); t.setPosition(mFGSurfaceControl, 64, 64); }); { mCapture = screenshot(); // Top left of foreground must now be visible mCapture->expectFGColor(64, 64); // But 10 pixels in we should see the child surface mCapture->expectChildColor(74, 74); // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); }); asTransaction([&](Transaction& t) { t.hide(mChild); }); // Since the child has the same client as the parent, it will not get // detached and will be hidden. { mCapture = screenshot(); mCapture->expectFGColor(64, 64); mCapture->expectFGColor(74, 74); mCapture->expectFGColor(84, 84); } } TEST_F(ChildLayerTest, DetachChildrenDifferentClient) { sp<SurfaceComposerClient> mNewComposerClient = new SurfaceComposerClient; sp<SurfaceControl> mChildNewClient = createSurface(mNewComposerClient, "New Child Test Surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(mChildNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(mChildNewClient, 200, 200, 200); asTransaction([&](Transaction& t) { t.hide(mChild); t.show(mChildNewClient); t.setPosition(mChildNewClient, 10, 10); t.setPosition(mFGSurfaceControl, 64, 64); }); { mCapture = screenshot(); // Top left of foreground must now be visible mCapture->expectFGColor(64, 64); // But 10 pixels in we should see the child surface mCapture->expectChildColor(74, 74); // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); }); asTransaction([&](Transaction& t) { t.hide(mChildNewClient); }); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectFGColor(64, 64); mCapture->expectChildColor(74, 74); mCapture->expectFGColor(84, 84); } } TEST_F(ChildLayerTest, DetachChildrenThenAttach) { sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(childNewClient != nullptr); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200); Transaction() .hide(mChild) .show(childNewClient) .setPosition(childNewClient, 10, 10) .setPosition(mFGSurfaceControl, 64, 64) .apply(); { mCapture = screenshot(); // Top left of foreground must now be visible mCapture->expectFGColor(64, 64); // But 10 pixels in we should see the child surface mCapture->expectChildColor(74, 74); // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } Transaction().detachChildren(mFGSurfaceControl).apply(); Transaction().hide(childNewClient).apply(); // Nothing should have changed. { mCapture = screenshot(); mCapture->expectFGColor(64, 64); mCapture->expectChildColor(74, 74); mCapture->expectFGColor(84, 84); } sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), 32, 32, 0); fillLayerColor(ISurfaceComposerClient::eFXSurfaceBufferQueue, newParentSurface, Color::RED, 32, 32); Transaction() .setLayer(newParentSurface, INT32_MAX - 1) .show(newParentSurface) .setPosition(newParentSurface, 20, 20) .reparent(childNewClient, newParentSurface->getHandle()) .apply(); { mCapture = screenshot(); // Child is now hidden. mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED); } } TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) { sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(childNewClient != nullptr); ASSERT_TRUE(childNewClient->isValid()); TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200); Transaction() .hide(mChild) .show(childNewClient) .setPosition(childNewClient, 10, 10) .setPosition(mFGSurfaceControl, 64, 64) .apply(); { mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color{195, 63, 63, 255}); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } Transaction() .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(), mFGSurfaceControl->getSurface()->getNextFrameNumber()) .apply(); Transaction().detachChildren(mFGSurfaceControl).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32)); // BufferLayer can still dequeue buffers even though there's a detached layer with a // deferred transaction. { SCOPED_TRACE("new buffer"); mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color::RED); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } } TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) { asTransaction([&](Transaction& t) { t.show(mChild); Loading