surfaceflinger: fix traverseLayersInDisplay
Ignore top-level relative layers in the loop since they are and
should be traversed by Layer::traverseInZOrder.
Test: SurfaceFlinger_test
Change-Id: Ibd82298257b057b564e4985686d40c10f618e1d9
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4c03112..ec2a459 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4762,7 +4762,8 @@
continue;
}
const Layer::State& state(layer->getDrawingState());
- if (state.z < minLayerZ || state.z > maxLayerZ) {
+ // relative layers are traversed in Layer::traverseInZOrder
+ if (state.zOrderRelativeOf != nullptr || state.z < minLayerZ || state.z > maxLayerZ) {
continue;
}
layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index ba34fe5..6ede562 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -702,6 +702,26 @@
}
}
+TEST_F(LayerTransactionTest, SetRelativeZNegative) {
+ sp<SurfaceControl> layerR;
+ sp<SurfaceControl> layerG;
+ sp<SurfaceControl> layerB;
+ ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED));
+ ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN));
+ ASSERT_NO_FATAL_FAILURE(layerB = createLayer("test B", 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE));
+
+ // layerR = mLayerZBase, layerG = layerR - 1, layerB = -2
+ Transaction().setRelativeLayer(layerG, layerR->getHandle(), -1).setLayer(layerB, -2).apply();
+
+ sp<ScreenCapture> screenshot;
+ // only layerB is in this range
+ ScreenCapture::captureScreen(&screenshot, -2, -1);
+ screenshot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
+}
+
TEST_F(LayerTransactionTest, SetRelativeZGroup) {
sp<SurfaceControl> layerR;
sp<SurfaceControl> layerG;