blob: ec826aed9cf981f5a080ee640e41af711e92b665 [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);
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);
Vishnu Nair2e2fbda2021-01-22 16:06:49 -0800302 waitForPostedBuffers();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700303
304 {
305 SCOPED_TRACE("before anything");
306 mCapture = screenshot();
307 mCapture->expectChildColor(64, 64);
308 }
309 }
310 void TearDown() override {
311 LayerUpdateTest::TearDown();
312 mChild = 0;
313 }
314
315 sp<SurfaceControl> mChild;
316 std::unique_ptr<ScreenCapture> mCapture;
317};
318
319TEST_F(ChildLayerTest, ChildLayerPositioning) {
320 asTransaction([&](Transaction& t) {
321 t.show(mChild);
322 t.setPosition(mChild, 10, 10);
323 t.setPosition(mFGSurfaceControl, 64, 64);
324 });
325
326 {
327 mCapture = screenshot();
328 // Top left of foreground must now be visible
329 mCapture->expectFGColor(64, 64);
330 // But 10 pixels in we should see the child surface
331 mCapture->expectChildColor(74, 74);
332 // And 10 more pixels we should be back to the foreground surface
333 mCapture->expectFGColor(84, 84);
334 }
335
336 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
337
338 {
339 mCapture = screenshot();
340 // Top left of foreground should now be at 0, 0
341 mCapture->expectFGColor(0, 0);
342 // But 10 pixels in we should see the child surface
343 mCapture->expectChildColor(10, 10);
344 // And 10 more pixels we should be back to the foreground surface
345 mCapture->expectFGColor(20, 20);
346 }
347}
348
349TEST_F(ChildLayerTest, ChildLayerCropping) {
350 asTransaction([&](Transaction& t) {
351 t.show(mChild);
352 t.setPosition(mChild, 0, 0);
353 t.setPosition(mFGSurfaceControl, 0, 0);
354 t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5));
355 });
356
357 {
358 mCapture = screenshot();
359 mCapture->expectChildColor(0, 0);
360 mCapture->expectChildColor(4, 4);
361 mCapture->expectBGColor(5, 5);
362 }
363}
364
365TEST_F(ChildLayerTest, ChildLayerConstraints) {
366 asTransaction([&](Transaction& t) {
367 t.show(mChild);
368 t.setPosition(mFGSurfaceControl, 0, 0);
369 t.setPosition(mChild, 63, 63);
370 });
371
372 {
373 mCapture = screenshot();
374 mCapture->expectFGColor(0, 0);
375 // Last pixel in foreground should now be the child.
376 mCapture->expectChildColor(63, 63);
377 // But the child should be constrained and the next pixel
378 // must be the background
379 mCapture->expectBGColor(64, 64);
380 }
381}
382
383TEST_F(ChildLayerTest, ChildLayerScaling) {
384 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
385
386 // Find the boundary between the parent and child
387 {
388 mCapture = screenshot();
389 mCapture->expectChildColor(9, 9);
390 mCapture->expectFGColor(10, 10);
391 }
392
393 asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
394
395 // The boundary should be twice as far from the origin now.
396 // The pixels from the last test should all be child now
397 {
398 mCapture = screenshot();
399 mCapture->expectChildColor(9, 9);
400 mCapture->expectChildColor(10, 10);
401 mCapture->expectChildColor(19, 19);
402 mCapture->expectFGColor(20, 20);
403 }
404}
405
406// A child with a scale transform should be cropped by its parent bounds.
407TEST_F(ChildLayerTest, ChildLayerScalingCroppedByParent) {
408 asTransaction([&](Transaction& t) {
409 t.setPosition(mFGSurfaceControl, 0, 0);
410 t.setPosition(mChild, 0, 0);
411 });
412
413 // Find the boundary between the parent and child.
414 {
415 mCapture = screenshot();
416 mCapture->expectChildColor(0, 0);
417 mCapture->expectChildColor(9, 9);
418 mCapture->expectFGColor(10, 10);
419 }
420
421 asTransaction([&](Transaction& t) { t.setMatrix(mChild, 10.0, 0, 0, 10.0); });
422
423 // The child should fill its parent bounds and be cropped by it.
424 {
425 mCapture = screenshot();
426 mCapture->expectChildColor(0, 0);
427 mCapture->expectChildColor(63, 63);
428 mCapture->expectBGColor(64, 64);
429 }
430}
431
432TEST_F(ChildLayerTest, ChildLayerAlpha) {
433 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
434 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
435 TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
436 waitForPostedBuffers();
437
438 asTransaction([&](Transaction& t) {
439 t.show(mChild);
440 t.setPosition(mChild, 0, 0);
441 t.setPosition(mFGSurfaceControl, 0, 0);
442 });
443
444 {
445 mCapture = screenshot();
446 // Unblended child color
447 mCapture->checkPixel(0, 0, 0, 254, 0);
448 }
449
450 asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
451
452 {
453 mCapture = screenshot();
454 // Child and BG blended.
455 mCapture->checkPixel(0, 0, 127, 127, 0);
456 }
457
458 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
459
460 {
461 mCapture = screenshot();
462 // Child and BG blended.
463 mCapture->checkPixel(0, 0, 95, 64, 95);
464 }
465}
466
467TEST_F(ChildLayerTest, ReparentChildren) {
468 asTransaction([&](Transaction& t) {
469 t.show(mChild);
470 t.setPosition(mChild, 10, 10);
471 t.setPosition(mFGSurfaceControl, 64, 64);
472 });
473
474 {
475 mCapture = screenshot();
476 // Top left of foreground must now be visible
477 mCapture->expectFGColor(64, 64);
478 // But 10 pixels in we should see the child surface
479 mCapture->expectChildColor(74, 74);
480 // And 10 more pixels we should be back to the foreground surface
481 mCapture->expectFGColor(84, 84);
482 }
483
Pablo Gamito11dcc222020-09-12 15:49:39 +0000484 asTransaction(
485 [&](Transaction& t) { t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700486
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
Pablo Gamito11dcc222020-09-12 15:49:39 +0000519 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700520
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
Pablo Gamito11dcc222020-09-12 15:49:39 +0000534 asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700535
536 {
537 SCOPED_TRACE("Child visible");
538 ScreenCapture::captureScreen(&mCapture);
539 mCapture->checkPixel(64, 64, 200, 200, 200);
540 }
541
542 asTransaction([&](Transaction& t) {
543 t.reparent(mChild, nullptr);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000544 t.reparentChildren(mChild, mFGSurfaceControl);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700545 });
546
547 {
548 SCOPED_TRACE("foreground visible reparenting grandchild");
549 ScreenCapture::captureScreen(&mCapture);
550 mCapture->checkPixel(64, 64, 195, 63, 63);
551 }
552}
553
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700554TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
555 asTransaction([&](Transaction& t) {
556 t.show(mChild);
557 t.setPosition(mChild, 0, 0);
558 t.setPosition(mFGSurfaceControl, 0, 0);
559 });
560
561 {
562 mCapture = screenshot();
563 // We've positioned the child in the top left.
564 mCapture->expectChildColor(0, 0);
565 // But it's only 10x15.
566 mCapture->expectFGColor(10, 15);
567 }
568
569 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700570 mFGSurfaceControl->getSurface()->setScalingMode(
571 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
572 // Resubmit buffer with new scaling mode
573 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700574 // We cause scaling by 2.
575 t.setSize(mFGSurfaceControl, 128, 128);
576 });
577
578 {
579 mCapture = screenshot();
580 // We've positioned the child in the top left.
581 mCapture->expectChildColor(0, 0);
582 mCapture->expectChildColor(10, 10);
583 mCapture->expectChildColor(19, 29);
584 // And now it should be scaled all the way to 20x30
585 mCapture->expectFGColor(20, 30);
586 }
587}
588
589// Regression test for b/37673612
590TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
591 asTransaction([&](Transaction& t) {
592 t.show(mChild);
593 t.setPosition(mChild, 0, 0);
594 t.setPosition(mFGSurfaceControl, 0, 0);
595 });
596
597 {
598 mCapture = screenshot();
599 // We've positioned the child in the top left.
600 mCapture->expectChildColor(0, 0);
601 mCapture->expectChildColor(9, 14);
602 // But it's only 10x15.
603 mCapture->expectFGColor(10, 15);
604 }
605 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
606 // the WM specified state size.
607 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
608 sp<Surface> s = mFGSurfaceControl->getSurface();
609 auto anw = static_cast<ANativeWindow*>(s.get());
610 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
611 native_window_set_buffers_dimensions(anw, 64, 128);
612 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
613 waitForPostedBuffers();
614
615 {
616 // The child should still be in the same place and not have any strange scaling as in
617 // b/37673612.
618 mCapture = screenshot();
619 mCapture->expectChildColor(0, 0);
620 mCapture->expectFGColor(10, 10);
621 }
622}
623
624// A child with a buffer transform from its parents should be cropped by its parent bounds.
625TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
626 asTransaction([&](Transaction& t) {
627 t.show(mChild);
628 t.setPosition(mChild, 0, 0);
629 t.setPosition(mFGSurfaceControl, 0, 0);
630 t.setSize(mChild, 100, 100);
631 });
632 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
633
634 {
635 mCapture = screenshot();
636
637 mCapture->expectChildColor(0, 0);
638 mCapture->expectChildColor(63, 63);
639 mCapture->expectBGColor(64, 64);
640 }
641
642 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
643 sp<Surface> s = mFGSurfaceControl->getSurface();
644 auto anw = static_cast<ANativeWindow*>(s.get());
645 // Apply a 90 transform on the buffer.
646 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
647 native_window_set_buffers_dimensions(anw, 64, 128);
648 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
649 waitForPostedBuffers();
650
651 // The child should be cropped by the new parent bounds.
652 {
653 mCapture = screenshot();
654 mCapture->expectChildColor(0, 0);
655 mCapture->expectChildColor(99, 63);
656 mCapture->expectFGColor(100, 63);
657 mCapture->expectBGColor(128, 64);
658 }
659}
660
661// A child with a scale transform from its parents should be cropped by its parent bounds.
662TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
663 asTransaction([&](Transaction& t) {
664 t.show(mChild);
665 t.setPosition(mChild, 0, 0);
666 t.setPosition(mFGSurfaceControl, 0, 0);
667 t.setSize(mChild, 200, 200);
668 });
669 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
670
671 {
672 mCapture = screenshot();
673
674 mCapture->expectChildColor(0, 0);
675 mCapture->expectChildColor(63, 63);
676 mCapture->expectBGColor(64, 64);
677 }
678
679 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700680 mFGSurfaceControl->getSurface()->setScalingMode(
681 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
682 // Resubmit buffer with new scaling mode
683 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700684 // Set a scaling by 2.
685 t.setSize(mFGSurfaceControl, 128, 128);
686 });
687
688 // Child should inherit its parents scale but should be cropped by its parent bounds.
689 {
690 mCapture = screenshot();
691 mCapture->expectChildColor(0, 0);
692 mCapture->expectChildColor(127, 127);
693 mCapture->expectBGColor(128, 128);
694 }
695}
696
697// Regression test for b/127368943
698// Child should ignore the buffer transform but apply parent scale transform.
699TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
700 asTransaction([&](Transaction& t) {
701 t.show(mChild);
702 t.setPosition(mChild, 0, 0);
703 t.setPosition(mFGSurfaceControl, 0, 0);
704 });
705
706 {
707 mCapture = screenshot();
708 mCapture->expectChildColor(0, 0);
709 mCapture->expectChildColor(9, 14);
710 mCapture->expectFGColor(10, 15);
711 }
712
713 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
714 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700715 mFGSurfaceControl->getSurface()->setScalingMode(
716 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
717 // Resubmit buffer with new scaling mode
718 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700719 t.setSize(mFGSurfaceControl, 128, 64);
720 });
721 sp<Surface> s = mFGSurfaceControl->getSurface();
722 auto anw = static_cast<ANativeWindow*>(s.get());
723 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
724 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
725 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
726 native_window_set_buffers_dimensions(anw, 32, 64);
727 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
728 waitForPostedBuffers();
729
730 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
731 {
732 mCapture = screenshot();
733 mCapture->expectChildColor(0, 0);
734 mCapture->expectChildColor(19, 29);
735 mCapture->expectFGColor(20, 30);
736 }
737}
738
739TEST_F(ChildLayerTest, Bug36858924) {
740 // Destroy the child layer
741 mChild.clear();
742
743 // Now recreate it as hidden
744 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
745 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
746
747 // Show the child layer in a deferred transaction
748 asTransaction([&](Transaction& t) {
Pablo Gamito11dcc222020-09-12 15:49:39 +0000749 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700750 mFGSurfaceControl->getSurface()->getNextFrameNumber());
751 t.show(mChild);
752 });
753
754 // Render the foreground surface a few times
755 //
756 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
757 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
758 // never acquire/release the first buffer
759 ALOGI("Filling 1");
760 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
761 ALOGI("Filling 2");
762 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
763 ALOGI("Filling 3");
764 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
765 ALOGI("Filling 4");
766 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
767}
768
769TEST_F(ChildLayerTest, Reparent) {
770 asTransaction([&](Transaction& t) {
771 t.show(mChild);
772 t.setPosition(mChild, 10, 10);
773 t.setPosition(mFGSurfaceControl, 64, 64);
774 });
775
776 {
777 mCapture = screenshot();
778 // Top left of foreground must now be visible
779 mCapture->expectFGColor(64, 64);
780 // But 10 pixels in we should see the child surface
781 mCapture->expectChildColor(74, 74);
782 // And 10 more pixels we should be back to the foreground surface
783 mCapture->expectFGColor(84, 84);
784 }
785
Pablo Gamito11dcc222020-09-12 15:49:39 +0000786 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700787
788 {
789 mCapture = screenshot();
790 mCapture->expectFGColor(64, 64);
791 // In reparenting we should have exposed the entire foreground surface.
792 mCapture->expectFGColor(74, 74);
793 // And the child layer should now begin at 10, 10 (since the BG
794 // layer is at (0, 0)).
795 mCapture->expectBGColor(9, 9);
796 mCapture->expectChildColor(10, 10);
797 }
798}
799
800TEST_F(ChildLayerTest, ReparentToNoParent) {
801 asTransaction([&](Transaction& t) {
802 t.show(mChild);
803 t.setPosition(mChild, 10, 10);
804 t.setPosition(mFGSurfaceControl, 64, 64);
805 });
806
807 {
808 mCapture = screenshot();
809 // Top left of foreground must now be visible
810 mCapture->expectFGColor(64, 64);
811 // But 10 pixels in we should see the child surface
812 mCapture->expectChildColor(74, 74);
813 // And 10 more pixels we should be back to the foreground surface
814 mCapture->expectFGColor(84, 84);
815 }
816 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
817 {
818 mCapture = screenshot();
819 // The surface should now be offscreen.
820 mCapture->expectFGColor(64, 64);
821 mCapture->expectFGColor(74, 74);
822 mCapture->expectFGColor(84, 84);
823 }
824}
825
826TEST_F(ChildLayerTest, ReparentFromNoParent) {
827 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
828 ASSERT_TRUE(newSurface != nullptr);
829 ASSERT_TRUE(newSurface->isValid());
830
831 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
832 asTransaction([&](Transaction& t) {
833 t.hide(mChild);
834 t.show(newSurface);
835 t.setPosition(newSurface, 10, 10);
836 t.setLayer(newSurface, INT32_MAX - 2);
837 t.setPosition(mFGSurfaceControl, 64, 64);
838 });
839
840 {
841 mCapture = screenshot();
842 // Top left of foreground must now be visible
843 mCapture->expectFGColor(64, 64);
844 // At 10, 10 we should see the new surface
845 mCapture->checkPixel(10, 10, 63, 195, 63);
846 }
847
Pablo Gamito11dcc222020-09-12 15:49:39 +0000848 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700849
850 {
851 mCapture = screenshot();
852 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
853 // mFGSurface, putting it at 74, 74.
854 mCapture->expectFGColor(64, 64);
855 mCapture->checkPixel(74, 74, 63, 195, 63);
856 mCapture->expectFGColor(84, 84);
857 }
858}
859
860TEST_F(ChildLayerTest, NestedChildren) {
861 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
862 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
863 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
864
865 {
866 mCapture = screenshot();
867 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
868 // which begins at 64, 64
869 mCapture->checkPixel(64, 64, 50, 50, 50);
870 }
871}
872
873TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
874 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
875 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
876
877 Transaction t;
878 t.setLayer(relative, INT32_MAX)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000879 .setRelativeLayer(mChild, relative, 1)
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700880 .setPosition(mFGSurfaceControl, 0, 0)
881 .apply(true);
882
883 // We expect that the child should have been elevated above our
884 // INT_MAX layer even though it's not a child of it.
885 {
886 mCapture = screenshot();
887 mCapture->expectChildColor(0, 0);
888 mCapture->expectChildColor(9, 9);
889 mCapture->checkPixel(10, 10, 255, 255, 255);
890 }
891}
892
893class BoundlessLayerTest : public LayerUpdateTest {
894protected:
895 std::unique_ptr<ScreenCapture> mCapture;
896};
897
898// Verify setting a size on a buffer layer has no effect.
899TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
900 sp<SurfaceControl> bufferLayer =
901 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
902 mFGSurfaceControl.get());
903 ASSERT_TRUE(bufferLayer->isValid());
904 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
905 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
906 {
907 mCapture = screenshot();
908 // Top left of background must now be visible
909 mCapture->expectBGColor(0, 0);
910 // Foreground Surface bounds must be color layer
911 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
912 // Buffer layer should not extend past buffer bounds
913 mCapture->expectFGColor(95, 95);
914 }
915}
916
917// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
918// which will crop the color layer.
919TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
920 sp<SurfaceControl> colorLayer =
921 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800922 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700923 ASSERT_TRUE(colorLayer->isValid());
924 asTransaction([&](Transaction& t) {
925 t.setColor(colorLayer, half3{0, 0, 0});
926 t.show(colorLayer);
927 });
928 {
929 mCapture = screenshot();
930 // Top left of background must now be visible
931 mCapture->expectBGColor(0, 0);
932 // Foreground Surface bounds must be color layer
933 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
934 // Color layer should not extend past foreground bounds
935 mCapture->expectBGColor(129, 129);
936 }
937}
938
939// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
940// a crop which will be used to crop the color layer.
941TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
942 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
943 0 /* flags */, mFGSurfaceControl.get());
944 ASSERT_TRUE(cropLayer->isValid());
945 sp<SurfaceControl> colorLayer =
946 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800947 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700948 ASSERT_TRUE(colorLayer->isValid());
949 asTransaction([&](Transaction& t) {
950 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
951 t.setColor(colorLayer, half3{0, 0, 0});
952 t.show(cropLayer);
953 t.show(colorLayer);
954 });
955 {
956 mCapture = screenshot();
957 // Top left of background must now be visible
958 mCapture->expectBGColor(0, 0);
959 // Top left of foreground must now be visible
960 mCapture->expectFGColor(64, 64);
961 // 5 pixels from the foreground we should see the child surface
962 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
963 // 10 pixels from the foreground we should be back to the foreground surface
964 mCapture->expectFGColor(74, 74);
965 }
966}
967
968// Verify for boundless layer with no children, their transforms have no effect.
969TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
970 sp<SurfaceControl> colorLayer =
971 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800972 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700973 ASSERT_TRUE(colorLayer->isValid());
974 asTransaction([&](Transaction& t) {
975 t.setPosition(colorLayer, 320, 320);
976 t.setMatrix(colorLayer, 2, 0, 0, 2);
977 t.setColor(colorLayer, half3{0, 0, 0});
978 t.show(colorLayer);
979 });
980 {
981 mCapture = screenshot();
982 // Top left of background must now be visible
983 mCapture->expectBGColor(0, 0);
984 // Foreground Surface bounds must be color layer
985 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
986 // Color layer should not extend past foreground bounds
987 mCapture->expectBGColor(129, 129);
988 }
989}
990
991// Verify for boundless layer with children, their transforms have an effect.
992TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
993 sp<SurfaceControl> boundlessLayerRightShift =
994 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
995 0 /* flags */, mFGSurfaceControl.get());
996 ASSERT_TRUE(boundlessLayerRightShift->isValid());
997 sp<SurfaceControl> boundlessLayerDownShift =
998 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
999 0 /* flags */, boundlessLayerRightShift.get());
1000 ASSERT_TRUE(boundlessLayerDownShift->isValid());
1001 sp<SurfaceControl> colorLayer =
1002 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001003 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001004 ASSERT_TRUE(colorLayer->isValid());
1005 asTransaction([&](Transaction& t) {
1006 t.setPosition(boundlessLayerRightShift, 32, 0);
1007 t.show(boundlessLayerRightShift);
1008 t.setPosition(boundlessLayerDownShift, 0, 32);
1009 t.show(boundlessLayerDownShift);
1010 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1011 t.setColor(colorLayer, half3{0, 0, 0});
1012 t.show(colorLayer);
1013 });
1014 {
1015 mCapture = screenshot();
1016 // Top left of background must now be visible
1017 mCapture->expectBGColor(0, 0);
1018 // Top left of foreground must now be visible
1019 mCapture->expectFGColor(64, 64);
1020 // Foreground Surface bounds must be color layer
1021 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1022 // Color layer should not extend past foreground bounds
1023 mCapture->expectBGColor(129, 129);
1024 }
1025}
1026
1027// Verify child layers do not get clipped if they temporarily move into the negative
1028// coordinate space as the result of an intermediate transformation.
1029TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1030 sp<SurfaceControl> boundlessLayer =
1031 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -07001032 0 /* flags */, mFGSurfaceControl->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001033 ASSERT_TRUE(boundlessLayer != nullptr);
1034 ASSERT_TRUE(boundlessLayer->isValid());
1035 sp<SurfaceControl> colorLayer =
1036 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -07001037 ISurfaceComposerClient::eFXSurfaceEffect,
1038 boundlessLayer->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001039 ASSERT_TRUE(colorLayer != nullptr);
1040 ASSERT_TRUE(colorLayer->isValid());
1041 asTransaction([&](Transaction& t) {
1042 // shift child layer off bounds. If this layer was not boundless, we will
1043 // expect the child layer to be cropped.
1044 t.setPosition(boundlessLayer, 32, 32);
1045 t.show(boundlessLayer);
1046 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1047 // undo shift by parent
1048 t.setPosition(colorLayer, -32, -32);
1049 t.setColor(colorLayer, half3{0, 0, 0});
1050 t.show(colorLayer);
1051 });
1052 {
1053 mCapture = screenshot();
1054 // Top left of background must now be visible
1055 mCapture->expectBGColor(0, 0);
1056 // Foreground Surface bounds must be color layer
1057 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1058 // Color layer should not extend past foreground bounds
1059 mCapture->expectBGColor(129, 129);
1060 }
1061}
1062
1063// Verify for boundless root layers with children, their transforms have an effect.
1064TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1065 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1066 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1067 ASSERT_TRUE(rootBoundlessLayer->isValid());
1068 sp<SurfaceControl> colorLayer =
1069 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001070 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001071
1072 ASSERT_TRUE(colorLayer->isValid());
1073 asTransaction([&](Transaction& t) {
1074 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1075 t.setPosition(rootBoundlessLayer, 32, 32);
1076 t.show(rootBoundlessLayer);
1077 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1078 t.setColor(colorLayer, half3{0, 0, 0});
1079 t.show(colorLayer);
1080 t.hide(mFGSurfaceControl);
1081 });
1082 {
1083 mCapture = screenshot();
1084 // Top left of background must now be visible
1085 mCapture->expectBGColor(0, 0);
1086 // Top left of foreground must now be visible
1087 mCapture->expectBGColor(31, 31);
1088 // Foreground Surface bounds must be color layer
1089 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1090 // Color layer should not extend past foreground bounds
1091 mCapture->expectBGColor(97, 97);
1092 }
1093}
1094
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001095} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001096
1097// TODO(b/129481165): remove the #pragma below and fix conversion issues
1098#pragma clang diagnostic pop // ignored "-Wconversion"