blob: adb5d58e8c692e4b3cb5f33556c4656d12dc36ac [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
36 const auto display = SurfaceComposerClient::getInternalDisplayToken();
37 ASSERT_FALSE(display == nullptr);
38
Marin Shalamanova7fe3042021-01-29 21:02:08 +010039 ui::DisplayMode mode;
40 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
41 const ui::Size& resolution = mode.resolution;
Valerie Hau9cfc6d82019-09-23 13:54:07 -070042
43 // Background surface
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080044 mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
45 resolution.getHeight(), 0);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070046 ASSERT_TRUE(mBGSurfaceControl != nullptr);
47 ASSERT_TRUE(mBGSurfaceControl->isValid());
48 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
49
50 // Foreground surface
51 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
52
53 ASSERT_TRUE(mFGSurfaceControl != nullptr);
54 ASSERT_TRUE(mFGSurfaceControl->isValid());
55
56 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
57
58 // Synchronization surface
59 mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
60 ASSERT_TRUE(mSyncSurfaceControl != nullptr);
61 ASSERT_TRUE(mSyncSurfaceControl->isValid());
62
63 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
64
65 asTransaction([&](Transaction& t) {
66 t.setDisplayLayerStack(display, 0);
67
68 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
69
70 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
71 .setPosition(mFGSurfaceControl, 64, 64)
72 .show(mFGSurfaceControl);
73
74 t.setLayer(mSyncSurfaceControl, INT32_MAX - 1)
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080075 .setPosition(mSyncSurfaceControl, resolution.getWidth() - 2,
76 resolution.getHeight() - 2)
Valerie Hau9cfc6d82019-09-23 13:54:07 -070077 .show(mSyncSurfaceControl);
78 });
79 }
80
81 virtual void TearDown() {
82 LayerTransactionTest::TearDown();
83 mBGSurfaceControl = 0;
84 mFGSurfaceControl = 0;
85 mSyncSurfaceControl = 0;
86 }
87
88 void waitForPostedBuffers() {
89 // Since the sync surface is in synchronous mode (i.e. double buffered)
90 // posting three buffers to it should ensure that at least two
91 // SurfaceFlinger::handlePageFlip calls have been made, which should
92 // guaranteed that a buffer posted to another Surface has been retired.
93 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
94 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
95 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
96 }
97
98 sp<SurfaceControl> mBGSurfaceControl;
99 sp<SurfaceControl> mFGSurfaceControl;
100
101 // This surface is used to ensure that the buffers posted to
102 // mFGSurfaceControl have been picked up by SurfaceFlinger.
103 sp<SurfaceControl> mSyncSurfaceControl;
104};
105
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700106class GeometryLatchingTest : public LayerUpdateTest {
107protected:
108 void EXPECT_INITIAL_STATE(const char* trace) {
109 SCOPED_TRACE(trace);
110 ScreenCapture::captureScreen(&sc);
111 // We find the leading edge of the FG surface.
112 sc->expectFGColor(127, 127);
113 sc->expectBGColor(128, 128);
114 }
115
116 void lockAndFillFGBuffer() {
117 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false);
118 }
119
120 void unlockFGBuffer() {
121 sp<Surface> s = mFGSurfaceControl->getSurface();
122 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
123 waitForPostedBuffers();
124 }
125
126 void completeFGResize() {
127 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
128 waitForPostedBuffers();
129 }
130 void restoreInitialState() {
131 asTransaction([&](Transaction& t) {
132 t.setSize(mFGSurfaceControl, 64, 64);
133 t.setPosition(mFGSurfaceControl, 64, 64);
chaviw25714502021-02-11 10:01:08 -0800134 t.setCrop(mFGSurfaceControl, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700135 });
136
137 EXPECT_INITIAL_STATE("After restoring initial state");
138 }
139 std::unique_ptr<ScreenCapture> sc;
140};
141
142class CropLatchingTest : public GeometryLatchingTest {
143protected:
144 void EXPECT_CROPPED_STATE(const char* trace) {
145 SCOPED_TRACE(trace);
146 ScreenCapture::captureScreen(&sc);
147 // The edge should be moved back one pixel by our crop.
148 sc->expectFGColor(126, 126);
149 sc->expectBGColor(127, 127);
150 sc->expectBGColor(128, 128);
151 }
152
153 void EXPECT_RESIZE_STATE(const char* trace) {
154 SCOPED_TRACE(trace);
155 ScreenCapture::captureScreen(&sc);
156 // The FG is now resized too 128,128 at 64,64
157 sc->expectFGColor(64, 64);
158 sc->expectFGColor(191, 191);
159 sc->expectBGColor(192, 192);
160 }
161};
162
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700163TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
164 std::unique_ptr<ScreenCapture> sc;
165
166 sp<SurfaceControl> childNoBuffer =
167 createSurface(mClient, "Bufferless child", 0 /* buffer width */, 0 /* buffer height */,
168 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
169 sp<SurfaceControl> childBuffer = createSurface(mClient, "Buffered child", 20, 20,
170 PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
171 TransactionUtils::fillSurfaceRGBA8(childBuffer, 200, 200, 200);
172 SurfaceComposerClient::Transaction{}
chaviw25714502021-02-11 10:01:08 -0800173 .setCrop(childNoBuffer, Rect(0, 0, 10, 10))
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700174 .show(childNoBuffer)
175 .show(childBuffer)
176 .apply(true);
177 {
178 ScreenCapture::captureScreen(&sc);
179 sc->expectChildColor(73, 73);
180 sc->expectFGColor(74, 74);
181 }
chaviw25714502021-02-11 10:01:08 -0800182 SurfaceComposerClient::Transaction{}.setCrop(childNoBuffer, Rect(0, 0, 20, 20)).apply(true);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700183 {
184 ScreenCapture::captureScreen(&sc);
185 sc->expectChildColor(73, 73);
186 sc->expectChildColor(74, 74);
187 }
188}
189
190TEST_F(LayerUpdateTest, MergingTransactions) {
191 std::unique_ptr<ScreenCapture> sc;
192 {
193 SCOPED_TRACE("before move");
194 ScreenCapture::captureScreen(&sc);
195 sc->expectBGColor(0, 12);
196 sc->expectFGColor(75, 75);
197 sc->expectBGColor(145, 145);
198 }
199
200 Transaction t1, t2;
201 t1.setPosition(mFGSurfaceControl, 128, 128);
202 t2.setPosition(mFGSurfaceControl, 0, 0);
203 // We expect that the position update from t2 now
204 // overwrites the position update from t1.
205 t1.merge(std::move(t2));
206 t1.apply();
207
208 {
209 ScreenCapture::captureScreen(&sc);
210 sc->expectFGColor(1, 1);
211 }
212}
213
214TEST_F(LayerUpdateTest, MergingTransactionFlags) {
215 Transaction().hide(mFGSurfaceControl).apply();
216 std::unique_ptr<ScreenCapture> sc;
217 {
218 SCOPED_TRACE("before merge");
219 ScreenCapture::captureScreen(&sc);
220 sc->expectBGColor(0, 12);
221 sc->expectBGColor(75, 75);
222 sc->expectBGColor(145, 145);
223 }
224
225 Transaction t1, t2;
226 t1.show(mFGSurfaceControl);
227 t2.setFlags(mFGSurfaceControl, 0 /* flags */, layer_state_t::eLayerSecure /* mask */);
228 t1.merge(std::move(t2));
229 t1.apply();
230
231 {
232 SCOPED_TRACE("after merge");
233 ScreenCapture::captureScreen(&sc);
234 sc->expectFGColor(75, 75);
235 }
236}
237
238class ChildLayerTest : public LayerUpdateTest {
239protected:
240 void SetUp() override {
241 LayerUpdateTest::SetUp();
242 mChild = createSurface(mClient, "Child surface", 10, 15, PIXEL_FORMAT_RGBA_8888, 0,
243 mFGSurfaceControl.get());
244 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
Vishnu Nair2e2fbda2021-01-22 16:06:49 -0800245 waitForPostedBuffers();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700246
247 {
248 SCOPED_TRACE("before anything");
249 mCapture = screenshot();
250 mCapture->expectChildColor(64, 64);
251 }
252 }
253 void TearDown() override {
254 LayerUpdateTest::TearDown();
255 mChild = 0;
256 }
257
258 sp<SurfaceControl> mChild;
259 std::unique_ptr<ScreenCapture> mCapture;
260};
261
262TEST_F(ChildLayerTest, ChildLayerPositioning) {
263 asTransaction([&](Transaction& t) {
264 t.show(mChild);
265 t.setPosition(mChild, 10, 10);
266 t.setPosition(mFGSurfaceControl, 64, 64);
267 });
268
269 {
270 mCapture = screenshot();
271 // Top left of foreground must now be visible
272 mCapture->expectFGColor(64, 64);
273 // But 10 pixels in we should see the child surface
274 mCapture->expectChildColor(74, 74);
275 // And 10 more pixels we should be back to the foreground surface
276 mCapture->expectFGColor(84, 84);
277 }
278
279 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
280
281 {
282 mCapture = screenshot();
283 // Top left of foreground should now be at 0, 0
284 mCapture->expectFGColor(0, 0);
285 // But 10 pixels in we should see the child surface
286 mCapture->expectChildColor(10, 10);
287 // And 10 more pixels we should be back to the foreground surface
288 mCapture->expectFGColor(20, 20);
289 }
290}
291
292TEST_F(ChildLayerTest, ChildLayerCropping) {
293 asTransaction([&](Transaction& t) {
294 t.show(mChild);
295 t.setPosition(mChild, 0, 0);
296 t.setPosition(mFGSurfaceControl, 0, 0);
chaviw25714502021-02-11 10:01:08 -0800297 t.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700298 });
299
300 {
301 mCapture = screenshot();
302 mCapture->expectChildColor(0, 0);
303 mCapture->expectChildColor(4, 4);
304 mCapture->expectBGColor(5, 5);
305 }
306}
307
308TEST_F(ChildLayerTest, ChildLayerConstraints) {
309 asTransaction([&](Transaction& t) {
310 t.show(mChild);
311 t.setPosition(mFGSurfaceControl, 0, 0);
312 t.setPosition(mChild, 63, 63);
313 });
314
315 {
316 mCapture = screenshot();
317 mCapture->expectFGColor(0, 0);
318 // Last pixel in foreground should now be the child.
319 mCapture->expectChildColor(63, 63);
320 // But the child should be constrained and the next pixel
321 // must be the background
322 mCapture->expectBGColor(64, 64);
323 }
324}
325
326TEST_F(ChildLayerTest, ChildLayerScaling) {
327 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
328
329 // Find the boundary between the parent and child
330 {
331 mCapture = screenshot();
332 mCapture->expectChildColor(9, 9);
333 mCapture->expectFGColor(10, 10);
334 }
335
336 asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
337
338 // The boundary should be twice as far from the origin now.
339 // The pixels from the last test should all be child now
340 {
341 mCapture = screenshot();
342 mCapture->expectChildColor(9, 9);
343 mCapture->expectChildColor(10, 10);
344 mCapture->expectChildColor(19, 19);
345 mCapture->expectFGColor(20, 20);
346 }
347}
348
349// A child with a scale transform should be cropped by its parent bounds.
350TEST_F(ChildLayerTest, ChildLayerScalingCroppedByParent) {
351 asTransaction([&](Transaction& t) {
352 t.setPosition(mFGSurfaceControl, 0, 0);
353 t.setPosition(mChild, 0, 0);
354 });
355
356 // Find the boundary between the parent and child.
357 {
358 mCapture = screenshot();
359 mCapture->expectChildColor(0, 0);
360 mCapture->expectChildColor(9, 9);
361 mCapture->expectFGColor(10, 10);
362 }
363
364 asTransaction([&](Transaction& t) { t.setMatrix(mChild, 10.0, 0, 0, 10.0); });
365
366 // The child should fill its parent bounds and be cropped by it.
367 {
368 mCapture = screenshot();
369 mCapture->expectChildColor(0, 0);
370 mCapture->expectChildColor(63, 63);
371 mCapture->expectBGColor(64, 64);
372 }
373}
374
375TEST_F(ChildLayerTest, ChildLayerAlpha) {
376 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
377 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
378 TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
379 waitForPostedBuffers();
380
381 asTransaction([&](Transaction& t) {
382 t.show(mChild);
383 t.setPosition(mChild, 0, 0);
384 t.setPosition(mFGSurfaceControl, 0, 0);
385 });
386
387 {
388 mCapture = screenshot();
389 // Unblended child color
390 mCapture->checkPixel(0, 0, 0, 254, 0);
391 }
392
393 asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
394
395 {
396 mCapture = screenshot();
Ana Krulec69de94c2021-01-25 18:18:27 -0800397 // Child and BG blended. See b/175352694 for tolerance.
398 mCapture->expectColor(Rect(0, 0, 1, 1), Color{127, 127, 0, 255}, 1);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700399 }
400
401 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
402
403 {
404 mCapture = screenshot();
Ana Krulec69de94c2021-01-25 18:18:27 -0800405 // Child and BG blended. See b/175352694 for tolerance.
406 mCapture->expectColor(Rect(0, 0, 1, 1), Color{95, 64, 95, 255}, 1);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700407 }
408}
409
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700410TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
411 sp<SurfaceControl> mGrandChild =
412 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
413 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
414
415 {
416 SCOPED_TRACE("Grandchild visible");
417 ScreenCapture::captureScreen(&mCapture);
418 mCapture->checkPixel(64, 64, 111, 111, 111);
419 }
420
Robert Carr0e328f62020-02-06 17:12:08 -0800421 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700422 mChild.clear();
423
424 {
425 SCOPED_TRACE("After destroying child");
426 ScreenCapture::captureScreen(&mCapture);
427 mCapture->expectFGColor(64, 64);
428 }
429
Pablo Gamito11dcc222020-09-12 15:49:39 +0000430 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700431
432 {
433 SCOPED_TRACE("After reparenting grandchild");
434 ScreenCapture::captureScreen(&mCapture);
435 mCapture->checkPixel(64, 64, 111, 111, 111);
436 }
437}
438
439TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
440 sp<SurfaceControl> mGrandChild =
441 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
442 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
443
444 // draw grand child behind the foreground surface
Pablo Gamito11dcc222020-09-12 15:49:39 +0000445 asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700446
447 {
448 SCOPED_TRACE("Child visible");
449 ScreenCapture::captureScreen(&mCapture);
450 mCapture->checkPixel(64, 64, 200, 200, 200);
451 }
452
453 asTransaction([&](Transaction& t) {
454 t.reparent(mChild, nullptr);
Robert Carr257fdae2021-04-08 17:30:52 -0700455 t.reparent(mGrandChild, mFGSurfaceControl);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700456 });
457
458 {
459 SCOPED_TRACE("foreground visible reparenting grandchild");
460 ScreenCapture::captureScreen(&mCapture);
461 mCapture->checkPixel(64, 64, 195, 63, 63);
462 }
463}
464
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700465TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
466 asTransaction([&](Transaction& t) {
467 t.show(mChild);
468 t.setPosition(mChild, 0, 0);
469 t.setPosition(mFGSurfaceControl, 0, 0);
470 });
471
472 {
473 mCapture = screenshot();
474 // We've positioned the child in the top left.
475 mCapture->expectChildColor(0, 0);
476 // But it's only 10x15.
477 mCapture->expectFGColor(10, 15);
478 }
479
480 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700481 mFGSurfaceControl->getSurface()->setScalingMode(
482 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
483 // Resubmit buffer with new scaling mode
484 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700485 // We cause scaling by 2.
486 t.setSize(mFGSurfaceControl, 128, 128);
487 });
488
489 {
490 mCapture = screenshot();
491 // We've positioned the child in the top left.
492 mCapture->expectChildColor(0, 0);
493 mCapture->expectChildColor(10, 10);
494 mCapture->expectChildColor(19, 29);
495 // And now it should be scaled all the way to 20x30
496 mCapture->expectFGColor(20, 30);
497 }
498}
499
500// Regression test for b/37673612
501TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
502 asTransaction([&](Transaction& t) {
503 t.show(mChild);
504 t.setPosition(mChild, 0, 0);
505 t.setPosition(mFGSurfaceControl, 0, 0);
506 });
507
508 {
509 mCapture = screenshot();
510 // We've positioned the child in the top left.
511 mCapture->expectChildColor(0, 0);
512 mCapture->expectChildColor(9, 14);
513 // But it's only 10x15.
514 mCapture->expectFGColor(10, 15);
515 }
516 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
517 // the WM specified state size.
518 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
519 sp<Surface> s = mFGSurfaceControl->getSurface();
520 auto anw = static_cast<ANativeWindow*>(s.get());
521 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
522 native_window_set_buffers_dimensions(anw, 64, 128);
523 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
524 waitForPostedBuffers();
525
526 {
527 // The child should still be in the same place and not have any strange scaling as in
528 // b/37673612.
529 mCapture = screenshot();
530 mCapture->expectChildColor(0, 0);
531 mCapture->expectFGColor(10, 10);
532 }
533}
534
535// A child with a buffer transform from its parents should be cropped by its parent bounds.
536TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
537 asTransaction([&](Transaction& t) {
538 t.show(mChild);
539 t.setPosition(mChild, 0, 0);
540 t.setPosition(mFGSurfaceControl, 0, 0);
541 t.setSize(mChild, 100, 100);
542 });
543 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
544
545 {
546 mCapture = screenshot();
547
548 mCapture->expectChildColor(0, 0);
549 mCapture->expectChildColor(63, 63);
550 mCapture->expectBGColor(64, 64);
551 }
552
553 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
554 sp<Surface> s = mFGSurfaceControl->getSurface();
555 auto anw = static_cast<ANativeWindow*>(s.get());
556 // Apply a 90 transform on the buffer.
557 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
558 native_window_set_buffers_dimensions(anw, 64, 128);
559 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
560 waitForPostedBuffers();
561
562 // The child should be cropped by the new parent bounds.
563 {
564 mCapture = screenshot();
565 mCapture->expectChildColor(0, 0);
566 mCapture->expectChildColor(99, 63);
567 mCapture->expectFGColor(100, 63);
568 mCapture->expectBGColor(128, 64);
569 }
570}
571
572// A child with a scale transform from its parents should be cropped by its parent bounds.
573TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
574 asTransaction([&](Transaction& t) {
575 t.show(mChild);
576 t.setPosition(mChild, 0, 0);
577 t.setPosition(mFGSurfaceControl, 0, 0);
578 t.setSize(mChild, 200, 200);
579 });
580 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
581
582 {
583 mCapture = screenshot();
584
585 mCapture->expectChildColor(0, 0);
586 mCapture->expectChildColor(63, 63);
587 mCapture->expectBGColor(64, 64);
588 }
589
590 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700591 mFGSurfaceControl->getSurface()->setScalingMode(
592 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
593 // Resubmit buffer with new scaling mode
594 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700595 // Set a scaling by 2.
596 t.setSize(mFGSurfaceControl, 128, 128);
597 });
598
599 // Child should inherit its parents scale but should be cropped by its parent bounds.
600 {
601 mCapture = screenshot();
602 mCapture->expectChildColor(0, 0);
603 mCapture->expectChildColor(127, 127);
604 mCapture->expectBGColor(128, 128);
605 }
606}
607
608// Regression test for b/127368943
609// Child should ignore the buffer transform but apply parent scale transform.
610TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
611 asTransaction([&](Transaction& t) {
612 t.show(mChild);
613 t.setPosition(mChild, 0, 0);
614 t.setPosition(mFGSurfaceControl, 0, 0);
615 });
616
617 {
618 mCapture = screenshot();
619 mCapture->expectChildColor(0, 0);
620 mCapture->expectChildColor(9, 14);
621 mCapture->expectFGColor(10, 15);
622 }
623
624 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
625 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700626 mFGSurfaceControl->getSurface()->setScalingMode(
627 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
628 // Resubmit buffer with new scaling mode
629 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700630 t.setSize(mFGSurfaceControl, 128, 64);
631 });
632 sp<Surface> s = mFGSurfaceControl->getSurface();
633 auto anw = static_cast<ANativeWindow*>(s.get());
634 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
635 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
636 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
637 native_window_set_buffers_dimensions(anw, 32, 64);
638 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
639 waitForPostedBuffers();
640
641 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
642 {
643 mCapture = screenshot();
644 mCapture->expectChildColor(0, 0);
645 mCapture->expectChildColor(19, 29);
646 mCapture->expectFGColor(20, 30);
647 }
648}
649
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700650TEST_F(ChildLayerTest, Reparent) {
651 asTransaction([&](Transaction& t) {
652 t.show(mChild);
653 t.setPosition(mChild, 10, 10);
654 t.setPosition(mFGSurfaceControl, 64, 64);
655 });
656
657 {
658 mCapture = screenshot();
659 // Top left of foreground must now be visible
660 mCapture->expectFGColor(64, 64);
661 // But 10 pixels in we should see the child surface
662 mCapture->expectChildColor(74, 74);
663 // And 10 more pixels we should be back to the foreground surface
664 mCapture->expectFGColor(84, 84);
665 }
666
Pablo Gamito11dcc222020-09-12 15:49:39 +0000667 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700668
669 {
670 mCapture = screenshot();
671 mCapture->expectFGColor(64, 64);
672 // In reparenting we should have exposed the entire foreground surface.
673 mCapture->expectFGColor(74, 74);
674 // And the child layer should now begin at 10, 10 (since the BG
675 // layer is at (0, 0)).
676 mCapture->expectBGColor(9, 9);
677 mCapture->expectChildColor(10, 10);
678 }
679}
680
681TEST_F(ChildLayerTest, ReparentToNoParent) {
682 asTransaction([&](Transaction& t) {
683 t.show(mChild);
684 t.setPosition(mChild, 10, 10);
685 t.setPosition(mFGSurfaceControl, 64, 64);
686 });
687
688 {
689 mCapture = screenshot();
690 // Top left of foreground must now be visible
691 mCapture->expectFGColor(64, 64);
692 // But 10 pixels in we should see the child surface
693 mCapture->expectChildColor(74, 74);
694 // And 10 more pixels we should be back to the foreground surface
695 mCapture->expectFGColor(84, 84);
696 }
697 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
698 {
699 mCapture = screenshot();
700 // The surface should now be offscreen.
701 mCapture->expectFGColor(64, 64);
702 mCapture->expectFGColor(74, 74);
703 mCapture->expectFGColor(84, 84);
704 }
705}
706
707TEST_F(ChildLayerTest, ReparentFromNoParent) {
708 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
709 ASSERT_TRUE(newSurface != nullptr);
710 ASSERT_TRUE(newSurface->isValid());
711
712 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
713 asTransaction([&](Transaction& t) {
714 t.hide(mChild);
715 t.show(newSurface);
716 t.setPosition(newSurface, 10, 10);
717 t.setLayer(newSurface, INT32_MAX - 2);
718 t.setPosition(mFGSurfaceControl, 64, 64);
719 });
720
721 {
722 mCapture = screenshot();
723 // Top left of foreground must now be visible
724 mCapture->expectFGColor(64, 64);
725 // At 10, 10 we should see the new surface
726 mCapture->checkPixel(10, 10, 63, 195, 63);
727 }
728
Pablo Gamito11dcc222020-09-12 15:49:39 +0000729 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700730
731 {
732 mCapture = screenshot();
733 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
734 // mFGSurface, putting it at 74, 74.
735 mCapture->expectFGColor(64, 64);
736 mCapture->checkPixel(74, 74, 63, 195, 63);
737 mCapture->expectFGColor(84, 84);
738 }
739}
740
741TEST_F(ChildLayerTest, NestedChildren) {
742 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
743 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
744 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
745
746 {
747 mCapture = screenshot();
748 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
749 // which begins at 64, 64
750 mCapture->checkPixel(64, 64, 50, 50, 50);
751 }
752}
753
754TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
755 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
756 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
757
758 Transaction t;
759 t.setLayer(relative, INT32_MAX)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000760 .setRelativeLayer(mChild, relative, 1)
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700761 .setPosition(mFGSurfaceControl, 0, 0)
762 .apply(true);
763
764 // We expect that the child should have been elevated above our
765 // INT_MAX layer even though it's not a child of it.
766 {
767 mCapture = screenshot();
768 mCapture->expectChildColor(0, 0);
769 mCapture->expectChildColor(9, 9);
770 mCapture->checkPixel(10, 10, 255, 255, 255);
771 }
772}
773
774class BoundlessLayerTest : public LayerUpdateTest {
775protected:
776 std::unique_ptr<ScreenCapture> mCapture;
777};
778
779// Verify setting a size on a buffer layer has no effect.
780TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
781 sp<SurfaceControl> bufferLayer =
782 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
783 mFGSurfaceControl.get());
784 ASSERT_TRUE(bufferLayer->isValid());
785 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
786 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
787 {
788 mCapture = screenshot();
789 // Top left of background must now be visible
790 mCapture->expectBGColor(0, 0);
791 // Foreground Surface bounds must be color layer
792 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
793 // Buffer layer should not extend past buffer bounds
794 mCapture->expectFGColor(95, 95);
795 }
796}
797
798// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
799// which will crop the color layer.
800TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
801 sp<SurfaceControl> colorLayer =
802 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800803 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700804 ASSERT_TRUE(colorLayer->isValid());
805 asTransaction([&](Transaction& t) {
806 t.setColor(colorLayer, half3{0, 0, 0});
807 t.show(colorLayer);
808 });
809 {
810 mCapture = screenshot();
811 // Top left of background must now be visible
812 mCapture->expectBGColor(0, 0);
813 // Foreground Surface bounds must be color layer
814 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
815 // Color layer should not extend past foreground bounds
816 mCapture->expectBGColor(129, 129);
817 }
818}
819
820// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
821// a crop which will be used to crop the color layer.
822TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
823 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
824 0 /* flags */, mFGSurfaceControl.get());
825 ASSERT_TRUE(cropLayer->isValid());
826 sp<SurfaceControl> colorLayer =
827 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800828 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700829 ASSERT_TRUE(colorLayer->isValid());
830 asTransaction([&](Transaction& t) {
chaviw25714502021-02-11 10:01:08 -0800831 t.setCrop(cropLayer, Rect(5, 5, 10, 10));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700832 t.setColor(colorLayer, half3{0, 0, 0});
833 t.show(cropLayer);
834 t.show(colorLayer);
835 });
836 {
837 mCapture = screenshot();
838 // Top left of background must now be visible
839 mCapture->expectBGColor(0, 0);
840 // Top left of foreground must now be visible
841 mCapture->expectFGColor(64, 64);
842 // 5 pixels from the foreground we should see the child surface
843 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
844 // 10 pixels from the foreground we should be back to the foreground surface
845 mCapture->expectFGColor(74, 74);
846 }
847}
848
849// Verify for boundless layer with no children, their transforms have no effect.
850TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
851 sp<SurfaceControl> colorLayer =
852 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800853 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700854 ASSERT_TRUE(colorLayer->isValid());
855 asTransaction([&](Transaction& t) {
856 t.setPosition(colorLayer, 320, 320);
857 t.setMatrix(colorLayer, 2, 0, 0, 2);
858 t.setColor(colorLayer, half3{0, 0, 0});
859 t.show(colorLayer);
860 });
861 {
862 mCapture = screenshot();
863 // Top left of background must now be visible
864 mCapture->expectBGColor(0, 0);
865 // Foreground Surface bounds must be color layer
866 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
867 // Color layer should not extend past foreground bounds
868 mCapture->expectBGColor(129, 129);
869 }
870}
871
872// Verify for boundless layer with children, their transforms have an effect.
873TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
874 sp<SurfaceControl> boundlessLayerRightShift =
875 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
876 0 /* flags */, mFGSurfaceControl.get());
877 ASSERT_TRUE(boundlessLayerRightShift->isValid());
878 sp<SurfaceControl> boundlessLayerDownShift =
879 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
880 0 /* flags */, boundlessLayerRightShift.get());
881 ASSERT_TRUE(boundlessLayerDownShift->isValid());
882 sp<SurfaceControl> colorLayer =
883 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800884 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700885 ASSERT_TRUE(colorLayer->isValid());
886 asTransaction([&](Transaction& t) {
887 t.setPosition(boundlessLayerRightShift, 32, 0);
888 t.show(boundlessLayerRightShift);
889 t.setPosition(boundlessLayerDownShift, 0, 32);
890 t.show(boundlessLayerDownShift);
chaviw25714502021-02-11 10:01:08 -0800891 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700892 t.setColor(colorLayer, half3{0, 0, 0});
893 t.show(colorLayer);
894 });
895 {
896 mCapture = screenshot();
897 // Top left of background must now be visible
898 mCapture->expectBGColor(0, 0);
899 // Top left of foreground must now be visible
900 mCapture->expectFGColor(64, 64);
901 // Foreground Surface bounds must be color layer
902 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
903 // Color layer should not extend past foreground bounds
904 mCapture->expectBGColor(129, 129);
905 }
906}
907
908// Verify child layers do not get clipped if they temporarily move into the negative
909// coordinate space as the result of an intermediate transformation.
910TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
911 sp<SurfaceControl> boundlessLayer =
912 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -0700913 0 /* flags */, mFGSurfaceControl->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700914 ASSERT_TRUE(boundlessLayer != nullptr);
915 ASSERT_TRUE(boundlessLayer->isValid());
916 sp<SurfaceControl> colorLayer =
917 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -0700918 ISurfaceComposerClient::eFXSurfaceEffect,
919 boundlessLayer->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700920 ASSERT_TRUE(colorLayer != nullptr);
921 ASSERT_TRUE(colorLayer->isValid());
922 asTransaction([&](Transaction& t) {
923 // shift child layer off bounds. If this layer was not boundless, we will
924 // expect the child layer to be cropped.
925 t.setPosition(boundlessLayer, 32, 32);
926 t.show(boundlessLayer);
chaviw25714502021-02-11 10:01:08 -0800927 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700928 // undo shift by parent
929 t.setPosition(colorLayer, -32, -32);
930 t.setColor(colorLayer, half3{0, 0, 0});
931 t.show(colorLayer);
932 });
933 {
934 mCapture = screenshot();
935 // Top left of background must now be visible
936 mCapture->expectBGColor(0, 0);
937 // Foreground Surface bounds must be color layer
938 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
939 // Color layer should not extend past foreground bounds
940 mCapture->expectBGColor(129, 129);
941 }
942}
943
944// Verify for boundless root layers with children, their transforms have an effect.
945TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
946 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
947 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
948 ASSERT_TRUE(rootBoundlessLayer->isValid());
949 sp<SurfaceControl> colorLayer =
950 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800951 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700952
953 ASSERT_TRUE(colorLayer->isValid());
954 asTransaction([&](Transaction& t) {
955 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
956 t.setPosition(rootBoundlessLayer, 32, 32);
957 t.show(rootBoundlessLayer);
chaviw25714502021-02-11 10:01:08 -0800958 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700959 t.setColor(colorLayer, half3{0, 0, 0});
960 t.show(colorLayer);
961 t.hide(mFGSurfaceControl);
962 });
963 {
964 mCapture = screenshot();
965 // Top left of background must now be visible
966 mCapture->expectBGColor(0, 0);
967 // Top left of foreground must now be visible
968 mCapture->expectBGColor(31, 31);
969 // Foreground Surface bounds must be color layer
970 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
971 // Color layer should not extend past foreground bounds
972 mCapture->expectBGColor(97, 97);
973 }
974}
975
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700976} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800977
978// TODO(b/129481165): remove the #pragma below and fix conversion issues
979#pragma clang diagnostic pop // ignored "-Wconversion"