Loading services/surfaceflinger/Layer.cpp +17 −4 Original line number Diff line number Diff line Loading @@ -1102,6 +1102,19 @@ bool Layer::setChildLayer(const sp<Layer>& childLayer, int32_t z) { return true; } bool Layer::setChildRelativeLayer(const sp<Layer>& childLayer, const sp<IBinder>& relativeToHandle, int32_t relativeZ) { ssize_t idx = mCurrentChildren.indexOf(childLayer); if (idx < 0) { return false; } if (childLayer->setRelativeLayer(relativeToHandle, relativeZ)) { mCurrentChildren.removeAt(idx); mCurrentChildren.add(childLayer); } return true; } bool Layer::setLayer(int32_t z) { if (mCurrentState.z == z) return false; mCurrentState.sequence++; Loading Loading @@ -1603,11 +1616,7 @@ __attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::mak const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren; const State& state = useDrawing ? mDrawingState : mCurrentState; if (state.zOrderRelatives.size() == 0) { return children; } LayerVector traverse; for (const wp<Layer>& weakRelative : state.zOrderRelatives) { sp<Layer> strongRelative = weakRelative.promote(); if (strongRelative != nullptr) { Loading @@ -1616,6 +1625,10 @@ __attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::mak } for (const sp<Layer>& child : children) { const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState; if (childState.zOrderRelativeOf != nullptr) { continue; } traverse.add(child); } Loading services/surfaceflinger/Layer.h +2 −0 Original line number Diff line number Diff line Loading @@ -482,6 +482,8 @@ public: bool hasParent() const { return getParent() != nullptr; } Rect computeScreenBounds(bool reduceTransparentRegion = true) const; bool setChildLayer(const sp<Layer>& childLayer, int32_t z); bool setChildRelativeLayer(const sp<Layer>& childLayer, const sp<IBinder>& relativeToHandle, int32_t relativeZ); // Copy the current list of children to the drawing state. Called by // SurfaceFlinger to complete a transaction. Loading services/surfaceflinger/SurfaceFlinger.cpp +15 −5 Original line number Diff line number Diff line Loading @@ -3143,12 +3143,22 @@ uint32_t SurfaceFlinger::setClientStateLocked( } } if (what & layer_state_t::eRelativeLayerChanged) { // NOTE: index needs to be calculated before we update the state const auto& p = layer->getParent(); if (p == nullptr) { ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); if (layer->setRelativeLayer(s.relativeLayerHandle, s.z)) { if (layer->setRelativeLayer(s.relativeLayerHandle, s.z) && idx >= 0) { mCurrentState.layersSortedByZ.removeAt(idx); mCurrentState.layersSortedByZ.add(layer); // we need traversal (state changed) // AND transaction (list changed) flags |= eTransactionNeeded|eTraversalNeeded; } } else { if (p->setChildRelativeLayer(layer, s.relativeLayerHandle, s.z)) { flags |= eTransactionNeeded|eTraversalNeeded; } } } if (what & layer_state_t::eSizeChanged) { if (layer->setSize(s.w, s.h)) { Loading services/surfaceflinger/tests/Transaction_test.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -1413,6 +1413,27 @@ TEST_F(ChildLayerTest, NestedChildren) { } } TEST_F(ChildLayerTest, ChildLayerRelativeLayer) { sp<SurfaceControl> relative = mComposerClient->createSurface(String8("Relative surface"), 128, 128, PIXEL_FORMAT_RGBA_8888, 0); fillSurfaceRGBA8(relative, 255, 255, 255); Transaction t; t.setLayer(relative, INT32_MAX) .setRelativeLayer(mChild, relative->getHandle(), 1) .setPosition(mFGSurfaceControl, 0, 0) .apply(true); // We expect that the child should have been elevated above our // INT_MAX layer even though it's not a child of it. { ScreenCapture::captureScreen(&mCapture); mCapture->expectChildColor(0, 0); mCapture->expectChildColor(9, 9); mCapture->checkPixel(10, 10, 255, 255, 255); } } class LayerColorTest : public LayerUpdateTest { protected: void SetUp() override { Loading Loading
services/surfaceflinger/Layer.cpp +17 −4 Original line number Diff line number Diff line Loading @@ -1102,6 +1102,19 @@ bool Layer::setChildLayer(const sp<Layer>& childLayer, int32_t z) { return true; } bool Layer::setChildRelativeLayer(const sp<Layer>& childLayer, const sp<IBinder>& relativeToHandle, int32_t relativeZ) { ssize_t idx = mCurrentChildren.indexOf(childLayer); if (idx < 0) { return false; } if (childLayer->setRelativeLayer(relativeToHandle, relativeZ)) { mCurrentChildren.removeAt(idx); mCurrentChildren.add(childLayer); } return true; } bool Layer::setLayer(int32_t z) { if (mCurrentState.z == z) return false; mCurrentState.sequence++; Loading Loading @@ -1603,11 +1616,7 @@ __attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::mak const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren; const State& state = useDrawing ? mDrawingState : mCurrentState; if (state.zOrderRelatives.size() == 0) { return children; } LayerVector traverse; for (const wp<Layer>& weakRelative : state.zOrderRelatives) { sp<Layer> strongRelative = weakRelative.promote(); if (strongRelative != nullptr) { Loading @@ -1616,6 +1625,10 @@ __attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::mak } for (const sp<Layer>& child : children) { const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState; if (childState.zOrderRelativeOf != nullptr) { continue; } traverse.add(child); } Loading
services/surfaceflinger/Layer.h +2 −0 Original line number Diff line number Diff line Loading @@ -482,6 +482,8 @@ public: bool hasParent() const { return getParent() != nullptr; } Rect computeScreenBounds(bool reduceTransparentRegion = true) const; bool setChildLayer(const sp<Layer>& childLayer, int32_t z); bool setChildRelativeLayer(const sp<Layer>& childLayer, const sp<IBinder>& relativeToHandle, int32_t relativeZ); // Copy the current list of children to the drawing state. Called by // SurfaceFlinger to complete a transaction. Loading
services/surfaceflinger/SurfaceFlinger.cpp +15 −5 Original line number Diff line number Diff line Loading @@ -3143,12 +3143,22 @@ uint32_t SurfaceFlinger::setClientStateLocked( } } if (what & layer_state_t::eRelativeLayerChanged) { // NOTE: index needs to be calculated before we update the state const auto& p = layer->getParent(); if (p == nullptr) { ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); if (layer->setRelativeLayer(s.relativeLayerHandle, s.z)) { if (layer->setRelativeLayer(s.relativeLayerHandle, s.z) && idx >= 0) { mCurrentState.layersSortedByZ.removeAt(idx); mCurrentState.layersSortedByZ.add(layer); // we need traversal (state changed) // AND transaction (list changed) flags |= eTransactionNeeded|eTraversalNeeded; } } else { if (p->setChildRelativeLayer(layer, s.relativeLayerHandle, s.z)) { flags |= eTransactionNeeded|eTraversalNeeded; } } } if (what & layer_state_t::eSizeChanged) { if (layer->setSize(s.w, s.h)) { Loading
services/surfaceflinger/tests/Transaction_test.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -1413,6 +1413,27 @@ TEST_F(ChildLayerTest, NestedChildren) { } } TEST_F(ChildLayerTest, ChildLayerRelativeLayer) { sp<SurfaceControl> relative = mComposerClient->createSurface(String8("Relative surface"), 128, 128, PIXEL_FORMAT_RGBA_8888, 0); fillSurfaceRGBA8(relative, 255, 255, 255); Transaction t; t.setLayer(relative, INT32_MAX) .setRelativeLayer(mChild, relative->getHandle(), 1) .setPosition(mFGSurfaceControl, 0, 0) .apply(true); // We expect that the child should have been elevated above our // INT_MAX layer even though it's not a child of it. { ScreenCapture::captureScreen(&mCapture); mCapture->expectChildColor(0, 0); mCapture->expectChildColor(9, 9); mCapture->checkPixel(10, 10, 255, 255, 255); } } class LayerColorTest : public LayerUpdateTest { protected: void SetUp() override { Loading