xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/tests/RelativeZ_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 
21 #include "LayerTransactionTest.h"
22 
23 namespace android {
24 
25 using android::hardware::graphics::common::V1_1::BufferUsage;
26 
27 ::testing::Environment* const binderEnv =
28         ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
29 
30 class RelativeZTest : public LayerTransactionTest {
31 protected:
SetUp()32     virtual void SetUp() {
33         LayerTransactionTest::SetUp();
34         ASSERT_EQ(NO_ERROR, mClient->initCheck());
35 
36         const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
37         ASSERT_FALSE(ids.empty());
38         const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
39         ASSERT_FALSE(display == nullptr);
40 
41         // Back layer
42         mBackgroundLayer = createColorLayer("Background layer", Color::RED);
43 
44         // Front layer
45         mForegroundLayer = createColorLayer("Foreground layer", Color::GREEN);
46 
47         asTransaction([&](Transaction& t) {
48             t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK);
49             t.setLayer(mBackgroundLayer, INT32_MAX - 2).show(mBackgroundLayer);
50             t.setLayer(mForegroundLayer, INT32_MAX - 1).show(mForegroundLayer);
51         });
52     }
53 
TearDown()54     virtual void TearDown() {
55         LayerTransactionTest::TearDown();
56         mBackgroundLayer = 0;
57         mForegroundLayer = 0;
58     }
59 
60     sp<SurfaceControl> mBackgroundLayer;
61     sp<SurfaceControl> mForegroundLayer;
62 };
63 
64 // When a layer is reparented offscreen, remove relative z order if the relative parent
65 // is still onscreen so that the layer is not drawn.
TEST_F(RelativeZTest,LayerRemoved)66 TEST_F(RelativeZTest, LayerRemoved) {
67     std::unique_ptr<ScreenCapture> sc;
68 
69     // Background layer (RED)
70     //   Child layer (WHITE) (relative to foregroud layer)
71     // Foregroud layer (GREEN)
72     sp<SurfaceControl> childLayer =
73             createColorLayer("Child layer", Color::BLUE, mBackgroundLayer.get());
74 
75     Transaction{}.setRelativeLayer(childLayer, mForegroundLayer, 1).show(childLayer).apply();
76 
77     {
78         // The childLayer should be in front of the FG control.
79         ScreenCapture::captureScreen(&sc);
80         sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
81     }
82 
83     // Background layer (RED)
84     // Foregroud layer (GREEN)
85     Transaction{}.reparent(childLayer, nullptr).apply();
86 
87     // Background layer (RED)
88     //   Child layer (WHITE)
89     // Foregroud layer (GREEN)
90     Transaction{}.reparent(childLayer, mBackgroundLayer).apply();
91 
92     {
93         // The relative z info for child layer should be reset, leaving FG control on top.
94         ScreenCapture::captureScreen(&sc);
95         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
96     }
97 }
98 
99 // When a layer is reparented offscreen, preseve relative z order if the relative parent
100 // is also offscreen. Regression test b/132613412
TEST_F(RelativeZTest,LayerRemovedOffscreenRelativeParent)101 TEST_F(RelativeZTest, LayerRemovedOffscreenRelativeParent) {
102     std::unique_ptr<ScreenCapture> sc;
103 
104     // Background layer (RED)
105     // Foregroud layer (GREEN)
106     //   child level 1 (WHITE)
107     //     child level 2a (BLUE)
108     //       child level 3 (GREEN) (relative to child level 2b)
109     //     child level 2b (BLACK)
110     sp<SurfaceControl> childLevel1 =
111             createColorLayer("child level 1", Color::WHITE, mForegroundLayer.get());
112     sp<SurfaceControl> childLevel2a =
113             createColorLayer("child level 2a", Color::BLUE, childLevel1.get());
114     sp<SurfaceControl> childLevel2b =
115             createColorLayer("child level 2b", Color::BLACK, childLevel1.get());
116     sp<SurfaceControl> childLevel3 =
117             createColorLayer("child level 3", Color::GREEN, childLevel2a.get());
118 
119     Transaction{}
120             .setRelativeLayer(childLevel3, childLevel2b, 1)
121             .show(childLevel2a)
122             .show(childLevel2b)
123             .show(childLevel3)
124             .apply();
125 
126     {
127         // The childLevel3 should be in front of childLevel2b.
128         ScreenCapture::captureScreen(&sc);
129         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
130     }
131 
132     // Background layer (RED)
133     // Foregroud layer (GREEN)
134     Transaction{}.reparent(childLevel1, nullptr).apply();
135 
136     // Background layer (RED)
137     // Foregroud layer (GREEN)
138     //   child level 1 (WHITE)
139     //     child level 2 back (BLUE)
140     //       child level 3 (GREEN) (relative to child level 2b)
141     //     child level 2 front (BLACK)
142     Transaction{}.reparent(childLevel1, mForegroundLayer).apply();
143 
144     {
145         // Nothing should change at this point since relative z info was preserved.
146         ScreenCapture::captureScreen(&sc);
147         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
148     }
149 }
150 
TEST_F(RelativeZTest,LayerAndRelativeRemoved)151 TEST_F(RelativeZTest, LayerAndRelativeRemoved) {
152     std::unique_ptr<ScreenCapture> sc;
153 
154     // Background layer (RED)
155     // Foregroud layer (GREEN)
156     //   Child layer (BLUE) (relative to relativeToLayer layer)
157     //   Relative layer (WHITE)
158     sp<SurfaceControl> childLayer =
159             createColorLayer("Child layer", Color::BLUE, mForegroundLayer.get());
160     sp<SurfaceControl> relativeToLayer =
161             createColorLayer("Relative layer", Color::WHITE, mForegroundLayer.get());
162 
163     Transaction{}
164             .setRelativeLayer(childLayer, relativeToLayer, 1)
165             .show(childLayer)
166             .show(relativeToLayer)
167             .apply();
168 
169     {
170         // The childLayer should be in front of relativeToLayer.
171         ScreenCapture::captureScreen(&sc);
172         sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
173     }
174 
175     // Remove layer that childLayer is relative to
176     // Background layer (RED)
177     // Foregroud layer (GREEN)
178     //   Child layer (BLUE) (relative to relativeToLayer layer)
179     Transaction{}.reparent(relativeToLayer, nullptr).apply();
180     relativeToLayer = 0;
181 
182     {
183         // The child layer is relative to an deleted layer so it won't be drawn.
184         ScreenCapture::captureScreen(&sc);
185         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
186     }
187 
188     // Background layer (RED)
189     // Foregroud layer (GREEN)
190     Transaction{}.reparent(childLayer, nullptr).apply();
191 
192     {
193         // The child layer is offscreen, so it won't be drawn.
194         ScreenCapture::captureScreen(&sc);
195         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
196     }
197 
198     // Background layer (RED)
199     // Foregroud layer (GREEN)
200     //   Child layer (BLUE)
201     Transaction{}.reparent(childLayer, mForegroundLayer).apply();
202 
203     {
204         // The relative z info for child layer should be reset, leaving the child layer on top.
205         ScreenCapture::captureScreen(&sc);
206         sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
207     }
208 }
209 
210 // Preserve the relative z order when a layer is reparented to a layer that's already offscreen
TEST_F(RelativeZTest,LayerWithRelativeReparentedToOffscreen)211 TEST_F(RelativeZTest, LayerWithRelativeReparentedToOffscreen) {
212     std::unique_ptr<ScreenCapture> sc;
213 
214     Color testLayerColor = {255, 100, 0, 255};
215 
216     // Background layer (RED)
217     // Foregroud layer (GREEN)
218     //   child level 1a (testLayerColor) (relative to child level 2b)
219     //   child level 1b (WHITE)
220     //     child level 2a (BLUE)
221     //     child level 2b (BLACK)
222     sp<SurfaceControl> childLevel1a =
223             createColorLayer("child level 1a", testLayerColor, mForegroundLayer.get());
224     sp<SurfaceControl> childLevel1b =
225             createColorLayer("child level 1b", Color::WHITE, mForegroundLayer.get());
226     sp<SurfaceControl> childLevel2a =
227             createColorLayer("child level 2a", Color::BLUE, childLevel1b.get());
228     sp<SurfaceControl> childLevel2b =
229             createColorLayer("child level 2b", Color::BLACK, childLevel1b.get());
230 
231     Transaction{}
232             .setRelativeLayer(childLevel1a, childLevel2b, 1)
233             .show(childLevel1a)
234             .show(childLevel1b)
235             .show(childLevel2a)
236             .show(childLevel2b)
237             .apply();
238 
239     {
240         // The childLevel1a should be in front of childLevel2b.
241         ScreenCapture::captureScreen(&sc);
242         sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), testLayerColor);
243     }
244 
245     // Background layer (RED)
246     // Foregroud layer (GREEN)
247     //   child level 1a (testLayerColor) (relative to child level 2b)
248     Transaction{}.reparent(childLevel1b, nullptr).apply();
249 
250     // // Background layer (RED)
251     // // Foregroud layer (GREEN)
252     Transaction{}.reparent(childLevel1a, childLevel2a).apply();
253 
254     {
255         // The childLevel1a and childLevel1b are no longer on screen
256         ScreenCapture::captureScreen(&sc);
257         sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::GREEN);
258     }
259 
260     // Background layer (RED)
261     // Foregroud layer (GREEN)
262     //   child level 1b (WHITE)
263     //     child level 2a (BLUE)
264     //       child level 1a (testLayerColor) (relative to child level 2b)
265     //     child level 2b (BLACK)
266     Transaction{}.reparent(childLevel1b, mForegroundLayer).apply();
267 
268     {
269         // Nothing should change at this point since relative z info was preserved.
270         ScreenCapture::captureScreen(&sc);
271         sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), testLayerColor);
272     }
273 }
274 } // namespace android
275 
276 // TODO(b/129481165): remove the #pragma below and fix conversion issues
277 #pragma clang diagnostic pop // ignored "-Wconversion"
278