blob: 38da0b195bce98885ed5c14c18ee019788967eba [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);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000176 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700177 mSyncSurfaceControl->getSurface()->getNextFrameNumber());
178 });
179
180 asTransaction([&](Transaction& t) {
181 t.setPosition(mFGSurfaceControl, 128, 128);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000182 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700183 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
Pablo Gamito11dcc222020-09-12 15:49:39 +0000483 asTransaction(
484 [&](Transaction& t) { t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700485
486 {
487 mCapture = screenshot();
488 mCapture->expectFGColor(64, 64);
489 // In reparenting we should have exposed the entire foreground surface.
490 mCapture->expectFGColor(74, 74);
491 // And the child layer should now begin at 10, 10 (since the BG
492 // layer is at (0, 0)).
493 mCapture->expectBGColor(9, 9);
494 mCapture->expectChildColor(10, 10);
495 }
496}
497
498TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
499 sp<SurfaceControl> mGrandChild =
500 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
501 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
502
503 {
504 SCOPED_TRACE("Grandchild visible");
505 ScreenCapture::captureScreen(&mCapture);
506 mCapture->checkPixel(64, 64, 111, 111, 111);
507 }
508
Robert Carr0e328f62020-02-06 17:12:08 -0800509 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700510 mChild.clear();
511
512 {
513 SCOPED_TRACE("After destroying child");
514 ScreenCapture::captureScreen(&mCapture);
515 mCapture->expectFGColor(64, 64);
516 }
517
Pablo Gamito11dcc222020-09-12 15:49:39 +0000518 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700519
520 {
521 SCOPED_TRACE("After reparenting grandchild");
522 ScreenCapture::captureScreen(&mCapture);
523 mCapture->checkPixel(64, 64, 111, 111, 111);
524 }
525}
526
527TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
528 sp<SurfaceControl> mGrandChild =
529 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
530 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
531
532 // draw grand child behind the foreground surface
Pablo Gamito11dcc222020-09-12 15:49:39 +0000533 asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700534
535 {
536 SCOPED_TRACE("Child visible");
537 ScreenCapture::captureScreen(&mCapture);
538 mCapture->checkPixel(64, 64, 200, 200, 200);
539 }
540
541 asTransaction([&](Transaction& t) {
542 t.reparent(mChild, nullptr);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000543 t.reparentChildren(mChild, mFGSurfaceControl);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700544 });
545
546 {
547 SCOPED_TRACE("foreground visible reparenting grandchild");
548 ScreenCapture::captureScreen(&mCapture);
549 mCapture->checkPixel(64, 64, 195, 63, 63);
550 }
551}
552
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700553TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
554 asTransaction([&](Transaction& t) {
555 t.show(mChild);
556 t.setPosition(mChild, 0, 0);
557 t.setPosition(mFGSurfaceControl, 0, 0);
558 });
559
560 {
561 mCapture = screenshot();
562 // We've positioned the child in the top left.
563 mCapture->expectChildColor(0, 0);
564 // But it's only 10x15.
565 mCapture->expectFGColor(10, 15);
566 }
567
568 asTransaction([&](Transaction& t) {
569 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
570 // We cause scaling by 2.
571 t.setSize(mFGSurfaceControl, 128, 128);
572 });
573
574 {
575 mCapture = screenshot();
576 // We've positioned the child in the top left.
577 mCapture->expectChildColor(0, 0);
578 mCapture->expectChildColor(10, 10);
579 mCapture->expectChildColor(19, 29);
580 // And now it should be scaled all the way to 20x30
581 mCapture->expectFGColor(20, 30);
582 }
583}
584
585// Regression test for b/37673612
586TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
587 asTransaction([&](Transaction& t) {
588 t.show(mChild);
589 t.setPosition(mChild, 0, 0);
590 t.setPosition(mFGSurfaceControl, 0, 0);
591 });
592
593 {
594 mCapture = screenshot();
595 // We've positioned the child in the top left.
596 mCapture->expectChildColor(0, 0);
597 mCapture->expectChildColor(9, 14);
598 // But it's only 10x15.
599 mCapture->expectFGColor(10, 15);
600 }
601 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
602 // the WM specified state size.
603 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
604 sp<Surface> s = mFGSurfaceControl->getSurface();
605 auto anw = static_cast<ANativeWindow*>(s.get());
606 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
607 native_window_set_buffers_dimensions(anw, 64, 128);
608 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
609 waitForPostedBuffers();
610
611 {
612 // The child should still be in the same place and not have any strange scaling as in
613 // b/37673612.
614 mCapture = screenshot();
615 mCapture->expectChildColor(0, 0);
616 mCapture->expectFGColor(10, 10);
617 }
618}
619
620// A child with a buffer transform from its parents should be cropped by its parent bounds.
621TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
622 asTransaction([&](Transaction& t) {
623 t.show(mChild);
624 t.setPosition(mChild, 0, 0);
625 t.setPosition(mFGSurfaceControl, 0, 0);
626 t.setSize(mChild, 100, 100);
627 });
628 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
629
630 {
631 mCapture = screenshot();
632
633 mCapture->expectChildColor(0, 0);
634 mCapture->expectChildColor(63, 63);
635 mCapture->expectBGColor(64, 64);
636 }
637
638 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
639 sp<Surface> s = mFGSurfaceControl->getSurface();
640 auto anw = static_cast<ANativeWindow*>(s.get());
641 // Apply a 90 transform on the buffer.
642 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
643 native_window_set_buffers_dimensions(anw, 64, 128);
644 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
645 waitForPostedBuffers();
646
647 // The child should be cropped by the new parent bounds.
648 {
649 mCapture = screenshot();
650 mCapture->expectChildColor(0, 0);
651 mCapture->expectChildColor(99, 63);
652 mCapture->expectFGColor(100, 63);
653 mCapture->expectBGColor(128, 64);
654 }
655}
656
657// A child with a scale transform from its parents should be cropped by its parent bounds.
658TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
659 asTransaction([&](Transaction& t) {
660 t.show(mChild);
661 t.setPosition(mChild, 0, 0);
662 t.setPosition(mFGSurfaceControl, 0, 0);
663 t.setSize(mChild, 200, 200);
664 });
665 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
666
667 {
668 mCapture = screenshot();
669
670 mCapture->expectChildColor(0, 0);
671 mCapture->expectChildColor(63, 63);
672 mCapture->expectBGColor(64, 64);
673 }
674
675 asTransaction([&](Transaction& t) {
676 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
677 // Set a scaling by 2.
678 t.setSize(mFGSurfaceControl, 128, 128);
679 });
680
681 // Child should inherit its parents scale but should be cropped by its parent bounds.
682 {
683 mCapture = screenshot();
684 mCapture->expectChildColor(0, 0);
685 mCapture->expectChildColor(127, 127);
686 mCapture->expectBGColor(128, 128);
687 }
688}
689
690// Regression test for b/127368943
691// Child should ignore the buffer transform but apply parent scale transform.
692TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
693 asTransaction([&](Transaction& t) {
694 t.show(mChild);
695 t.setPosition(mChild, 0, 0);
696 t.setPosition(mFGSurfaceControl, 0, 0);
697 });
698
699 {
700 mCapture = screenshot();
701 mCapture->expectChildColor(0, 0);
702 mCapture->expectChildColor(9, 14);
703 mCapture->expectFGColor(10, 15);
704 }
705
706 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
707 asTransaction([&](Transaction& t) {
708 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
709 t.setSize(mFGSurfaceControl, 128, 64);
710 });
711 sp<Surface> s = mFGSurfaceControl->getSurface();
712 auto anw = static_cast<ANativeWindow*>(s.get());
713 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
714 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
715 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
716 native_window_set_buffers_dimensions(anw, 32, 64);
717 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
718 waitForPostedBuffers();
719
720 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
721 {
722 mCapture = screenshot();
723 mCapture->expectChildColor(0, 0);
724 mCapture->expectChildColor(19, 29);
725 mCapture->expectFGColor(20, 30);
726 }
727}
728
729TEST_F(ChildLayerTest, Bug36858924) {
730 // Destroy the child layer
731 mChild.clear();
732
733 // Now recreate it as hidden
734 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
735 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
736
737 // Show the child layer in a deferred transaction
738 asTransaction([&](Transaction& t) {
Pablo Gamito11dcc222020-09-12 15:49:39 +0000739 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700740 mFGSurfaceControl->getSurface()->getNextFrameNumber());
741 t.show(mChild);
742 });
743
744 // Render the foreground surface a few times
745 //
746 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
747 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
748 // never acquire/release the first buffer
749 ALOGI("Filling 1");
750 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
751 ALOGI("Filling 2");
752 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
753 ALOGI("Filling 3");
754 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
755 ALOGI("Filling 4");
756 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
757}
758
759TEST_F(ChildLayerTest, Reparent) {
760 asTransaction([&](Transaction& t) {
761 t.show(mChild);
762 t.setPosition(mChild, 10, 10);
763 t.setPosition(mFGSurfaceControl, 64, 64);
764 });
765
766 {
767 mCapture = screenshot();
768 // Top left of foreground must now be visible
769 mCapture->expectFGColor(64, 64);
770 // But 10 pixels in we should see the child surface
771 mCapture->expectChildColor(74, 74);
772 // And 10 more pixels we should be back to the foreground surface
773 mCapture->expectFGColor(84, 84);
774 }
775
Pablo Gamito11dcc222020-09-12 15:49:39 +0000776 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700777
778 {
779 mCapture = screenshot();
780 mCapture->expectFGColor(64, 64);
781 // In reparenting we should have exposed the entire foreground surface.
782 mCapture->expectFGColor(74, 74);
783 // And the child layer should now begin at 10, 10 (since the BG
784 // layer is at (0, 0)).
785 mCapture->expectBGColor(9, 9);
786 mCapture->expectChildColor(10, 10);
787 }
788}
789
790TEST_F(ChildLayerTest, ReparentToNoParent) {
791 asTransaction([&](Transaction& t) {
792 t.show(mChild);
793 t.setPosition(mChild, 10, 10);
794 t.setPosition(mFGSurfaceControl, 64, 64);
795 });
796
797 {
798 mCapture = screenshot();
799 // Top left of foreground must now be visible
800 mCapture->expectFGColor(64, 64);
801 // But 10 pixels in we should see the child surface
802 mCapture->expectChildColor(74, 74);
803 // And 10 more pixels we should be back to the foreground surface
804 mCapture->expectFGColor(84, 84);
805 }
806 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
807 {
808 mCapture = screenshot();
809 // The surface should now be offscreen.
810 mCapture->expectFGColor(64, 64);
811 mCapture->expectFGColor(74, 74);
812 mCapture->expectFGColor(84, 84);
813 }
814}
815
816TEST_F(ChildLayerTest, ReparentFromNoParent) {
817 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
818 ASSERT_TRUE(newSurface != nullptr);
819 ASSERT_TRUE(newSurface->isValid());
820
821 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
822 asTransaction([&](Transaction& t) {
823 t.hide(mChild);
824 t.show(newSurface);
825 t.setPosition(newSurface, 10, 10);
826 t.setLayer(newSurface, INT32_MAX - 2);
827 t.setPosition(mFGSurfaceControl, 64, 64);
828 });
829
830 {
831 mCapture = screenshot();
832 // Top left of foreground must now be visible
833 mCapture->expectFGColor(64, 64);
834 // At 10, 10 we should see the new surface
835 mCapture->checkPixel(10, 10, 63, 195, 63);
836 }
837
Pablo Gamito11dcc222020-09-12 15:49:39 +0000838 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700839
840 {
841 mCapture = screenshot();
842 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
843 // mFGSurface, putting it at 74, 74.
844 mCapture->expectFGColor(64, 64);
845 mCapture->checkPixel(74, 74, 63, 195, 63);
846 mCapture->expectFGColor(84, 84);
847 }
848}
849
850TEST_F(ChildLayerTest, NestedChildren) {
851 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
852 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
853 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
854
855 {
856 mCapture = screenshot();
857 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
858 // which begins at 64, 64
859 mCapture->checkPixel(64, 64, 50, 50, 50);
860 }
861}
862
863TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
864 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
865 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
866
867 Transaction t;
868 t.setLayer(relative, INT32_MAX)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000869 .setRelativeLayer(mChild, relative, 1)
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700870 .setPosition(mFGSurfaceControl, 0, 0)
871 .apply(true);
872
873 // We expect that the child should have been elevated above our
874 // INT_MAX layer even though it's not a child of it.
875 {
876 mCapture = screenshot();
877 mCapture->expectChildColor(0, 0);
878 mCapture->expectChildColor(9, 9);
879 mCapture->checkPixel(10, 10, 255, 255, 255);
880 }
881}
882
883class BoundlessLayerTest : public LayerUpdateTest {
884protected:
885 std::unique_ptr<ScreenCapture> mCapture;
886};
887
888// Verify setting a size on a buffer layer has no effect.
889TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
890 sp<SurfaceControl> bufferLayer =
891 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
892 mFGSurfaceControl.get());
893 ASSERT_TRUE(bufferLayer->isValid());
894 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
895 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
896 {
897 mCapture = screenshot();
898 // Top left of background must now be visible
899 mCapture->expectBGColor(0, 0);
900 // Foreground Surface bounds must be color layer
901 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
902 // Buffer layer should not extend past buffer bounds
903 mCapture->expectFGColor(95, 95);
904 }
905}
906
907// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
908// which will crop the color layer.
909TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
910 sp<SurfaceControl> colorLayer =
911 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800912 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700913 ASSERT_TRUE(colorLayer->isValid());
914 asTransaction([&](Transaction& t) {
915 t.setColor(colorLayer, half3{0, 0, 0});
916 t.show(colorLayer);
917 });
918 {
919 mCapture = screenshot();
920 // Top left of background must now be visible
921 mCapture->expectBGColor(0, 0);
922 // Foreground Surface bounds must be color layer
923 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
924 // Color layer should not extend past foreground bounds
925 mCapture->expectBGColor(129, 129);
926 }
927}
928
929// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
930// a crop which will be used to crop the color layer.
931TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
932 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
933 0 /* flags */, mFGSurfaceControl.get());
934 ASSERT_TRUE(cropLayer->isValid());
935 sp<SurfaceControl> colorLayer =
936 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800937 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700938 ASSERT_TRUE(colorLayer->isValid());
939 asTransaction([&](Transaction& t) {
940 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
941 t.setColor(colorLayer, half3{0, 0, 0});
942 t.show(cropLayer);
943 t.show(colorLayer);
944 });
945 {
946 mCapture = screenshot();
947 // Top left of background must now be visible
948 mCapture->expectBGColor(0, 0);
949 // Top left of foreground must now be visible
950 mCapture->expectFGColor(64, 64);
951 // 5 pixels from the foreground we should see the child surface
952 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
953 // 10 pixels from the foreground we should be back to the foreground surface
954 mCapture->expectFGColor(74, 74);
955 }
956}
957
958// Verify for boundless layer with no children, their transforms have no effect.
959TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
960 sp<SurfaceControl> colorLayer =
961 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800962 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700963 ASSERT_TRUE(colorLayer->isValid());
964 asTransaction([&](Transaction& t) {
965 t.setPosition(colorLayer, 320, 320);
966 t.setMatrix(colorLayer, 2, 0, 0, 2);
967 t.setColor(colorLayer, half3{0, 0, 0});
968 t.show(colorLayer);
969 });
970 {
971 mCapture = screenshot();
972 // Top left of background must now be visible
973 mCapture->expectBGColor(0, 0);
974 // Foreground Surface bounds must be color layer
975 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
976 // Color layer should not extend past foreground bounds
977 mCapture->expectBGColor(129, 129);
978 }
979}
980
981// Verify for boundless layer with children, their transforms have an effect.
982TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
983 sp<SurfaceControl> boundlessLayerRightShift =
984 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
985 0 /* flags */, mFGSurfaceControl.get());
986 ASSERT_TRUE(boundlessLayerRightShift->isValid());
987 sp<SurfaceControl> boundlessLayerDownShift =
988 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
989 0 /* flags */, boundlessLayerRightShift.get());
990 ASSERT_TRUE(boundlessLayerDownShift->isValid());
991 sp<SurfaceControl> colorLayer =
992 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800993 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700994 ASSERT_TRUE(colorLayer->isValid());
995 asTransaction([&](Transaction& t) {
996 t.setPosition(boundlessLayerRightShift, 32, 0);
997 t.show(boundlessLayerRightShift);
998 t.setPosition(boundlessLayerDownShift, 0, 32);
999 t.show(boundlessLayerDownShift);
1000 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1001 t.setColor(colorLayer, half3{0, 0, 0});
1002 t.show(colorLayer);
1003 });
1004 {
1005 mCapture = screenshot();
1006 // Top left of background must now be visible
1007 mCapture->expectBGColor(0, 0);
1008 // Top left of foreground must now be visible
1009 mCapture->expectFGColor(64, 64);
1010 // Foreground Surface bounds must be color layer
1011 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1012 // Color layer should not extend past foreground bounds
1013 mCapture->expectBGColor(129, 129);
1014 }
1015}
1016
1017// Verify child layers do not get clipped if they temporarily move into the negative
1018// coordinate space as the result of an intermediate transformation.
1019TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1020 sp<SurfaceControl> boundlessLayer =
1021 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1022 0 /* flags */, mFGSurfaceControl.get());
1023 ASSERT_TRUE(boundlessLayer != nullptr);
1024 ASSERT_TRUE(boundlessLayer->isValid());
1025 sp<SurfaceControl> colorLayer =
1026 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001027 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001028 ASSERT_TRUE(colorLayer != nullptr);
1029 ASSERT_TRUE(colorLayer->isValid());
1030 asTransaction([&](Transaction& t) {
1031 // shift child layer off bounds. If this layer was not boundless, we will
1032 // expect the child layer to be cropped.
1033 t.setPosition(boundlessLayer, 32, 32);
1034 t.show(boundlessLayer);
1035 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1036 // undo shift by parent
1037 t.setPosition(colorLayer, -32, -32);
1038 t.setColor(colorLayer, half3{0, 0, 0});
1039 t.show(colorLayer);
1040 });
1041 {
1042 mCapture = screenshot();
1043 // Top left of background must now be visible
1044 mCapture->expectBGColor(0, 0);
1045 // Foreground Surface bounds must be color layer
1046 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1047 // Color layer should not extend past foreground bounds
1048 mCapture->expectBGColor(129, 129);
1049 }
1050}
1051
1052// Verify for boundless root layers with children, their transforms have an effect.
1053TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1054 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1055 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1056 ASSERT_TRUE(rootBoundlessLayer->isValid());
1057 sp<SurfaceControl> colorLayer =
1058 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001059 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001060
1061 ASSERT_TRUE(colorLayer->isValid());
1062 asTransaction([&](Transaction& t) {
1063 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1064 t.setPosition(rootBoundlessLayer, 32, 32);
1065 t.show(rootBoundlessLayer);
1066 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1067 t.setColor(colorLayer, half3{0, 0, 0});
1068 t.show(colorLayer);
1069 t.hide(mFGSurfaceControl);
1070 });
1071 {
1072 mCapture = screenshot();
1073 // Top left of background must now be visible
1074 mCapture->expectBGColor(0, 0);
1075 // Top left of foreground must now be visible
1076 mCapture->expectBGColor(31, 31);
1077 // Foreground Surface bounds must be color layer
1078 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1079 // Color layer should not extend past foreground bounds
1080 mCapture->expectBGColor(97, 97);
1081 }
1082}
1083
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001084} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001085
1086// TODO(b/129481165): remove the #pragma below and fix conversion issues
1087#pragma clang diagnostic pop // ignored "-Wconversion"