blob: c56d4733949c036bd7b1c20936439d18019684f8 [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
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080039 DisplayConfig config;
40 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(display, &config));
41 const ui::Size& resolution = config.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);
134 t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 64, 64));
135 });
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
163TEST_F(LayerUpdateTest, DeferredTransactionTest) {
164 std::unique_ptr<ScreenCapture> sc;
165 {
166 SCOPED_TRACE("before anything");
167 ScreenCapture::captureScreen(&sc);
168 sc->expectBGColor(32, 32);
169 sc->expectFGColor(96, 96);
170 sc->expectBGColor(160, 160);
171 }
172
173 // set up two deferred transactions on different frames
174 asTransaction([&](Transaction& t) {
175 t.setAlpha(mFGSurfaceControl, 0.75);
176 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
177 mSyncSurfaceControl->getSurface()->getNextFrameNumber());
178 });
179
180 asTransaction([&](Transaction& t) {
181 t.setPosition(mFGSurfaceControl, 128, 128);
182 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
183 mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1);
184 });
185
186 {
187 SCOPED_TRACE("before any trigger");
188 ScreenCapture::captureScreen(&sc);
189 sc->expectBGColor(32, 32);
190 sc->expectFGColor(96, 96);
191 sc->expectBGColor(160, 160);
192 }
193
194 // should trigger the first deferred transaction, but not the second one
195 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
196 {
197 SCOPED_TRACE("after first trigger");
198 ScreenCapture::captureScreen(&sc);
199 sc->expectBGColor(32, 32);
200 sc->checkPixel(96, 96, 162, 63, 96);
201 sc->expectBGColor(160, 160);
202 }
203
204 // should show up immediately since it's not deferred
205 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 1.0); });
206
207 // trigger the second deferred transaction
208 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
209 {
210 SCOPED_TRACE("after second trigger");
211 ScreenCapture::captureScreen(&sc);
212 sc->expectBGColor(32, 32);
213 sc->expectBGColor(96, 96);
214 sc->expectFGColor(160, 160);
215 }
216}
217
218TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
219 std::unique_ptr<ScreenCapture> sc;
220
221 sp<SurfaceControl> childNoBuffer =
222 createSurface(mClient, "Bufferless child", 0 /* buffer width */, 0 /* buffer height */,
223 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
224 sp<SurfaceControl> childBuffer = createSurface(mClient, "Buffered child", 20, 20,
225 PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
226 TransactionUtils::fillSurfaceRGBA8(childBuffer, 200, 200, 200);
227 SurfaceComposerClient::Transaction{}
228 .setCrop_legacy(childNoBuffer, Rect(0, 0, 10, 10))
229 .show(childNoBuffer)
230 .show(childBuffer)
231 .apply(true);
232 {
233 ScreenCapture::captureScreen(&sc);
234 sc->expectChildColor(73, 73);
235 sc->expectFGColor(74, 74);
236 }
237 SurfaceComposerClient::Transaction{}
238 .setCrop_legacy(childNoBuffer, Rect(0, 0, 20, 20))
239 .apply(true);
240 {
241 ScreenCapture::captureScreen(&sc);
242 sc->expectChildColor(73, 73);
243 sc->expectChildColor(74, 74);
244 }
245}
246
247TEST_F(LayerUpdateTest, MergingTransactions) {
248 std::unique_ptr<ScreenCapture> sc;
249 {
250 SCOPED_TRACE("before move");
251 ScreenCapture::captureScreen(&sc);
252 sc->expectBGColor(0, 12);
253 sc->expectFGColor(75, 75);
254 sc->expectBGColor(145, 145);
255 }
256
257 Transaction t1, t2;
258 t1.setPosition(mFGSurfaceControl, 128, 128);
259 t2.setPosition(mFGSurfaceControl, 0, 0);
260 // We expect that the position update from t2 now
261 // overwrites the position update from t1.
262 t1.merge(std::move(t2));
263 t1.apply();
264
265 {
266 ScreenCapture::captureScreen(&sc);
267 sc->expectFGColor(1, 1);
268 }
269}
270
271TEST_F(LayerUpdateTest, MergingTransactionFlags) {
272 Transaction().hide(mFGSurfaceControl).apply();
273 std::unique_ptr<ScreenCapture> sc;
274 {
275 SCOPED_TRACE("before merge");
276 ScreenCapture::captureScreen(&sc);
277 sc->expectBGColor(0, 12);
278 sc->expectBGColor(75, 75);
279 sc->expectBGColor(145, 145);
280 }
281
282 Transaction t1, t2;
283 t1.show(mFGSurfaceControl);
284 t2.setFlags(mFGSurfaceControl, 0 /* flags */, layer_state_t::eLayerSecure /* mask */);
285 t1.merge(std::move(t2));
286 t1.apply();
287
288 {
289 SCOPED_TRACE("after merge");
290 ScreenCapture::captureScreen(&sc);
291 sc->expectFGColor(75, 75);
292 }
293}
294
295class ChildLayerTest : public LayerUpdateTest {
296protected:
297 void SetUp() override {
298 LayerUpdateTest::SetUp();
299 mChild = createSurface(mClient, "Child surface", 10, 15, PIXEL_FORMAT_RGBA_8888, 0,
300 mFGSurfaceControl.get());
301 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
302
303 {
304 SCOPED_TRACE("before anything");
305 mCapture = screenshot();
306 mCapture->expectChildColor(64, 64);
307 }
308 }
309 void TearDown() override {
310 LayerUpdateTest::TearDown();
311 mChild = 0;
312 }
313
314 sp<SurfaceControl> mChild;
315 std::unique_ptr<ScreenCapture> mCapture;
316};
317
318TEST_F(ChildLayerTest, ChildLayerPositioning) {
319 asTransaction([&](Transaction& t) {
320 t.show(mChild);
321 t.setPosition(mChild, 10, 10);
322 t.setPosition(mFGSurfaceControl, 64, 64);
323 });
324
325 {
326 mCapture = screenshot();
327 // Top left of foreground must now be visible
328 mCapture->expectFGColor(64, 64);
329 // But 10 pixels in we should see the child surface
330 mCapture->expectChildColor(74, 74);
331 // And 10 more pixels we should be back to the foreground surface
332 mCapture->expectFGColor(84, 84);
333 }
334
335 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
336
337 {
338 mCapture = screenshot();
339 // Top left of foreground should now be at 0, 0
340 mCapture->expectFGColor(0, 0);
341 // But 10 pixels in we should see the child surface
342 mCapture->expectChildColor(10, 10);
343 // And 10 more pixels we should be back to the foreground surface
344 mCapture->expectFGColor(20, 20);
345 }
346}
347
348TEST_F(ChildLayerTest, ChildLayerCropping) {
349 asTransaction([&](Transaction& t) {
350 t.show(mChild);
351 t.setPosition(mChild, 0, 0);
352 t.setPosition(mFGSurfaceControl, 0, 0);
353 t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5));
354 });
355
356 {
357 mCapture = screenshot();
358 mCapture->expectChildColor(0, 0);
359 mCapture->expectChildColor(4, 4);
360 mCapture->expectBGColor(5, 5);
361 }
362}
363
364TEST_F(ChildLayerTest, ChildLayerConstraints) {
365 asTransaction([&](Transaction& t) {
366 t.show(mChild);
367 t.setPosition(mFGSurfaceControl, 0, 0);
368 t.setPosition(mChild, 63, 63);
369 });
370
371 {
372 mCapture = screenshot();
373 mCapture->expectFGColor(0, 0);
374 // Last pixel in foreground should now be the child.
375 mCapture->expectChildColor(63, 63);
376 // But the child should be constrained and the next pixel
377 // must be the background
378 mCapture->expectBGColor(64, 64);
379 }
380}
381
382TEST_F(ChildLayerTest, ChildLayerScaling) {
383 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
384
385 // Find the boundary between the parent and child
386 {
387 mCapture = screenshot();
388 mCapture->expectChildColor(9, 9);
389 mCapture->expectFGColor(10, 10);
390 }
391
392 asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
393
394 // The boundary should be twice as far from the origin now.
395 // The pixels from the last test should all be child now
396 {
397 mCapture = screenshot();
398 mCapture->expectChildColor(9, 9);
399 mCapture->expectChildColor(10, 10);
400 mCapture->expectChildColor(19, 19);
401 mCapture->expectFGColor(20, 20);
402 }
403}
404
405// A child with a scale transform should be cropped by its parent bounds.
406TEST_F(ChildLayerTest, ChildLayerScalingCroppedByParent) {
407 asTransaction([&](Transaction& t) {
408 t.setPosition(mFGSurfaceControl, 0, 0);
409 t.setPosition(mChild, 0, 0);
410 });
411
412 // Find the boundary between the parent and child.
413 {
414 mCapture = screenshot();
415 mCapture->expectChildColor(0, 0);
416 mCapture->expectChildColor(9, 9);
417 mCapture->expectFGColor(10, 10);
418 }
419
420 asTransaction([&](Transaction& t) { t.setMatrix(mChild, 10.0, 0, 0, 10.0); });
421
422 // The child should fill its parent bounds and be cropped by it.
423 {
424 mCapture = screenshot();
425 mCapture->expectChildColor(0, 0);
426 mCapture->expectChildColor(63, 63);
427 mCapture->expectBGColor(64, 64);
428 }
429}
430
431TEST_F(ChildLayerTest, ChildLayerAlpha) {
432 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
433 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
434 TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
435 waitForPostedBuffers();
436
437 asTransaction([&](Transaction& t) {
438 t.show(mChild);
439 t.setPosition(mChild, 0, 0);
440 t.setPosition(mFGSurfaceControl, 0, 0);
441 });
442
443 {
444 mCapture = screenshot();
445 // Unblended child color
446 mCapture->checkPixel(0, 0, 0, 254, 0);
447 }
448
449 asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
450
451 {
452 mCapture = screenshot();
453 // Child and BG blended.
454 mCapture->checkPixel(0, 0, 127, 127, 0);
455 }
456
457 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
458
459 {
460 mCapture = screenshot();
461 // Child and BG blended.
462 mCapture->checkPixel(0, 0, 95, 64, 95);
463 }
464}
465
466TEST_F(ChildLayerTest, ReparentChildren) {
467 asTransaction([&](Transaction& t) {
468 t.show(mChild);
469 t.setPosition(mChild, 10, 10);
470 t.setPosition(mFGSurfaceControl, 64, 64);
471 });
472
473 {
474 mCapture = screenshot();
475 // Top left of foreground must now be visible
476 mCapture->expectFGColor(64, 64);
477 // But 10 pixels in we should see the child surface
478 mCapture->expectChildColor(74, 74);
479 // And 10 more pixels we should be back to the foreground surface
480 mCapture->expectFGColor(84, 84);
481 }
482
483 asTransaction([&](Transaction& t) {
484 t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle());
485 });
486
487 {
488 mCapture = screenshot();
489 mCapture->expectFGColor(64, 64);
490 // In reparenting we should have exposed the entire foreground surface.
491 mCapture->expectFGColor(74, 74);
492 // And the child layer should now begin at 10, 10 (since the BG
493 // layer is at (0, 0)).
494 mCapture->expectBGColor(9, 9);
495 mCapture->expectChildColor(10, 10);
496 }
497}
498
499TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
500 sp<SurfaceControl> mGrandChild =
501 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
502 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
503
504 {
505 SCOPED_TRACE("Grandchild visible");
506 ScreenCapture::captureScreen(&mCapture);
507 mCapture->checkPixel(64, 64, 111, 111, 111);
508 }
509
Robert Carr0e328f62020-02-06 17:12:08 -0800510 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700511 mChild.clear();
512
513 {
514 SCOPED_TRACE("After destroying child");
515 ScreenCapture::captureScreen(&mCapture);
516 mCapture->expectFGColor(64, 64);
517 }
518
519 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl->getHandle()); });
520
521 {
522 SCOPED_TRACE("After reparenting grandchild");
523 ScreenCapture::captureScreen(&mCapture);
524 mCapture->checkPixel(64, 64, 111, 111, 111);
525 }
526}
527
528TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
529 sp<SurfaceControl> mGrandChild =
530 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
531 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
532
533 // draw grand child behind the foreground surface
534 asTransaction([&](Transaction& t) {
535 t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1);
536 });
537
538 {
539 SCOPED_TRACE("Child visible");
540 ScreenCapture::captureScreen(&mCapture);
541 mCapture->checkPixel(64, 64, 200, 200, 200);
542 }
543
544 asTransaction([&](Transaction& t) {
545 t.reparent(mChild, nullptr);
546 t.reparentChildren(mChild, mFGSurfaceControl->getHandle());
547 });
548
549 {
550 SCOPED_TRACE("foreground visible reparenting grandchild");
551 ScreenCapture::captureScreen(&mCapture);
552 mCapture->checkPixel(64, 64, 195, 63, 63);
553 }
554}
555
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700556TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
557 asTransaction([&](Transaction& t) {
558 t.show(mChild);
559 t.setPosition(mChild, 0, 0);
560 t.setPosition(mFGSurfaceControl, 0, 0);
561 });
562
563 {
564 mCapture = screenshot();
565 // We've positioned the child in the top left.
566 mCapture->expectChildColor(0, 0);
567 // But it's only 10x15.
568 mCapture->expectFGColor(10, 15);
569 }
570
571 asTransaction([&](Transaction& t) {
572 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
573 // We cause scaling by 2.
574 t.setSize(mFGSurfaceControl, 128, 128);
575 });
576
577 {
578 mCapture = screenshot();
579 // We've positioned the child in the top left.
580 mCapture->expectChildColor(0, 0);
581 mCapture->expectChildColor(10, 10);
582 mCapture->expectChildColor(19, 29);
583 // And now it should be scaled all the way to 20x30
584 mCapture->expectFGColor(20, 30);
585 }
586}
587
588// Regression test for b/37673612
589TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
590 asTransaction([&](Transaction& t) {
591 t.show(mChild);
592 t.setPosition(mChild, 0, 0);
593 t.setPosition(mFGSurfaceControl, 0, 0);
594 });
595
596 {
597 mCapture = screenshot();
598 // We've positioned the child in the top left.
599 mCapture->expectChildColor(0, 0);
600 mCapture->expectChildColor(9, 14);
601 // But it's only 10x15.
602 mCapture->expectFGColor(10, 15);
603 }
604 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
605 // the WM specified state size.
606 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
607 sp<Surface> s = mFGSurfaceControl->getSurface();
608 auto anw = static_cast<ANativeWindow*>(s.get());
609 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
610 native_window_set_buffers_dimensions(anw, 64, 128);
611 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
612 waitForPostedBuffers();
613
614 {
615 // The child should still be in the same place and not have any strange scaling as in
616 // b/37673612.
617 mCapture = screenshot();
618 mCapture->expectChildColor(0, 0);
619 mCapture->expectFGColor(10, 10);
620 }
621}
622
623// A child with a buffer transform from its parents should be cropped by its parent bounds.
624TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
625 asTransaction([&](Transaction& t) {
626 t.show(mChild);
627 t.setPosition(mChild, 0, 0);
628 t.setPosition(mFGSurfaceControl, 0, 0);
629 t.setSize(mChild, 100, 100);
630 });
631 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
632
633 {
634 mCapture = screenshot();
635
636 mCapture->expectChildColor(0, 0);
637 mCapture->expectChildColor(63, 63);
638 mCapture->expectBGColor(64, 64);
639 }
640
641 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
642 sp<Surface> s = mFGSurfaceControl->getSurface();
643 auto anw = static_cast<ANativeWindow*>(s.get());
644 // Apply a 90 transform on the buffer.
645 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
646 native_window_set_buffers_dimensions(anw, 64, 128);
647 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
648 waitForPostedBuffers();
649
650 // The child should be cropped by the new parent bounds.
651 {
652 mCapture = screenshot();
653 mCapture->expectChildColor(0, 0);
654 mCapture->expectChildColor(99, 63);
655 mCapture->expectFGColor(100, 63);
656 mCapture->expectBGColor(128, 64);
657 }
658}
659
660// A child with a scale transform from its parents should be cropped by its parent bounds.
661TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
662 asTransaction([&](Transaction& t) {
663 t.show(mChild);
664 t.setPosition(mChild, 0, 0);
665 t.setPosition(mFGSurfaceControl, 0, 0);
666 t.setSize(mChild, 200, 200);
667 });
668 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
669
670 {
671 mCapture = screenshot();
672
673 mCapture->expectChildColor(0, 0);
674 mCapture->expectChildColor(63, 63);
675 mCapture->expectBGColor(64, 64);
676 }
677
678 asTransaction([&](Transaction& t) {
679 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
680 // Set a scaling by 2.
681 t.setSize(mFGSurfaceControl, 128, 128);
682 });
683
684 // Child should inherit its parents scale but should be cropped by its parent bounds.
685 {
686 mCapture = screenshot();
687 mCapture->expectChildColor(0, 0);
688 mCapture->expectChildColor(127, 127);
689 mCapture->expectBGColor(128, 128);
690 }
691}
692
693// Regression test for b/127368943
694// Child should ignore the buffer transform but apply parent scale transform.
695TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
696 asTransaction([&](Transaction& t) {
697 t.show(mChild);
698 t.setPosition(mChild, 0, 0);
699 t.setPosition(mFGSurfaceControl, 0, 0);
700 });
701
702 {
703 mCapture = screenshot();
704 mCapture->expectChildColor(0, 0);
705 mCapture->expectChildColor(9, 14);
706 mCapture->expectFGColor(10, 15);
707 }
708
709 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
710 asTransaction([&](Transaction& t) {
711 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
712 t.setSize(mFGSurfaceControl, 128, 64);
713 });
714 sp<Surface> s = mFGSurfaceControl->getSurface();
715 auto anw = static_cast<ANativeWindow*>(s.get());
716 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
717 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
718 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
719 native_window_set_buffers_dimensions(anw, 32, 64);
720 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
721 waitForPostedBuffers();
722
723 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
724 {
725 mCapture = screenshot();
726 mCapture->expectChildColor(0, 0);
727 mCapture->expectChildColor(19, 29);
728 mCapture->expectFGColor(20, 30);
729 }
730}
731
732TEST_F(ChildLayerTest, Bug36858924) {
733 // Destroy the child layer
734 mChild.clear();
735
736 // Now recreate it as hidden
737 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
738 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
739
740 // Show the child layer in a deferred transaction
741 asTransaction([&](Transaction& t) {
742 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl->getHandle(),
743 mFGSurfaceControl->getSurface()->getNextFrameNumber());
744 t.show(mChild);
745 });
746
747 // Render the foreground surface a few times
748 //
749 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
750 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
751 // never acquire/release the first buffer
752 ALOGI("Filling 1");
753 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
754 ALOGI("Filling 2");
755 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
756 ALOGI("Filling 3");
757 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
758 ALOGI("Filling 4");
759 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
760}
761
762TEST_F(ChildLayerTest, Reparent) {
763 asTransaction([&](Transaction& t) {
764 t.show(mChild);
765 t.setPosition(mChild, 10, 10);
766 t.setPosition(mFGSurfaceControl, 64, 64);
767 });
768
769 {
770 mCapture = screenshot();
771 // Top left of foreground must now be visible
772 mCapture->expectFGColor(64, 64);
773 // But 10 pixels in we should see the child surface
774 mCapture->expectChildColor(74, 74);
775 // And 10 more pixels we should be back to the foreground surface
776 mCapture->expectFGColor(84, 84);
777 }
778
779 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl->getHandle()); });
780
781 {
782 mCapture = screenshot();
783 mCapture->expectFGColor(64, 64);
784 // In reparenting we should have exposed the entire foreground surface.
785 mCapture->expectFGColor(74, 74);
786 // And the child layer should now begin at 10, 10 (since the BG
787 // layer is at (0, 0)).
788 mCapture->expectBGColor(9, 9);
789 mCapture->expectChildColor(10, 10);
790 }
791}
792
793TEST_F(ChildLayerTest, ReparentToNoParent) {
794 asTransaction([&](Transaction& t) {
795 t.show(mChild);
796 t.setPosition(mChild, 10, 10);
797 t.setPosition(mFGSurfaceControl, 64, 64);
798 });
799
800 {
801 mCapture = screenshot();
802 // Top left of foreground must now be visible
803 mCapture->expectFGColor(64, 64);
804 // But 10 pixels in we should see the child surface
805 mCapture->expectChildColor(74, 74);
806 // And 10 more pixels we should be back to the foreground surface
807 mCapture->expectFGColor(84, 84);
808 }
809 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
810 {
811 mCapture = screenshot();
812 // The surface should now be offscreen.
813 mCapture->expectFGColor(64, 64);
814 mCapture->expectFGColor(74, 74);
815 mCapture->expectFGColor(84, 84);
816 }
817}
818
819TEST_F(ChildLayerTest, ReparentFromNoParent) {
820 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
821 ASSERT_TRUE(newSurface != nullptr);
822 ASSERT_TRUE(newSurface->isValid());
823
824 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
825 asTransaction([&](Transaction& t) {
826 t.hide(mChild);
827 t.show(newSurface);
828 t.setPosition(newSurface, 10, 10);
829 t.setLayer(newSurface, INT32_MAX - 2);
830 t.setPosition(mFGSurfaceControl, 64, 64);
831 });
832
833 {
834 mCapture = screenshot();
835 // Top left of foreground must now be visible
836 mCapture->expectFGColor(64, 64);
837 // At 10, 10 we should see the new surface
838 mCapture->checkPixel(10, 10, 63, 195, 63);
839 }
840
841 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl->getHandle()); });
842
843 {
844 mCapture = screenshot();
845 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
846 // mFGSurface, putting it at 74, 74.
847 mCapture->expectFGColor(64, 64);
848 mCapture->checkPixel(74, 74, 63, 195, 63);
849 mCapture->expectFGColor(84, 84);
850 }
851}
852
853TEST_F(ChildLayerTest, NestedChildren) {
854 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
855 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
856 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
857
858 {
859 mCapture = screenshot();
860 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
861 // which begins at 64, 64
862 mCapture->checkPixel(64, 64, 50, 50, 50);
863 }
864}
865
866TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
867 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
868 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
869
870 Transaction t;
871 t.setLayer(relative, INT32_MAX)
872 .setRelativeLayer(mChild, relative->getHandle(), 1)
873 .setPosition(mFGSurfaceControl, 0, 0)
874 .apply(true);
875
876 // We expect that the child should have been elevated above our
877 // INT_MAX layer even though it's not a child of it.
878 {
879 mCapture = screenshot();
880 mCapture->expectChildColor(0, 0);
881 mCapture->expectChildColor(9, 9);
882 mCapture->checkPixel(10, 10, 255, 255, 255);
883 }
884}
885
886class BoundlessLayerTest : public LayerUpdateTest {
887protected:
888 std::unique_ptr<ScreenCapture> mCapture;
889};
890
891// Verify setting a size on a buffer layer has no effect.
892TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
893 sp<SurfaceControl> bufferLayer =
894 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
895 mFGSurfaceControl.get());
896 ASSERT_TRUE(bufferLayer->isValid());
897 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
898 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
899 {
900 mCapture = screenshot();
901 // Top left of background must now be visible
902 mCapture->expectBGColor(0, 0);
903 // Foreground Surface bounds must be color layer
904 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
905 // Buffer layer should not extend past buffer bounds
906 mCapture->expectFGColor(95, 95);
907 }
908}
909
910// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
911// which will crop the color layer.
912TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
913 sp<SurfaceControl> colorLayer =
914 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800915 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700916 ASSERT_TRUE(colorLayer->isValid());
917 asTransaction([&](Transaction& t) {
918 t.setColor(colorLayer, half3{0, 0, 0});
919 t.show(colorLayer);
920 });
921 {
922 mCapture = screenshot();
923 // Top left of background must now be visible
924 mCapture->expectBGColor(0, 0);
925 // Foreground Surface bounds must be color layer
926 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
927 // Color layer should not extend past foreground bounds
928 mCapture->expectBGColor(129, 129);
929 }
930}
931
932// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
933// a crop which will be used to crop the color layer.
934TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
935 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
936 0 /* flags */, mFGSurfaceControl.get());
937 ASSERT_TRUE(cropLayer->isValid());
938 sp<SurfaceControl> colorLayer =
939 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800940 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700941 ASSERT_TRUE(colorLayer->isValid());
942 asTransaction([&](Transaction& t) {
943 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
944 t.setColor(colorLayer, half3{0, 0, 0});
945 t.show(cropLayer);
946 t.show(colorLayer);
947 });
948 {
949 mCapture = screenshot();
950 // Top left of background must now be visible
951 mCapture->expectBGColor(0, 0);
952 // Top left of foreground must now be visible
953 mCapture->expectFGColor(64, 64);
954 // 5 pixels from the foreground we should see the child surface
955 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
956 // 10 pixels from the foreground we should be back to the foreground surface
957 mCapture->expectFGColor(74, 74);
958 }
959}
960
961// Verify for boundless layer with no children, their transforms have no effect.
962TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
963 sp<SurfaceControl> colorLayer =
964 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800965 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700966 ASSERT_TRUE(colorLayer->isValid());
967 asTransaction([&](Transaction& t) {
968 t.setPosition(colorLayer, 320, 320);
969 t.setMatrix(colorLayer, 2, 0, 0, 2);
970 t.setColor(colorLayer, half3{0, 0, 0});
971 t.show(colorLayer);
972 });
973 {
974 mCapture = screenshot();
975 // Top left of background must now be visible
976 mCapture->expectBGColor(0, 0);
977 // Foreground Surface bounds must be color layer
978 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
979 // Color layer should not extend past foreground bounds
980 mCapture->expectBGColor(129, 129);
981 }
982}
983
984// Verify for boundless layer with children, their transforms have an effect.
985TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
986 sp<SurfaceControl> boundlessLayerRightShift =
987 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
988 0 /* flags */, mFGSurfaceControl.get());
989 ASSERT_TRUE(boundlessLayerRightShift->isValid());
990 sp<SurfaceControl> boundlessLayerDownShift =
991 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
992 0 /* flags */, boundlessLayerRightShift.get());
993 ASSERT_TRUE(boundlessLayerDownShift->isValid());
994 sp<SurfaceControl> colorLayer =
995 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800996 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700997 ASSERT_TRUE(colorLayer->isValid());
998 asTransaction([&](Transaction& t) {
999 t.setPosition(boundlessLayerRightShift, 32, 0);
1000 t.show(boundlessLayerRightShift);
1001 t.setPosition(boundlessLayerDownShift, 0, 32);
1002 t.show(boundlessLayerDownShift);
1003 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1004 t.setColor(colorLayer, half3{0, 0, 0});
1005 t.show(colorLayer);
1006 });
1007 {
1008 mCapture = screenshot();
1009 // Top left of background must now be visible
1010 mCapture->expectBGColor(0, 0);
1011 // Top left of foreground must now be visible
1012 mCapture->expectFGColor(64, 64);
1013 // Foreground Surface bounds must be color layer
1014 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1015 // Color layer should not extend past foreground bounds
1016 mCapture->expectBGColor(129, 129);
1017 }
1018}
1019
1020// Verify child layers do not get clipped if they temporarily move into the negative
1021// coordinate space as the result of an intermediate transformation.
1022TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1023 sp<SurfaceControl> boundlessLayer =
1024 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1025 0 /* flags */, mFGSurfaceControl.get());
1026 ASSERT_TRUE(boundlessLayer != nullptr);
1027 ASSERT_TRUE(boundlessLayer->isValid());
1028 sp<SurfaceControl> colorLayer =
1029 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001030 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001031 ASSERT_TRUE(colorLayer != nullptr);
1032 ASSERT_TRUE(colorLayer->isValid());
1033 asTransaction([&](Transaction& t) {
1034 // shift child layer off bounds. If this layer was not boundless, we will
1035 // expect the child layer to be cropped.
1036 t.setPosition(boundlessLayer, 32, 32);
1037 t.show(boundlessLayer);
1038 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1039 // undo shift by parent
1040 t.setPosition(colorLayer, -32, -32);
1041 t.setColor(colorLayer, half3{0, 0, 0});
1042 t.show(colorLayer);
1043 });
1044 {
1045 mCapture = screenshot();
1046 // Top left of background must now be visible
1047 mCapture->expectBGColor(0, 0);
1048 // Foreground Surface bounds must be color layer
1049 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1050 // Color layer should not extend past foreground bounds
1051 mCapture->expectBGColor(129, 129);
1052 }
1053}
1054
1055// Verify for boundless root layers with children, their transforms have an effect.
1056TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1057 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1058 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1059 ASSERT_TRUE(rootBoundlessLayer->isValid());
1060 sp<SurfaceControl> colorLayer =
1061 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001062 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001063
1064 ASSERT_TRUE(colorLayer->isValid());
1065 asTransaction([&](Transaction& t) {
1066 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1067 t.setPosition(rootBoundlessLayer, 32, 32);
1068 t.show(rootBoundlessLayer);
1069 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1070 t.setColor(colorLayer, half3{0, 0, 0});
1071 t.show(colorLayer);
1072 t.hide(mFGSurfaceControl);
1073 });
1074 {
1075 mCapture = screenshot();
1076 // Top left of background must now be visible
1077 mCapture->expectBGColor(0, 0);
1078 // Top left of foreground must now be visible
1079 mCapture->expectBGColor(31, 31);
1080 // Foreground Surface bounds must be color layer
1081 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1082 // Color layer should not extend past foreground bounds
1083 mCapture->expectBGColor(97, 97);
1084 }
1085}
1086
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001087} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001088
1089// TODO(b/129481165): remove the #pragma below and fix conversion issues
1090#pragma clang diagnostic pop // ignored "-Wconversion"