• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 display = SurfaceComposerClient::getInternalDisplayToken();
37         ASSERT_FALSE(display == nullptr);
38 
39         // Back layer
40         mBackgroundLayer = createColorLayer("Background layer", Color::RED);
41 
42         // Front layer
43         mForegroundLayer = createColorLayer("Foreground layer", Color::GREEN);
44 
45         asTransaction([&](Transaction& t) {
46             t.setDisplayLayerStack(display, 0);
47             t.setLayer(mBackgroundLayer, INT32_MAX - 2).show(mBackgroundLayer);
48             t.setLayer(mForegroundLayer, INT32_MAX - 1).show(mForegroundLayer);
49         });
50     }
51 
TearDown()52     virtual void TearDown() {
53         LayerTransactionTest::TearDown();
54         mBackgroundLayer = 0;
55         mForegroundLayer = 0;
56     }
57 
58     sp<SurfaceControl> mBackgroundLayer;
59     sp<SurfaceControl> mForegroundLayer;
60 };
61 
62 // When a layer is reparented offscreen, remove relative z order if the relative parent
63 // is still onscreen so that the layer is not drawn.
TEST_F(RelativeZTest,LayerRemoved)64 TEST_F(RelativeZTest, LayerRemoved) {
65     std::unique_ptr<ScreenCapture> sc;
66 
67     // Background layer (RED)
68     //   Child layer (WHITE) (relative to foregroud layer)
69     // Foregroud layer (GREEN)
70     sp<SurfaceControl> childLayer =
71             createColorLayer("Child layer", Color::BLUE, mBackgroundLayer.get());
72 
73     Transaction{}.setRelativeLayer(childLayer, mForegroundLayer, 1).show(childLayer).apply();
74 
75     {
76         // The childLayer should be in front of the FG control.
77         ScreenCapture::captureScreen(&sc);
78         sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
79     }
80 
81     // Background layer (RED)
82     // Foregroud layer (GREEN)
83     Transaction{}.reparent(childLayer, nullptr).apply();
84 
85     // Background layer (RED)
86     //   Child layer (WHITE)
87     // Foregroud layer (GREEN)
88     Transaction{}.reparent(childLayer, mBackgroundLayer).apply();
89 
90     {
91         // The relative z info for child layer should be reset, leaving FG control on top.
92         ScreenCapture::captureScreen(&sc);
93         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
94     }
95 }
96 
97 // When a layer is reparented offscreen, preseve relative z order if the relative parent
98 // is also offscreen. Regression test b/132613412
TEST_F(RelativeZTest,LayerRemovedOffscreenRelativeParent)99 TEST_F(RelativeZTest, LayerRemovedOffscreenRelativeParent) {
100     std::unique_ptr<ScreenCapture> sc;
101 
102     // Background layer (RED)
103     // Foregroud layer (GREEN)
104     //   child level 1 (WHITE)
105     //     child level 2a (BLUE)
106     //       child level 3 (GREEN) (relative to child level 2b)
107     //     child level 2b (BLACK)
108     sp<SurfaceControl> childLevel1 =
109             createColorLayer("child level 1", Color::WHITE, mForegroundLayer.get());
110     sp<SurfaceControl> childLevel2a =
111             createColorLayer("child level 2a", Color::BLUE, childLevel1.get());
112     sp<SurfaceControl> childLevel2b =
113             createColorLayer("child level 2b", Color::BLACK, childLevel1.get());
114     sp<SurfaceControl> childLevel3 =
115             createColorLayer("child level 3", Color::GREEN, childLevel2a.get());
116 
117     Transaction{}
118             .setRelativeLayer(childLevel3, childLevel2b, 1)
119             .show(childLevel2a)
120             .show(childLevel2b)
121             .show(childLevel3)
122             .apply();
123 
124     {
125         // The childLevel3 should be in front of childLevel2b.
126         ScreenCapture::captureScreen(&sc);
127         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
128     }
129 
130     // Background layer (RED)
131     // Foregroud layer (GREEN)
132     Transaction{}.reparent(childLevel1, nullptr).apply();
133 
134     // Background layer (RED)
135     // Foregroud layer (GREEN)
136     //   child level 1 (WHITE)
137     //     child level 2 back (BLUE)
138     //       child level 3 (GREEN) (relative to child level 2b)
139     //     child level 2 front (BLACK)
140     Transaction{}.reparent(childLevel1, mForegroundLayer).apply();
141 
142     {
143         // Nothing should change at this point since relative z info was preserved.
144         ScreenCapture::captureScreen(&sc);
145         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
146     }
147 }
148 
TEST_F(RelativeZTest,LayerAndRelativeRemoved)149 TEST_F(RelativeZTest, LayerAndRelativeRemoved) {
150     std::unique_ptr<ScreenCapture> sc;
151 
152     // Background layer (RED)
153     // Foregroud layer (GREEN)
154     //   Child layer (BLUE) (relative to relativeToLayer layer)
155     //   Relative layer (WHITE)
156     sp<SurfaceControl> childLayer =
157             createColorLayer("Child layer", Color::BLUE, mForegroundLayer.get());
158     sp<SurfaceControl> relativeToLayer =
159             createColorLayer("Relative layer", Color::WHITE, mForegroundLayer.get());
160 
161     Transaction{}
162             .setRelativeLayer(childLayer, relativeToLayer, 1)
163             .show(childLayer)
164             .show(relativeToLayer)
165             .apply();
166 
167     {
168         // The childLayer should be in front of relativeToLayer.
169         ScreenCapture::captureScreen(&sc);
170         sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
171     }
172 
173     // Remove layer that childLayer is relative to
174     // Background layer (RED)
175     // Foregroud layer (GREEN)
176     //   Child layer (BLUE) (relative to relativeToLayer layer)
177     Transaction{}.reparent(relativeToLayer, nullptr).apply();
178     relativeToLayer = 0;
179 
180     {
181         // The child layer is relative to an deleted layer so it won't be drawn.
182         ScreenCapture::captureScreen(&sc);
183         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
184     }
185 
186     // Background layer (RED)
187     // Foregroud layer (GREEN)
188     Transaction{}.reparent(childLayer, nullptr).apply();
189 
190     {
191         // The child layer is offscreen, so it won't be drawn.
192         ScreenCapture::captureScreen(&sc);
193         sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
194     }
195 
196     // Background layer (RED)
197     // Foregroud layer (GREEN)
198     //   Child layer (BLUE)
199     Transaction{}.reparent(childLayer, mForegroundLayer).apply();
200 
201     {
202         // The relative z info for child layer should be reset, leaving the child layer on top.
203         ScreenCapture::captureScreen(&sc);
204         sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
205     }
206 }
207 
208 // Preserve the relative z order when a layer is reparented to a layer that's already offscreen
TEST_F(RelativeZTest,LayerWithRelativeReparentedToOffscreen)209 TEST_F(RelativeZTest, LayerWithRelativeReparentedToOffscreen) {
210     std::unique_ptr<ScreenCapture> sc;
211 
212     Color testLayerColor = {255, 100, 0, 255};
213 
214     // Background layer (RED)
215     // Foregroud layer (GREEN)
216     //   child level 1a (testLayerColor) (relative to child level 2b)
217     //   child level 1b (WHITE)
218     //     child level 2a (BLUE)
219     //     child level 2b (BLACK)
220     sp<SurfaceControl> childLevel1a =
221             createColorLayer("child level 1a", testLayerColor, mForegroundLayer.get());
222     sp<SurfaceControl> childLevel1b =
223             createColorLayer("child level 1b", Color::WHITE, mForegroundLayer.get());
224     sp<SurfaceControl> childLevel2a =
225             createColorLayer("child level 2a", Color::BLUE, childLevel1b.get());
226     sp<SurfaceControl> childLevel2b =
227             createColorLayer("child level 2b", Color::BLACK, childLevel1b.get());
228 
229     Transaction{}
230             .setRelativeLayer(childLevel1a, childLevel2b, 1)
231             .show(childLevel1a)
232             .show(childLevel1b)
233             .show(childLevel2a)
234             .show(childLevel2b)
235             .apply();
236 
237     {
238         // The childLevel1a should be in front of childLevel2b.
239         ScreenCapture::captureScreen(&sc);
240         sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), testLayerColor);
241     }
242 
243     // Background layer (RED)
244     // Foregroud layer (GREEN)
245     //   child level 1a (testLayerColor) (relative to child level 2b)
246     Transaction{}.reparent(childLevel1b, nullptr).apply();
247 
248     // // Background layer (RED)
249     // // Foregroud layer (GREEN)
250     Transaction{}.reparent(childLevel1a, childLevel2a).apply();
251 
252     {
253         // The childLevel1a and childLevel1b are no longer on screen
254         ScreenCapture::captureScreen(&sc);
255         sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::GREEN);
256     }
257 
258     // Background layer (RED)
259     // Foregroud layer (GREEN)
260     //   child level 1b (WHITE)
261     //     child level 2a (BLUE)
262     //       child level 1a (testLayerColor) (relative to child level 2b)
263     //     child level 2b (BLACK)
264     Transaction{}.reparent(childLevel1b, mForegroundLayer).apply();
265 
266     {
267         // Nothing should change at this point since relative z info was preserved.
268         ScreenCapture::captureScreen(&sc);
269         sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), testLayerColor);
270     }
271 }
272 } // namespace android
273 
274 // TODO(b/129481165): remove the #pragma below and fix conversion issues
275 #pragma clang diagnostic pop // ignored "-Wconversion"
276