blob: 867eddbc4465ef17979d3aa7c6f234daa825ce04 [file] [log] [blame]
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001/*
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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Valerie Hau9cfc6d82019-09-23 13:54:07 -070021#include "LayerTransactionTest.h"
22
23namespace android {
24
25using android::hardware::graphics::common::V1_1::BufferUsage;
26
27::testing::Environment* const binderEnv =
28 ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
29
30class LayerUpdateTest : public LayerTransactionTest {
31protected:
32 virtual void SetUp() {
33 LayerTransactionTest::SetUp();
34 ASSERT_EQ(NO_ERROR, mClient->initCheck());
35
Huihong Luo31b5ac22022-08-15 20:38:10 -070036 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
37 ASSERT_FALSE(ids.empty());
38 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hau9cfc6d82019-09-23 13:54:07 -070039 ASSERT_FALSE(display == nullptr);
40
Marin Shalamanova7fe3042021-01-29 21:02:08 +010041 ui::DisplayMode mode;
42 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
43 const ui::Size& resolution = mode.resolution;
Valerie Hau9cfc6d82019-09-23 13:54:07 -070044
45 // Background surface
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080046 mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
47 resolution.getHeight(), 0);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070048 ASSERT_TRUE(mBGSurfaceControl != nullptr);
49 ASSERT_TRUE(mBGSurfaceControl->isValid());
50 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
51
52 // Foreground surface
53 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
54
55 ASSERT_TRUE(mFGSurfaceControl != nullptr);
56 ASSERT_TRUE(mFGSurfaceControl->isValid());
57
58 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
59
60 // Synchronization surface
61 mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
62 ASSERT_TRUE(mSyncSurfaceControl != nullptr);
63 ASSERT_TRUE(mSyncSurfaceControl->isValid());
64
65 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
66
67 asTransaction([&](Transaction& t) {
Dominik Laskowski29fa1462021-04-27 15:51:50 -070068 t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070069
70 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
71
72 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
73 .setPosition(mFGSurfaceControl, 64, 64)
74 .show(mFGSurfaceControl);
75
76 t.setLayer(mSyncSurfaceControl, INT32_MAX - 1)
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080077 .setPosition(mSyncSurfaceControl, resolution.getWidth() - 2,
78 resolution.getHeight() - 2)
Valerie Hau9cfc6d82019-09-23 13:54:07 -070079 .show(mSyncSurfaceControl);
80 });
81 }
82
83 virtual void TearDown() {
84 LayerTransactionTest::TearDown();
85 mBGSurfaceControl = 0;
86 mFGSurfaceControl = 0;
87 mSyncSurfaceControl = 0;
88 }
89
90 void waitForPostedBuffers() {
91 // Since the sync surface is in synchronous mode (i.e. double buffered)
92 // posting three buffers to it should ensure that at least two
93 // SurfaceFlinger::handlePageFlip calls have been made, which should
94 // guaranteed that a buffer posted to another Surface has been retired.
95 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
96 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
97 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
98 }
99
100 sp<SurfaceControl> mBGSurfaceControl;
101 sp<SurfaceControl> mFGSurfaceControl;
102
103 // This surface is used to ensure that the buffers posted to
104 // mFGSurfaceControl have been picked up by SurfaceFlinger.
105 sp<SurfaceControl> mSyncSurfaceControl;
106};
107
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700108class GeometryLatchingTest : public LayerUpdateTest {
109protected:
110 void EXPECT_INITIAL_STATE(const char* trace) {
111 SCOPED_TRACE(trace);
112 ScreenCapture::captureScreen(&sc);
113 // We find the leading edge of the FG surface.
114 sc->expectFGColor(127, 127);
115 sc->expectBGColor(128, 128);
116 }
117
118 void lockAndFillFGBuffer() {
119 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false);
120 }
121
122 void unlockFGBuffer() {
123 sp<Surface> s = mFGSurfaceControl->getSurface();
124 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
125 waitForPostedBuffers();
126 }
127
128 void completeFGResize() {
129 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
130 waitForPostedBuffers();
131 }
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700132
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700133 std::unique_ptr<ScreenCapture> sc;
134};
135
136class CropLatchingTest : public GeometryLatchingTest {
137protected:
138 void EXPECT_CROPPED_STATE(const char* trace) {
139 SCOPED_TRACE(trace);
140 ScreenCapture::captureScreen(&sc);
141 // The edge should be moved back one pixel by our crop.
142 sc->expectFGColor(126, 126);
143 sc->expectBGColor(127, 127);
144 sc->expectBGColor(128, 128);
145 }
146
147 void EXPECT_RESIZE_STATE(const char* trace) {
148 SCOPED_TRACE(trace);
149 ScreenCapture::captureScreen(&sc);
150 // The FG is now resized too 128,128 at 64,64
151 sc->expectFGColor(64, 64);
152 sc->expectFGColor(191, 191);
153 sc->expectBGColor(192, 192);
154 }
155};
156
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700157TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
158 std::unique_ptr<ScreenCapture> sc;
159
160 sp<SurfaceControl> childNoBuffer =
161 createSurface(mClient, "Bufferless child", 0 /* buffer width */, 0 /* buffer height */,
162 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
163 sp<SurfaceControl> childBuffer = createSurface(mClient, "Buffered child", 20, 20,
164 PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
165 TransactionUtils::fillSurfaceRGBA8(childBuffer, 200, 200, 200);
166 SurfaceComposerClient::Transaction{}
chaviw25714502021-02-11 10:01:08 -0800167 .setCrop(childNoBuffer, Rect(0, 0, 10, 10))
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700168 .show(childNoBuffer)
169 .show(childBuffer)
170 .apply(true);
171 {
172 ScreenCapture::captureScreen(&sc);
173 sc->expectChildColor(73, 73);
174 sc->expectFGColor(74, 74);
175 }
chaviw25714502021-02-11 10:01:08 -0800176 SurfaceComposerClient::Transaction{}.setCrop(childNoBuffer, Rect(0, 0, 20, 20)).apply(true);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700177 {
178 ScreenCapture::captureScreen(&sc);
179 sc->expectChildColor(73, 73);
180 sc->expectChildColor(74, 74);
181 }
182}
183
184TEST_F(LayerUpdateTest, MergingTransactions) {
185 std::unique_ptr<ScreenCapture> sc;
186 {
187 SCOPED_TRACE("before move");
188 ScreenCapture::captureScreen(&sc);
189 sc->expectBGColor(0, 12);
190 sc->expectFGColor(75, 75);
191 sc->expectBGColor(145, 145);
192 }
193
194 Transaction t1, t2;
195 t1.setPosition(mFGSurfaceControl, 128, 128);
196 t2.setPosition(mFGSurfaceControl, 0, 0);
197 // We expect that the position update from t2 now
198 // overwrites the position update from t1.
199 t1.merge(std::move(t2));
200 t1.apply();
201
202 {
203 ScreenCapture::captureScreen(&sc);
204 sc->expectFGColor(1, 1);
205 }
206}
207
208TEST_F(LayerUpdateTest, MergingTransactionFlags) {
209 Transaction().hide(mFGSurfaceControl).apply();
210 std::unique_ptr<ScreenCapture> sc;
211 {
212 SCOPED_TRACE("before merge");
213 ScreenCapture::captureScreen(&sc);
214 sc->expectBGColor(0, 12);
215 sc->expectBGColor(75, 75);
216 sc->expectBGColor(145, 145);
217 }
218
219 Transaction t1, t2;
220 t1.show(mFGSurfaceControl);
221 t2.setFlags(mFGSurfaceControl, 0 /* flags */, layer_state_t::eLayerSecure /* mask */);
222 t1.merge(std::move(t2));
223 t1.apply();
224
225 {
226 SCOPED_TRACE("after merge");
227 ScreenCapture::captureScreen(&sc);
228 sc->expectFGColor(75, 75);
229 }
230}
231
232class ChildLayerTest : public LayerUpdateTest {
233protected:
234 void SetUp() override {
235 LayerUpdateTest::SetUp();
236 mChild = createSurface(mClient, "Child surface", 10, 15, PIXEL_FORMAT_RGBA_8888, 0,
237 mFGSurfaceControl.get());
238 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
Vishnu Nair2e2fbda2021-01-22 16:06:49 -0800239 waitForPostedBuffers();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700240
241 {
242 SCOPED_TRACE("before anything");
243 mCapture = screenshot();
244 mCapture->expectChildColor(64, 64);
245 }
246 }
247 void TearDown() override {
248 LayerUpdateTest::TearDown();
249 mChild = 0;
250 }
251
252 sp<SurfaceControl> mChild;
253 std::unique_ptr<ScreenCapture> mCapture;
254};
255
256TEST_F(ChildLayerTest, ChildLayerPositioning) {
257 asTransaction([&](Transaction& t) {
258 t.show(mChild);
259 t.setPosition(mChild, 10, 10);
260 t.setPosition(mFGSurfaceControl, 64, 64);
261 });
262
263 {
264 mCapture = screenshot();
265 // Top left of foreground must now be visible
266 mCapture->expectFGColor(64, 64);
267 // But 10 pixels in we should see the child surface
268 mCapture->expectChildColor(74, 74);
269 // And 10 more pixels we should be back to the foreground surface
270 mCapture->expectFGColor(84, 84);
271 }
272
273 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
274
275 {
276 mCapture = screenshot();
277 // Top left of foreground should now be at 0, 0
278 mCapture->expectFGColor(0, 0);
279 // But 10 pixels in we should see the child surface
280 mCapture->expectChildColor(10, 10);
281 // And 10 more pixels we should be back to the foreground surface
282 mCapture->expectFGColor(20, 20);
283 }
284}
285
286TEST_F(ChildLayerTest, ChildLayerCropping) {
287 asTransaction([&](Transaction& t) {
288 t.show(mChild);
289 t.setPosition(mChild, 0, 0);
290 t.setPosition(mFGSurfaceControl, 0, 0);
chaviw25714502021-02-11 10:01:08 -0800291 t.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700292 });
293
294 {
295 mCapture = screenshot();
296 mCapture->expectChildColor(0, 0);
297 mCapture->expectChildColor(4, 4);
298 mCapture->expectBGColor(5, 5);
299 }
300}
301
302TEST_F(ChildLayerTest, ChildLayerConstraints) {
303 asTransaction([&](Transaction& t) {
304 t.show(mChild);
305 t.setPosition(mFGSurfaceControl, 0, 0);
306 t.setPosition(mChild, 63, 63);
307 });
308
309 {
310 mCapture = screenshot();
311 mCapture->expectFGColor(0, 0);
312 // Last pixel in foreground should now be the child.
313 mCapture->expectChildColor(63, 63);
314 // But the child should be constrained and the next pixel
315 // must be the background
316 mCapture->expectBGColor(64, 64);
317 }
318}
319
320TEST_F(ChildLayerTest, ChildLayerScaling) {
321 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
322
323 // Find the boundary between the parent and child
324 {
325 mCapture = screenshot();
326 mCapture->expectChildColor(9, 9);
327 mCapture->expectFGColor(10, 10);
328 }
329
330 asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
331
332 // The boundary should be twice as far from the origin now.
333 // The pixels from the last test should all be child now
334 {
335 mCapture = screenshot();
336 mCapture->expectChildColor(9, 9);
337 mCapture->expectChildColor(10, 10);
338 mCapture->expectChildColor(19, 19);
339 mCapture->expectFGColor(20, 20);
340 }
341}
342
343// A child with a scale transform should be cropped by its parent bounds.
344TEST_F(ChildLayerTest, ChildLayerScalingCroppedByParent) {
345 asTransaction([&](Transaction& t) {
346 t.setPosition(mFGSurfaceControl, 0, 0);
347 t.setPosition(mChild, 0, 0);
348 });
349
350 // Find the boundary between the parent and child.
351 {
352 mCapture = screenshot();
353 mCapture->expectChildColor(0, 0);
354 mCapture->expectChildColor(9, 9);
355 mCapture->expectFGColor(10, 10);
356 }
357
358 asTransaction([&](Transaction& t) { t.setMatrix(mChild, 10.0, 0, 0, 10.0); });
359
360 // The child should fill its parent bounds and be cropped by it.
361 {
362 mCapture = screenshot();
363 mCapture->expectChildColor(0, 0);
364 mCapture->expectChildColor(63, 63);
365 mCapture->expectBGColor(64, 64);
366 }
367}
368
369TEST_F(ChildLayerTest, ChildLayerAlpha) {
370 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
371 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
372 TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
373 waitForPostedBuffers();
374
375 asTransaction([&](Transaction& t) {
376 t.show(mChild);
377 t.setPosition(mChild, 0, 0);
378 t.setPosition(mFGSurfaceControl, 0, 0);
379 });
380
381 {
382 mCapture = screenshot();
383 // Unblended child color
384 mCapture->checkPixel(0, 0, 0, 254, 0);
385 }
386
387 asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
388
389 {
390 mCapture = screenshot();
Ana Krulec69de94c2021-01-25 18:18:27 -0800391 // Child and BG blended. See b/175352694 for tolerance.
392 mCapture->expectColor(Rect(0, 0, 1, 1), Color{127, 127, 0, 255}, 1);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700393 }
394
395 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
396
397 {
398 mCapture = screenshot();
Ana Krulec69de94c2021-01-25 18:18:27 -0800399 // Child and BG blended. See b/175352694 for tolerance.
400 mCapture->expectColor(Rect(0, 0, 1, 1), Color{95, 64, 95, 255}, 1);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700401 }
402}
403
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700404TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
405 sp<SurfaceControl> mGrandChild =
406 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
407 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
408
409 {
410 SCOPED_TRACE("Grandchild visible");
411 ScreenCapture::captureScreen(&mCapture);
412 mCapture->checkPixel(64, 64, 111, 111, 111);
413 }
414
Robert Carr0e328f62020-02-06 17:12:08 -0800415 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700416 mChild.clear();
417
418 {
419 SCOPED_TRACE("After destroying child");
420 ScreenCapture::captureScreen(&mCapture);
421 mCapture->expectFGColor(64, 64);
422 }
423
Pablo Gamito11dcc222020-09-12 15:49:39 +0000424 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700425
426 {
427 SCOPED_TRACE("After reparenting grandchild");
428 ScreenCapture::captureScreen(&mCapture);
429 mCapture->checkPixel(64, 64, 111, 111, 111);
430 }
431}
432
433TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
434 sp<SurfaceControl> mGrandChild =
435 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
436 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
437
438 // draw grand child behind the foreground surface
Pablo Gamito11dcc222020-09-12 15:49:39 +0000439 asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700440
441 {
442 SCOPED_TRACE("Child visible");
443 ScreenCapture::captureScreen(&mCapture);
444 mCapture->checkPixel(64, 64, 200, 200, 200);
445 }
446
447 asTransaction([&](Transaction& t) {
448 t.reparent(mChild, nullptr);
Robert Carr257fdae2021-04-08 17:30:52 -0700449 t.reparent(mGrandChild, mFGSurfaceControl);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700450 });
451
452 {
453 SCOPED_TRACE("foreground visible reparenting grandchild");
454 ScreenCapture::captureScreen(&mCapture);
455 mCapture->checkPixel(64, 64, 195, 63, 63);
456 }
457}
458
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700459TEST_F(ChildLayerTest, Reparent) {
460 asTransaction([&](Transaction& t) {
461 t.show(mChild);
462 t.setPosition(mChild, 10, 10);
463 t.setPosition(mFGSurfaceControl, 64, 64);
464 });
465
466 {
467 mCapture = screenshot();
468 // Top left of foreground must now be visible
469 mCapture->expectFGColor(64, 64);
470 // But 10 pixels in we should see the child surface
471 mCapture->expectChildColor(74, 74);
472 // And 10 more pixels we should be back to the foreground surface
473 mCapture->expectFGColor(84, 84);
474 }
475
Pablo Gamito11dcc222020-09-12 15:49:39 +0000476 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700477
478 {
479 mCapture = screenshot();
480 mCapture->expectFGColor(64, 64);
481 // In reparenting we should have exposed the entire foreground surface.
482 mCapture->expectFGColor(74, 74);
483 // And the child layer should now begin at 10, 10 (since the BG
484 // layer is at (0, 0)).
485 mCapture->expectBGColor(9, 9);
486 mCapture->expectChildColor(10, 10);
487 }
488}
489
490TEST_F(ChildLayerTest, ReparentToNoParent) {
491 asTransaction([&](Transaction& t) {
492 t.show(mChild);
493 t.setPosition(mChild, 10, 10);
494 t.setPosition(mFGSurfaceControl, 64, 64);
495 });
496
497 {
498 mCapture = screenshot();
499 // Top left of foreground must now be visible
500 mCapture->expectFGColor(64, 64);
501 // But 10 pixels in we should see the child surface
502 mCapture->expectChildColor(74, 74);
503 // And 10 more pixels we should be back to the foreground surface
504 mCapture->expectFGColor(84, 84);
505 }
506 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
507 {
508 mCapture = screenshot();
509 // The surface should now be offscreen.
510 mCapture->expectFGColor(64, 64);
511 mCapture->expectFGColor(74, 74);
512 mCapture->expectFGColor(84, 84);
513 }
514}
515
516TEST_F(ChildLayerTest, ReparentFromNoParent) {
517 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
518 ASSERT_TRUE(newSurface != nullptr);
519 ASSERT_TRUE(newSurface->isValid());
520
521 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
522 asTransaction([&](Transaction& t) {
523 t.hide(mChild);
524 t.show(newSurface);
525 t.setPosition(newSurface, 10, 10);
526 t.setLayer(newSurface, INT32_MAX - 2);
527 t.setPosition(mFGSurfaceControl, 64, 64);
528 });
529
530 {
531 mCapture = screenshot();
532 // Top left of foreground must now be visible
533 mCapture->expectFGColor(64, 64);
534 // At 10, 10 we should see the new surface
535 mCapture->checkPixel(10, 10, 63, 195, 63);
536 }
537
Pablo Gamito11dcc222020-09-12 15:49:39 +0000538 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700539
540 {
541 mCapture = screenshot();
542 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
543 // mFGSurface, putting it at 74, 74.
544 mCapture->expectFGColor(64, 64);
545 mCapture->checkPixel(74, 74, 63, 195, 63);
546 mCapture->expectFGColor(84, 84);
547 }
548}
549
550TEST_F(ChildLayerTest, NestedChildren) {
551 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
552 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
553 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
554
555 {
556 mCapture = screenshot();
557 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
558 // which begins at 64, 64
559 mCapture->checkPixel(64, 64, 50, 50, 50);
560 }
561}
562
563TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
564 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
565 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
566
567 Transaction t;
568 t.setLayer(relative, INT32_MAX)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000569 .setRelativeLayer(mChild, relative, 1)
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700570 .setPosition(mFGSurfaceControl, 0, 0)
571 .apply(true);
572
573 // We expect that the child should have been elevated above our
574 // INT_MAX layer even though it's not a child of it.
575 {
576 mCapture = screenshot();
577 mCapture->expectChildColor(0, 0);
578 mCapture->expectChildColor(9, 9);
579 mCapture->checkPixel(10, 10, 255, 255, 255);
580 }
581}
582
583class BoundlessLayerTest : public LayerUpdateTest {
584protected:
585 std::unique_ptr<ScreenCapture> mCapture;
586};
587
588// Verify setting a size on a buffer layer has no effect.
589TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
590 sp<SurfaceControl> bufferLayer =
591 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
592 mFGSurfaceControl.get());
593 ASSERT_TRUE(bufferLayer->isValid());
594 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
595 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
596 {
597 mCapture = screenshot();
598 // Top left of background must now be visible
599 mCapture->expectBGColor(0, 0);
600 // Foreground Surface bounds must be color layer
601 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
602 // Buffer layer should not extend past buffer bounds
603 mCapture->expectFGColor(95, 95);
604 }
605}
606
607// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
608// which will crop the color layer.
609TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
610 sp<SurfaceControl> colorLayer =
611 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800612 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700613 ASSERT_TRUE(colorLayer->isValid());
614 asTransaction([&](Transaction& t) {
615 t.setColor(colorLayer, half3{0, 0, 0});
616 t.show(colorLayer);
617 });
618 {
619 mCapture = screenshot();
620 // Top left of background must now be visible
621 mCapture->expectBGColor(0, 0);
622 // Foreground Surface bounds must be color layer
623 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
624 // Color layer should not extend past foreground bounds
625 mCapture->expectBGColor(129, 129);
626 }
627}
628
629// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
630// a crop which will be used to crop the color layer.
631TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
632 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
633 0 /* flags */, mFGSurfaceControl.get());
634 ASSERT_TRUE(cropLayer->isValid());
635 sp<SurfaceControl> colorLayer =
636 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800637 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700638 ASSERT_TRUE(colorLayer->isValid());
639 asTransaction([&](Transaction& t) {
chaviw25714502021-02-11 10:01:08 -0800640 t.setCrop(cropLayer, Rect(5, 5, 10, 10));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700641 t.setColor(colorLayer, half3{0, 0, 0});
642 t.show(cropLayer);
643 t.show(colorLayer);
644 });
645 {
646 mCapture = screenshot();
647 // Top left of background must now be visible
648 mCapture->expectBGColor(0, 0);
649 // Top left of foreground must now be visible
650 mCapture->expectFGColor(64, 64);
651 // 5 pixels from the foreground we should see the child surface
652 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
653 // 10 pixels from the foreground we should be back to the foreground surface
654 mCapture->expectFGColor(74, 74);
655 }
656}
657
658// Verify for boundless layer with no children, their transforms have no effect.
659TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
660 sp<SurfaceControl> colorLayer =
661 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800662 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700663 ASSERT_TRUE(colorLayer->isValid());
664 asTransaction([&](Transaction& t) {
665 t.setPosition(colorLayer, 320, 320);
666 t.setMatrix(colorLayer, 2, 0, 0, 2);
667 t.setColor(colorLayer, half3{0, 0, 0});
668 t.show(colorLayer);
669 });
670 {
671 mCapture = screenshot();
672 // Top left of background must now be visible
673 mCapture->expectBGColor(0, 0);
674 // Foreground Surface bounds must be color layer
675 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
676 // Color layer should not extend past foreground bounds
677 mCapture->expectBGColor(129, 129);
678 }
679}
680
681// Verify for boundless layer with children, their transforms have an effect.
682TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
683 sp<SurfaceControl> boundlessLayerRightShift =
684 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
685 0 /* flags */, mFGSurfaceControl.get());
686 ASSERT_TRUE(boundlessLayerRightShift->isValid());
687 sp<SurfaceControl> boundlessLayerDownShift =
688 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
689 0 /* flags */, boundlessLayerRightShift.get());
690 ASSERT_TRUE(boundlessLayerDownShift->isValid());
691 sp<SurfaceControl> colorLayer =
692 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800693 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700694 ASSERT_TRUE(colorLayer->isValid());
695 asTransaction([&](Transaction& t) {
696 t.setPosition(boundlessLayerRightShift, 32, 0);
697 t.show(boundlessLayerRightShift);
698 t.setPosition(boundlessLayerDownShift, 0, 32);
699 t.show(boundlessLayerDownShift);
chaviw25714502021-02-11 10:01:08 -0800700 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700701 t.setColor(colorLayer, half3{0, 0, 0});
702 t.show(colorLayer);
703 });
704 {
705 mCapture = screenshot();
706 // Top left of background must now be visible
707 mCapture->expectBGColor(0, 0);
708 // Top left of foreground must now be visible
709 mCapture->expectFGColor(64, 64);
710 // Foreground Surface bounds must be color layer
711 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
712 // Color layer should not extend past foreground bounds
713 mCapture->expectBGColor(129, 129);
714 }
715}
716
717// Verify child layers do not get clipped if they temporarily move into the negative
718// coordinate space as the result of an intermediate transformation.
719TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
720 sp<SurfaceControl> boundlessLayer =
721 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -0700722 0 /* flags */, mFGSurfaceControl->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700723 ASSERT_TRUE(boundlessLayer != nullptr);
724 ASSERT_TRUE(boundlessLayer->isValid());
725 sp<SurfaceControl> colorLayer =
726 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -0700727 ISurfaceComposerClient::eFXSurfaceEffect,
728 boundlessLayer->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700729 ASSERT_TRUE(colorLayer != nullptr);
730 ASSERT_TRUE(colorLayer->isValid());
731 asTransaction([&](Transaction& t) {
732 // shift child layer off bounds. If this layer was not boundless, we will
733 // expect the child layer to be cropped.
734 t.setPosition(boundlessLayer, 32, 32);
735 t.show(boundlessLayer);
chaviw25714502021-02-11 10:01:08 -0800736 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700737 // undo shift by parent
738 t.setPosition(colorLayer, -32, -32);
739 t.setColor(colorLayer, half3{0, 0, 0});
740 t.show(colorLayer);
741 });
742 {
743 mCapture = screenshot();
744 // Top left of background must now be visible
745 mCapture->expectBGColor(0, 0);
746 // Foreground Surface bounds must be color layer
747 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
748 // Color layer should not extend past foreground bounds
749 mCapture->expectBGColor(129, 129);
750 }
751}
752
753// Verify for boundless root layers with children, their transforms have an effect.
754TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
755 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
756 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
757 ASSERT_TRUE(rootBoundlessLayer->isValid());
758 sp<SurfaceControl> colorLayer =
759 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800760 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700761
762 ASSERT_TRUE(colorLayer->isValid());
763 asTransaction([&](Transaction& t) {
764 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
765 t.setPosition(rootBoundlessLayer, 32, 32);
766 t.show(rootBoundlessLayer);
chaviw25714502021-02-11 10:01:08 -0800767 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700768 t.setColor(colorLayer, half3{0, 0, 0});
769 t.show(colorLayer);
770 t.hide(mFGSurfaceControl);
771 });
772 {
773 mCapture = screenshot();
774 // Top left of background must now be visible
775 mCapture->expectBGColor(0, 0);
776 // Top left of foreground must now be visible
777 mCapture->expectBGColor(31, 31);
778 // Foreground Surface bounds must be color layer
779 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
780 // Color layer should not extend past foreground bounds
781 mCapture->expectBGColor(97, 97);
782 }
783}
784
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700785} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800786
787// TODO(b/129481165): remove the #pragma below and fix conversion issues
788#pragma clang diagnostic pop // ignored "-Wconversion"