Loading services/surfaceflinger/SurfaceFlinger.cpp +13 −9 Original line number Diff line number Diff line Loading @@ -3957,15 +3957,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } if (what & layer_state_t::eReparent) { bool hadParent = layer->hasParent(); if (layer->reparent(s.parentHandleForChild)) { if (!hadParent) { mCurrentState.layersSortedByZ.remove(layer); } flags |= eTransactionNeeded|eTraversalNeeded; } } if (what & layer_state_t::eReparentChildren) { if (layer->reparentChildren(s.reparentHandle)) { flags |= eTransactionNeeded|eTraversalNeeded; Loading Loading @@ -4026,6 +4017,19 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTraversalNeeded; } } // This has to happen after we reparent children because when we reparent to null we remove // child layers from current state and remove its relative z. If the children are reparented in // the same transaction, then we have to make sure we reparent the children first so we do not // lose its relative z order. if (what & layer_state_t::eReparent) { bool hadParent = layer->hasParent(); if (layer->reparent(s.parentHandleForChild)) { if (!hadParent) { mCurrentState.layersSortedByZ.remove(layer); } flags |= eTransactionNeeded | eTraversalNeeded; } } std::vector<sp<CallbackHandle>> callbackHandles; if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!listenerCallbacks.empty())) { for (const auto& [listener, callbackIds] : listenerCallbacks) { Loading services/surfaceflinger/tests/Transaction_test.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -4686,6 +4686,34 @@ TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) { } } TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) { sp<SurfaceControl> mGrandChild = createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get()); fillSurfaceRGBA8(mGrandChild, 111, 111, 111); // draw grand child behind the foreground surface asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1); }); { SCOPED_TRACE("Child visible"); ScreenCapture::captureScreen(&mCapture); mCapture->checkPixel(64, 64, 200, 200, 200); } asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); t.reparentChildren(mChild, mFGSurfaceControl->getHandle()); }); { SCOPED_TRACE("foreground visible reparenting grandchild"); ScreenCapture::captureScreen(&mCapture); mCapture->checkPixel(64, 64, 195, 63, 63); } } TEST_F(ChildLayerTest, DetachChildrenSameClient) { asTransaction([&](Transaction& t) { t.show(mChild); Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +13 −9 Original line number Diff line number Diff line Loading @@ -3957,15 +3957,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } if (what & layer_state_t::eReparent) { bool hadParent = layer->hasParent(); if (layer->reparent(s.parentHandleForChild)) { if (!hadParent) { mCurrentState.layersSortedByZ.remove(layer); } flags |= eTransactionNeeded|eTraversalNeeded; } } if (what & layer_state_t::eReparentChildren) { if (layer->reparentChildren(s.reparentHandle)) { flags |= eTransactionNeeded|eTraversalNeeded; Loading Loading @@ -4026,6 +4017,19 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTraversalNeeded; } } // This has to happen after we reparent children because when we reparent to null we remove // child layers from current state and remove its relative z. If the children are reparented in // the same transaction, then we have to make sure we reparent the children first so we do not // lose its relative z order. if (what & layer_state_t::eReparent) { bool hadParent = layer->hasParent(); if (layer->reparent(s.parentHandleForChild)) { if (!hadParent) { mCurrentState.layersSortedByZ.remove(layer); } flags |= eTransactionNeeded | eTraversalNeeded; } } std::vector<sp<CallbackHandle>> callbackHandles; if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!listenerCallbacks.empty())) { for (const auto& [listener, callbackIds] : listenerCallbacks) { Loading
services/surfaceflinger/tests/Transaction_test.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -4686,6 +4686,34 @@ TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) { } } TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) { sp<SurfaceControl> mGrandChild = createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get()); fillSurfaceRGBA8(mGrandChild, 111, 111, 111); // draw grand child behind the foreground surface asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1); }); { SCOPED_TRACE("Child visible"); ScreenCapture::captureScreen(&mCapture); mCapture->checkPixel(64, 64, 200, 200, 200); } asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); t.reparentChildren(mChild, mFGSurfaceControl->getHandle()); }); { SCOPED_TRACE("foreground visible reparenting grandchild"); ScreenCapture::captureScreen(&mCapture); mCapture->checkPixel(64, 64, 195, 63, 63); } } TEST_F(ChildLayerTest, DetachChildrenSameClient) { asTransaction([&](Transaction& t) { t.show(mChild); Loading