blob: 39d9206e1a096efbb5bf56176b7056c4b8290b56 [file] [log] [blame]
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Valerie Hau9cfc6d82019-09-23 13:54:07 -070021#include "LayerTransactionTest.h"
22
23namespace android {
24
25using android::hardware::graphics::common::V1_1::BufferUsage;
26
27::testing::Environment* const binderEnv =
28 ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
29
30class LayerUpdateTest : public LayerTransactionTest {
31protected:
32 virtual void SetUp() {
33 LayerTransactionTest::SetUp();
34 ASSERT_EQ(NO_ERROR, mClient->initCheck());
35
36 const auto display = SurfaceComposerClient::getInternalDisplayToken();
37 ASSERT_FALSE(display == nullptr);
38
Marin Shalamanova7fe3042021-01-29 21:02:08 +010039 ui::DisplayMode mode;
40 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
41 const ui::Size& resolution = mode.resolution;
Valerie Hau9cfc6d82019-09-23 13:54:07 -070042
43 // Background surface
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080044 mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
45 resolution.getHeight(), 0);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070046 ASSERT_TRUE(mBGSurfaceControl != nullptr);
47 ASSERT_TRUE(mBGSurfaceControl->isValid());
48 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
49
50 // Foreground surface
51 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
52
53 ASSERT_TRUE(mFGSurfaceControl != nullptr);
54 ASSERT_TRUE(mFGSurfaceControl->isValid());
55
56 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
57
58 // Synchronization surface
59 mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
60 ASSERT_TRUE(mSyncSurfaceControl != nullptr);
61 ASSERT_TRUE(mSyncSurfaceControl->isValid());
62
63 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
64
65 asTransaction([&](Transaction& t) {
66 t.setDisplayLayerStack(display, 0);
67
68 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
69
70 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
71 .setPosition(mFGSurfaceControl, 64, 64)
72 .show(mFGSurfaceControl);
73
74 t.setLayer(mSyncSurfaceControl, INT32_MAX - 1)
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080075 .setPosition(mSyncSurfaceControl, resolution.getWidth() - 2,
76 resolution.getHeight() - 2)
Valerie Hau9cfc6d82019-09-23 13:54:07 -070077 .show(mSyncSurfaceControl);
78 });
79 }
80
81 virtual void TearDown() {
82 LayerTransactionTest::TearDown();
83 mBGSurfaceControl = 0;
84 mFGSurfaceControl = 0;
85 mSyncSurfaceControl = 0;
86 }
87
88 void waitForPostedBuffers() {
89 // Since the sync surface is in synchronous mode (i.e. double buffered)
90 // posting three buffers to it should ensure that at least two
91 // SurfaceFlinger::handlePageFlip calls have been made, which should
92 // guaranteed that a buffer posted to another Surface has been retired.
93 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
94 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
95 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
96 }
97
98 sp<SurfaceControl> mBGSurfaceControl;
99 sp<SurfaceControl> mFGSurfaceControl;
100
101 // This surface is used to ensure that the buffers posted to
102 // mFGSurfaceControl have been picked up by SurfaceFlinger.
103 sp<SurfaceControl> mSyncSurfaceControl;
104};
105
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700106class GeometryLatchingTest : public LayerUpdateTest {
107protected:
108 void EXPECT_INITIAL_STATE(const char* trace) {
109 SCOPED_TRACE(trace);
110 ScreenCapture::captureScreen(&sc);
111 // We find the leading edge of the FG surface.
112 sc->expectFGColor(127, 127);
113 sc->expectBGColor(128, 128);
114 }
115
116 void lockAndFillFGBuffer() {
117 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false);
118 }
119
120 void unlockFGBuffer() {
121 sp<Surface> s = mFGSurfaceControl->getSurface();
122 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
123 waitForPostedBuffers();
124 }
125
126 void completeFGResize() {
127 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
128 waitForPostedBuffers();
129 }
130 void restoreInitialState() {
131 asTransaction([&](Transaction& t) {
132 t.setSize(mFGSurfaceControl, 64, 64);
133 t.setPosition(mFGSurfaceControl, 64, 64);
chaviw25714502021-02-11 10:01:08 -0800134 t.setCrop(mFGSurfaceControl, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700135 });
136
137 EXPECT_INITIAL_STATE("After restoring initial state");
138 }
139 std::unique_ptr<ScreenCapture> sc;
140};
141
142class CropLatchingTest : public GeometryLatchingTest {
143protected:
144 void EXPECT_CROPPED_STATE(const char* trace) {
145 SCOPED_TRACE(trace);
146 ScreenCapture::captureScreen(&sc);
147 // The edge should be moved back one pixel by our crop.
148 sc->expectFGColor(126, 126);
149 sc->expectBGColor(127, 127);
150 sc->expectBGColor(128, 128);
151 }
152
153 void EXPECT_RESIZE_STATE(const char* trace) {
154 SCOPED_TRACE(trace);
155 ScreenCapture::captureScreen(&sc);
156 // The FG is now resized too 128,128 at 64,64
157 sc->expectFGColor(64, 64);
158 sc->expectFGColor(191, 191);
159 sc->expectBGColor(192, 192);
160 }
161};
162
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{}
chaviw25714502021-02-11 10:01:08 -0800228 .setCrop(childNoBuffer, Rect(0, 0, 10, 10))
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700229 .show(childNoBuffer)
230 .show(childBuffer)
231 .apply(true);
232 {
233 ScreenCapture::captureScreen(&sc);
234 sc->expectChildColor(73, 73);
235 sc->expectFGColor(74, 74);
236 }
chaviw25714502021-02-11 10:01:08 -0800237 SurfaceComposerClient::Transaction{}.setCrop(childNoBuffer, Rect(0, 0, 20, 20)).apply(true);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700238 {
239 ScreenCapture::captureScreen(&sc);
240 sc->expectChildColor(73, 73);
241 sc->expectChildColor(74, 74);
242 }
243}
244
245TEST_F(LayerUpdateTest, MergingTransactions) {
246 std::unique_ptr<ScreenCapture> sc;
247 {
248 SCOPED_TRACE("before move");
249 ScreenCapture::captureScreen(&sc);
250 sc->expectBGColor(0, 12);
251 sc->expectFGColor(75, 75);
252 sc->expectBGColor(145, 145);
253 }
254
255 Transaction t1, t2;
256 t1.setPosition(mFGSurfaceControl, 128, 128);
257 t2.setPosition(mFGSurfaceControl, 0, 0);
258 // We expect that the position update from t2 now
259 // overwrites the position update from t1.
260 t1.merge(std::move(t2));
261 t1.apply();
262
263 {
264 ScreenCapture::captureScreen(&sc);
265 sc->expectFGColor(1, 1);
266 }
267}
268
269TEST_F(LayerUpdateTest, MergingTransactionFlags) {
270 Transaction().hide(mFGSurfaceControl).apply();
271 std::unique_ptr<ScreenCapture> sc;
272 {
273 SCOPED_TRACE("before merge");
274 ScreenCapture::captureScreen(&sc);
275 sc->expectBGColor(0, 12);
276 sc->expectBGColor(75, 75);
277 sc->expectBGColor(145, 145);
278 }
279
280 Transaction t1, t2;
281 t1.show(mFGSurfaceControl);
282 t2.setFlags(mFGSurfaceControl, 0 /* flags */, layer_state_t::eLayerSecure /* mask */);
283 t1.merge(std::move(t2));
284 t1.apply();
285
286 {
287 SCOPED_TRACE("after merge");
288 ScreenCapture::captureScreen(&sc);
289 sc->expectFGColor(75, 75);
290 }
291}
292
293class ChildLayerTest : public LayerUpdateTest {
294protected:
295 void SetUp() override {
296 LayerUpdateTest::SetUp();
297 mChild = createSurface(mClient, "Child surface", 10, 15, PIXEL_FORMAT_RGBA_8888, 0,
298 mFGSurfaceControl.get());
299 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
Vishnu Nair2e2fbda2021-01-22 16:06:49 -0800300 waitForPostedBuffers();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700301
302 {
303 SCOPED_TRACE("before anything");
304 mCapture = screenshot();
305 mCapture->expectChildColor(64, 64);
306 }
307 }
308 void TearDown() override {
309 LayerUpdateTest::TearDown();
310 mChild = 0;
311 }
312
313 sp<SurfaceControl> mChild;
314 std::unique_ptr<ScreenCapture> mCapture;
315};
316
317TEST_F(ChildLayerTest, ChildLayerPositioning) {
318 asTransaction([&](Transaction& t) {
319 t.show(mChild);
320 t.setPosition(mChild, 10, 10);
321 t.setPosition(mFGSurfaceControl, 64, 64);
322 });
323
324 {
325 mCapture = screenshot();
326 // Top left of foreground must now be visible
327 mCapture->expectFGColor(64, 64);
328 // But 10 pixels in we should see the child surface
329 mCapture->expectChildColor(74, 74);
330 // And 10 more pixels we should be back to the foreground surface
331 mCapture->expectFGColor(84, 84);
332 }
333
334 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
335
336 {
337 mCapture = screenshot();
338 // Top left of foreground should now be at 0, 0
339 mCapture->expectFGColor(0, 0);
340 // But 10 pixels in we should see the child surface
341 mCapture->expectChildColor(10, 10);
342 // And 10 more pixels we should be back to the foreground surface
343 mCapture->expectFGColor(20, 20);
344 }
345}
346
347TEST_F(ChildLayerTest, ChildLayerCropping) {
348 asTransaction([&](Transaction& t) {
349 t.show(mChild);
350 t.setPosition(mChild, 0, 0);
351 t.setPosition(mFGSurfaceControl, 0, 0);
chaviw25714502021-02-11 10:01:08 -0800352 t.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700353 });
354
355 {
356 mCapture = screenshot();
357 mCapture->expectChildColor(0, 0);
358 mCapture->expectChildColor(4, 4);
359 mCapture->expectBGColor(5, 5);
360 }
361}
362
363TEST_F(ChildLayerTest, ChildLayerConstraints) {
364 asTransaction([&](Transaction& t) {
365 t.show(mChild);
366 t.setPosition(mFGSurfaceControl, 0, 0);
367 t.setPosition(mChild, 63, 63);
368 });
369
370 {
371 mCapture = screenshot();
372 mCapture->expectFGColor(0, 0);
373 // Last pixel in foreground should now be the child.
374 mCapture->expectChildColor(63, 63);
375 // But the child should be constrained and the next pixel
376 // must be the background
377 mCapture->expectBGColor(64, 64);
378 }
379}
380
381TEST_F(ChildLayerTest, ChildLayerScaling) {
382 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
383
384 // Find the boundary between the parent and child
385 {
386 mCapture = screenshot();
387 mCapture->expectChildColor(9, 9);
388 mCapture->expectFGColor(10, 10);
389 }
390
391 asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
392
393 // The boundary should be twice as far from the origin now.
394 // The pixels from the last test should all be child now
395 {
396 mCapture = screenshot();
397 mCapture->expectChildColor(9, 9);
398 mCapture->expectChildColor(10, 10);
399 mCapture->expectChildColor(19, 19);
400 mCapture->expectFGColor(20, 20);
401 }
402}
403
404// A child with a scale transform should be cropped by its parent bounds.
405TEST_F(ChildLayerTest, ChildLayerScalingCroppedByParent) {
406 asTransaction([&](Transaction& t) {
407 t.setPosition(mFGSurfaceControl, 0, 0);
408 t.setPosition(mChild, 0, 0);
409 });
410
411 // Find the boundary between the parent and child.
412 {
413 mCapture = screenshot();
414 mCapture->expectChildColor(0, 0);
415 mCapture->expectChildColor(9, 9);
416 mCapture->expectFGColor(10, 10);
417 }
418
419 asTransaction([&](Transaction& t) { t.setMatrix(mChild, 10.0, 0, 0, 10.0); });
420
421 // The child should fill its parent bounds and be cropped by it.
422 {
423 mCapture = screenshot();
424 mCapture->expectChildColor(0, 0);
425 mCapture->expectChildColor(63, 63);
426 mCapture->expectBGColor(64, 64);
427 }
428}
429
430TEST_F(ChildLayerTest, ChildLayerAlpha) {
431 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
432 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
433 TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
434 waitForPostedBuffers();
435
436 asTransaction([&](Transaction& t) {
437 t.show(mChild);
438 t.setPosition(mChild, 0, 0);
439 t.setPosition(mFGSurfaceControl, 0, 0);
440 });
441
442 {
443 mCapture = screenshot();
444 // Unblended child color
445 mCapture->checkPixel(0, 0, 0, 254, 0);
446 }
447
448 asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
449
450 {
451 mCapture = screenshot();
Ana Krulec69de94c2021-01-25 18:18:27 -0800452 // Child and BG blended. See b/175352694 for tolerance.
453 mCapture->expectColor(Rect(0, 0, 1, 1), Color{127, 127, 0, 255}, 1);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700454 }
455
456 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
457
458 {
459 mCapture = screenshot();
Ana Krulec69de94c2021-01-25 18:18:27 -0800460 // Child and BG blended. See b/175352694 for tolerance.
461 mCapture->expectColor(Rect(0, 0, 1, 1), Color{95, 64, 95, 255}, 1);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700462 }
463}
464
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700465TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
466 sp<SurfaceControl> mGrandChild =
467 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
468 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
469
470 {
471 SCOPED_TRACE("Grandchild visible");
472 ScreenCapture::captureScreen(&mCapture);
473 mCapture->checkPixel(64, 64, 111, 111, 111);
474 }
475
Robert Carr0e328f62020-02-06 17:12:08 -0800476 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700477 mChild.clear();
478
479 {
480 SCOPED_TRACE("After destroying child");
481 ScreenCapture::captureScreen(&mCapture);
482 mCapture->expectFGColor(64, 64);
483 }
484
Pablo Gamito11dcc222020-09-12 15:49:39 +0000485 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700486
487 {
488 SCOPED_TRACE("After reparenting grandchild");
489 ScreenCapture::captureScreen(&mCapture);
490 mCapture->checkPixel(64, 64, 111, 111, 111);
491 }
492}
493
494TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
495 sp<SurfaceControl> mGrandChild =
496 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
497 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
498
499 // draw grand child behind the foreground surface
Pablo Gamito11dcc222020-09-12 15:49:39 +0000500 asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700501
502 {
503 SCOPED_TRACE("Child visible");
504 ScreenCapture::captureScreen(&mCapture);
505 mCapture->checkPixel(64, 64, 200, 200, 200);
506 }
507
508 asTransaction([&](Transaction& t) {
509 t.reparent(mChild, nullptr);
Robert Carr257fdae2021-04-08 17:30:52 -0700510 t.reparent(mGrandChild, mFGSurfaceControl);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700511 });
512
513 {
514 SCOPED_TRACE("foreground visible reparenting grandchild");
515 ScreenCapture::captureScreen(&mCapture);
516 mCapture->checkPixel(64, 64, 195, 63, 63);
517 }
518}
519
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700520TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
521 asTransaction([&](Transaction& t) {
522 t.show(mChild);
523 t.setPosition(mChild, 0, 0);
524 t.setPosition(mFGSurfaceControl, 0, 0);
525 });
526
527 {
528 mCapture = screenshot();
529 // We've positioned the child in the top left.
530 mCapture->expectChildColor(0, 0);
531 // But it's only 10x15.
532 mCapture->expectFGColor(10, 15);
533 }
534
535 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700536 mFGSurfaceControl->getSurface()->setScalingMode(
537 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
538 // Resubmit buffer with new scaling mode
539 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700540 // We cause scaling by 2.
541 t.setSize(mFGSurfaceControl, 128, 128);
542 });
543
544 {
545 mCapture = screenshot();
546 // We've positioned the child in the top left.
547 mCapture->expectChildColor(0, 0);
548 mCapture->expectChildColor(10, 10);
549 mCapture->expectChildColor(19, 29);
550 // And now it should be scaled all the way to 20x30
551 mCapture->expectFGColor(20, 30);
552 }
553}
554
555// Regression test for b/37673612
556TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
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 mCapture->expectChildColor(9, 14);
568 // But it's only 10x15.
569 mCapture->expectFGColor(10, 15);
570 }
571 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
572 // the WM specified state size.
573 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
574 sp<Surface> s = mFGSurfaceControl->getSurface();
575 auto anw = static_cast<ANativeWindow*>(s.get());
576 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
577 native_window_set_buffers_dimensions(anw, 64, 128);
578 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
579 waitForPostedBuffers();
580
581 {
582 // The child should still be in the same place and not have any strange scaling as in
583 // b/37673612.
584 mCapture = screenshot();
585 mCapture->expectChildColor(0, 0);
586 mCapture->expectFGColor(10, 10);
587 }
588}
589
590// A child with a buffer transform from its parents should be cropped by its parent bounds.
591TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
592 asTransaction([&](Transaction& t) {
593 t.show(mChild);
594 t.setPosition(mChild, 0, 0);
595 t.setPosition(mFGSurfaceControl, 0, 0);
596 t.setSize(mChild, 100, 100);
597 });
598 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
599
600 {
601 mCapture = screenshot();
602
603 mCapture->expectChildColor(0, 0);
604 mCapture->expectChildColor(63, 63);
605 mCapture->expectBGColor(64, 64);
606 }
607
608 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
609 sp<Surface> s = mFGSurfaceControl->getSurface();
610 auto anw = static_cast<ANativeWindow*>(s.get());
611 // Apply a 90 transform on the buffer.
612 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
613 native_window_set_buffers_dimensions(anw, 64, 128);
614 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
615 waitForPostedBuffers();
616
617 // The child should be cropped by the new parent bounds.
618 {
619 mCapture = screenshot();
620 mCapture->expectChildColor(0, 0);
621 mCapture->expectChildColor(99, 63);
622 mCapture->expectFGColor(100, 63);
623 mCapture->expectBGColor(128, 64);
624 }
625}
626
627// A child with a scale transform from its parents should be cropped by its parent bounds.
628TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
629 asTransaction([&](Transaction& t) {
630 t.show(mChild);
631 t.setPosition(mChild, 0, 0);
632 t.setPosition(mFGSurfaceControl, 0, 0);
633 t.setSize(mChild, 200, 200);
634 });
635 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
636
637 {
638 mCapture = screenshot();
639
640 mCapture->expectChildColor(0, 0);
641 mCapture->expectChildColor(63, 63);
642 mCapture->expectBGColor(64, 64);
643 }
644
645 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700646 mFGSurfaceControl->getSurface()->setScalingMode(
647 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
648 // Resubmit buffer with new scaling mode
649 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700650 // Set a scaling by 2.
651 t.setSize(mFGSurfaceControl, 128, 128);
652 });
653
654 // Child should inherit its parents scale but should be cropped by its parent bounds.
655 {
656 mCapture = screenshot();
657 mCapture->expectChildColor(0, 0);
658 mCapture->expectChildColor(127, 127);
659 mCapture->expectBGColor(128, 128);
660 }
661}
662
663// Regression test for b/127368943
664// Child should ignore the buffer transform but apply parent scale transform.
665TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
666 asTransaction([&](Transaction& t) {
667 t.show(mChild);
668 t.setPosition(mChild, 0, 0);
669 t.setPosition(mFGSurfaceControl, 0, 0);
670 });
671
672 {
673 mCapture = screenshot();
674 mCapture->expectChildColor(0, 0);
675 mCapture->expectChildColor(9, 14);
676 mCapture->expectFGColor(10, 15);
677 }
678
679 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
680 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700681 mFGSurfaceControl->getSurface()->setScalingMode(
682 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
683 // Resubmit buffer with new scaling mode
684 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700685 t.setSize(mFGSurfaceControl, 128, 64);
686 });
687 sp<Surface> s = mFGSurfaceControl->getSurface();
688 auto anw = static_cast<ANativeWindow*>(s.get());
689 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
690 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
691 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
692 native_window_set_buffers_dimensions(anw, 32, 64);
693 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
694 waitForPostedBuffers();
695
696 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
697 {
698 mCapture = screenshot();
699 mCapture->expectChildColor(0, 0);
700 mCapture->expectChildColor(19, 29);
701 mCapture->expectFGColor(20, 30);
702 }
703}
704
705TEST_F(ChildLayerTest, Bug36858924) {
706 // Destroy the child layer
707 mChild.clear();
708
709 // Now recreate it as hidden
710 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
711 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
712
713 // Show the child layer in a deferred transaction
714 asTransaction([&](Transaction& t) {
Pablo Gamito11dcc222020-09-12 15:49:39 +0000715 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700716 mFGSurfaceControl->getSurface()->getNextFrameNumber());
717 t.show(mChild);
718 });
719
720 // Render the foreground surface a few times
721 //
722 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
723 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
724 // never acquire/release the first buffer
725 ALOGI("Filling 1");
726 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
727 ALOGI("Filling 2");
728 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
729 ALOGI("Filling 3");
730 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
731 ALOGI("Filling 4");
732 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
733}
734
735TEST_F(ChildLayerTest, Reparent) {
736 asTransaction([&](Transaction& t) {
737 t.show(mChild);
738 t.setPosition(mChild, 10, 10);
739 t.setPosition(mFGSurfaceControl, 64, 64);
740 });
741
742 {
743 mCapture = screenshot();
744 // Top left of foreground must now be visible
745 mCapture->expectFGColor(64, 64);
746 // But 10 pixels in we should see the child surface
747 mCapture->expectChildColor(74, 74);
748 // And 10 more pixels we should be back to the foreground surface
749 mCapture->expectFGColor(84, 84);
750 }
751
Pablo Gamito11dcc222020-09-12 15:49:39 +0000752 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700753
754 {
755 mCapture = screenshot();
756 mCapture->expectFGColor(64, 64);
757 // In reparenting we should have exposed the entire foreground surface.
758 mCapture->expectFGColor(74, 74);
759 // And the child layer should now begin at 10, 10 (since the BG
760 // layer is at (0, 0)).
761 mCapture->expectBGColor(9, 9);
762 mCapture->expectChildColor(10, 10);
763 }
764}
765
766TEST_F(ChildLayerTest, ReparentToNoParent) {
767 asTransaction([&](Transaction& t) {
768 t.show(mChild);
769 t.setPosition(mChild, 10, 10);
770 t.setPosition(mFGSurfaceControl, 64, 64);
771 });
772
773 {
774 mCapture = screenshot();
775 // Top left of foreground must now be visible
776 mCapture->expectFGColor(64, 64);
777 // But 10 pixels in we should see the child surface
778 mCapture->expectChildColor(74, 74);
779 // And 10 more pixels we should be back to the foreground surface
780 mCapture->expectFGColor(84, 84);
781 }
782 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
783 {
784 mCapture = screenshot();
785 // The surface should now be offscreen.
786 mCapture->expectFGColor(64, 64);
787 mCapture->expectFGColor(74, 74);
788 mCapture->expectFGColor(84, 84);
789 }
790}
791
792TEST_F(ChildLayerTest, ReparentFromNoParent) {
793 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
794 ASSERT_TRUE(newSurface != nullptr);
795 ASSERT_TRUE(newSurface->isValid());
796
797 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
798 asTransaction([&](Transaction& t) {
799 t.hide(mChild);
800 t.show(newSurface);
801 t.setPosition(newSurface, 10, 10);
802 t.setLayer(newSurface, INT32_MAX - 2);
803 t.setPosition(mFGSurfaceControl, 64, 64);
804 });
805
806 {
807 mCapture = screenshot();
808 // Top left of foreground must now be visible
809 mCapture->expectFGColor(64, 64);
810 // At 10, 10 we should see the new surface
811 mCapture->checkPixel(10, 10, 63, 195, 63);
812 }
813
Pablo Gamito11dcc222020-09-12 15:49:39 +0000814 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700815
816 {
817 mCapture = screenshot();
818 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
819 // mFGSurface, putting it at 74, 74.
820 mCapture->expectFGColor(64, 64);
821 mCapture->checkPixel(74, 74, 63, 195, 63);
822 mCapture->expectFGColor(84, 84);
823 }
824}
825
826TEST_F(ChildLayerTest, NestedChildren) {
827 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
828 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
829 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
830
831 {
832 mCapture = screenshot();
833 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
834 // which begins at 64, 64
835 mCapture->checkPixel(64, 64, 50, 50, 50);
836 }
837}
838
839TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
840 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
841 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
842
843 Transaction t;
844 t.setLayer(relative, INT32_MAX)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000845 .setRelativeLayer(mChild, relative, 1)
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700846 .setPosition(mFGSurfaceControl, 0, 0)
847 .apply(true);
848
849 // We expect that the child should have been elevated above our
850 // INT_MAX layer even though it's not a child of it.
851 {
852 mCapture = screenshot();
853 mCapture->expectChildColor(0, 0);
854 mCapture->expectChildColor(9, 9);
855 mCapture->checkPixel(10, 10, 255, 255, 255);
856 }
857}
858
859class BoundlessLayerTest : public LayerUpdateTest {
860protected:
861 std::unique_ptr<ScreenCapture> mCapture;
862};
863
864// Verify setting a size on a buffer layer has no effect.
865TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
866 sp<SurfaceControl> bufferLayer =
867 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
868 mFGSurfaceControl.get());
869 ASSERT_TRUE(bufferLayer->isValid());
870 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
871 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
872 {
873 mCapture = screenshot();
874 // Top left of background must now be visible
875 mCapture->expectBGColor(0, 0);
876 // Foreground Surface bounds must be color layer
877 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
878 // Buffer layer should not extend past buffer bounds
879 mCapture->expectFGColor(95, 95);
880 }
881}
882
883// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
884// which will crop the color layer.
885TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
886 sp<SurfaceControl> colorLayer =
887 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800888 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700889 ASSERT_TRUE(colorLayer->isValid());
890 asTransaction([&](Transaction& t) {
891 t.setColor(colorLayer, half3{0, 0, 0});
892 t.show(colorLayer);
893 });
894 {
895 mCapture = screenshot();
896 // Top left of background must now be visible
897 mCapture->expectBGColor(0, 0);
898 // Foreground Surface bounds must be color layer
899 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
900 // Color layer should not extend past foreground bounds
901 mCapture->expectBGColor(129, 129);
902 }
903}
904
905// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
906// a crop which will be used to crop the color layer.
907TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
908 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
909 0 /* flags */, mFGSurfaceControl.get());
910 ASSERT_TRUE(cropLayer->isValid());
911 sp<SurfaceControl> colorLayer =
912 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800913 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700914 ASSERT_TRUE(colorLayer->isValid());
915 asTransaction([&](Transaction& t) {
chaviw25714502021-02-11 10:01:08 -0800916 t.setCrop(cropLayer, Rect(5, 5, 10, 10));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700917 t.setColor(colorLayer, half3{0, 0, 0});
918 t.show(cropLayer);
919 t.show(colorLayer);
920 });
921 {
922 mCapture = screenshot();
923 // Top left of background must now be visible
924 mCapture->expectBGColor(0, 0);
925 // Top left of foreground must now be visible
926 mCapture->expectFGColor(64, 64);
927 // 5 pixels from the foreground we should see the child surface
928 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
929 // 10 pixels from the foreground we should be back to the foreground surface
930 mCapture->expectFGColor(74, 74);
931 }
932}
933
934// Verify for boundless layer with no children, their transforms have no effect.
935TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
936 sp<SurfaceControl> colorLayer =
937 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800938 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700939 ASSERT_TRUE(colorLayer->isValid());
940 asTransaction([&](Transaction& t) {
941 t.setPosition(colorLayer, 320, 320);
942 t.setMatrix(colorLayer, 2, 0, 0, 2);
943 t.setColor(colorLayer, half3{0, 0, 0});
944 t.show(colorLayer);
945 });
946 {
947 mCapture = screenshot();
948 // Top left of background must now be visible
949 mCapture->expectBGColor(0, 0);
950 // Foreground Surface bounds must be color layer
951 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
952 // Color layer should not extend past foreground bounds
953 mCapture->expectBGColor(129, 129);
954 }
955}
956
957// Verify for boundless layer with children, their transforms have an effect.
958TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
959 sp<SurfaceControl> boundlessLayerRightShift =
960 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
961 0 /* flags */, mFGSurfaceControl.get());
962 ASSERT_TRUE(boundlessLayerRightShift->isValid());
963 sp<SurfaceControl> boundlessLayerDownShift =
964 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
965 0 /* flags */, boundlessLayerRightShift.get());
966 ASSERT_TRUE(boundlessLayerDownShift->isValid());
967 sp<SurfaceControl> colorLayer =
968 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800969 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700970 ASSERT_TRUE(colorLayer->isValid());
971 asTransaction([&](Transaction& t) {
972 t.setPosition(boundlessLayerRightShift, 32, 0);
973 t.show(boundlessLayerRightShift);
974 t.setPosition(boundlessLayerDownShift, 0, 32);
975 t.show(boundlessLayerDownShift);
chaviw25714502021-02-11 10:01:08 -0800976 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700977 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 // Top left of foreground must now be visible
985 mCapture->expectFGColor(64, 64);
986 // Foreground Surface bounds must be color layer
987 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
988 // Color layer should not extend past foreground bounds
989 mCapture->expectBGColor(129, 129);
990 }
991}
992
993// Verify child layers do not get clipped if they temporarily move into the negative
994// coordinate space as the result of an intermediate transformation.
995TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
996 sp<SurfaceControl> boundlessLayer =
997 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -0700998 0 /* flags */, mFGSurfaceControl->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700999 ASSERT_TRUE(boundlessLayer != nullptr);
1000 ASSERT_TRUE(boundlessLayer->isValid());
1001 sp<SurfaceControl> colorLayer =
1002 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -07001003 ISurfaceComposerClient::eFXSurfaceEffect,
1004 boundlessLayer->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001005 ASSERT_TRUE(colorLayer != nullptr);
1006 ASSERT_TRUE(colorLayer->isValid());
1007 asTransaction([&](Transaction& t) {
1008 // shift child layer off bounds. If this layer was not boundless, we will
1009 // expect the child layer to be cropped.
1010 t.setPosition(boundlessLayer, 32, 32);
1011 t.show(boundlessLayer);
chaviw25714502021-02-11 10:01:08 -08001012 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001013 // undo shift by parent
1014 t.setPosition(colorLayer, -32, -32);
1015 t.setColor(colorLayer, half3{0, 0, 0});
1016 t.show(colorLayer);
1017 });
1018 {
1019 mCapture = screenshot();
1020 // Top left of background must now be visible
1021 mCapture->expectBGColor(0, 0);
1022 // Foreground Surface bounds must be color layer
1023 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1024 // Color layer should not extend past foreground bounds
1025 mCapture->expectBGColor(129, 129);
1026 }
1027}
1028
1029// Verify for boundless root layers with children, their transforms have an effect.
1030TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1031 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1032 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1033 ASSERT_TRUE(rootBoundlessLayer->isValid());
1034 sp<SurfaceControl> colorLayer =
1035 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001036 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001037
1038 ASSERT_TRUE(colorLayer->isValid());
1039 asTransaction([&](Transaction& t) {
1040 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1041 t.setPosition(rootBoundlessLayer, 32, 32);
1042 t.show(rootBoundlessLayer);
chaviw25714502021-02-11 10:01:08 -08001043 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001044 t.setColor(colorLayer, half3{0, 0, 0});
1045 t.show(colorLayer);
1046 t.hide(mFGSurfaceControl);
1047 });
1048 {
1049 mCapture = screenshot();
1050 // Top left of background must now be visible
1051 mCapture->expectBGColor(0, 0);
1052 // Top left of foreground must now be visible
1053 mCapture->expectBGColor(31, 31);
1054 // Foreground Surface bounds must be color layer
1055 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1056 // Color layer should not extend past foreground bounds
1057 mCapture->expectBGColor(97, 97);
1058 }
1059}
1060
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001061} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001062
1063// TODO(b/129481165): remove the #pragma below and fix conversion issues
1064#pragma clang diagnostic pop // ignored "-Wconversion"