blob: 0cafd001ff0a7c5831e947af2be5d0de882fc2dd [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) {
Robert Carr916b0362020-10-06 13:53:03 -0700569 mFGSurfaceControl->getSurface()->setScalingMode(
570 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
571 // Resubmit buffer with new scaling mode
572 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700573 // We cause scaling by 2.
574 t.setSize(mFGSurfaceControl, 128, 128);
575 });
576
577 {
578 mCapture = screenshot();
579 // We've positioned the child in the top left.
580 mCapture->expectChildColor(0, 0);
581 mCapture->expectChildColor(10, 10);
582 mCapture->expectChildColor(19, 29);
583 // And now it should be scaled all the way to 20x30
584 mCapture->expectFGColor(20, 30);
585 }
586}
587
588// Regression test for b/37673612
589TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
590 asTransaction([&](Transaction& t) {
591 t.show(mChild);
592 t.setPosition(mChild, 0, 0);
593 t.setPosition(mFGSurfaceControl, 0, 0);
594 });
595
596 {
597 mCapture = screenshot();
598 // We've positioned the child in the top left.
599 mCapture->expectChildColor(0, 0);
600 mCapture->expectChildColor(9, 14);
601 // But it's only 10x15.
602 mCapture->expectFGColor(10, 15);
603 }
604 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
605 // the WM specified state size.
606 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
607 sp<Surface> s = mFGSurfaceControl->getSurface();
608 auto anw = static_cast<ANativeWindow*>(s.get());
609 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
610 native_window_set_buffers_dimensions(anw, 64, 128);
611 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
612 waitForPostedBuffers();
613
614 {
615 // The child should still be in the same place and not have any strange scaling as in
616 // b/37673612.
617 mCapture = screenshot();
618 mCapture->expectChildColor(0, 0);
619 mCapture->expectFGColor(10, 10);
620 }
621}
622
623// A child with a buffer transform from its parents should be cropped by its parent bounds.
624TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
625 asTransaction([&](Transaction& t) {
626 t.show(mChild);
627 t.setPosition(mChild, 0, 0);
628 t.setPosition(mFGSurfaceControl, 0, 0);
629 t.setSize(mChild, 100, 100);
630 });
631 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
632
633 {
634 mCapture = screenshot();
635
636 mCapture->expectChildColor(0, 0);
637 mCapture->expectChildColor(63, 63);
638 mCapture->expectBGColor(64, 64);
639 }
640
641 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
642 sp<Surface> s = mFGSurfaceControl->getSurface();
643 auto anw = static_cast<ANativeWindow*>(s.get());
644 // Apply a 90 transform on the buffer.
645 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
646 native_window_set_buffers_dimensions(anw, 64, 128);
647 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
648 waitForPostedBuffers();
649
650 // The child should be cropped by the new parent bounds.
651 {
652 mCapture = screenshot();
653 mCapture->expectChildColor(0, 0);
654 mCapture->expectChildColor(99, 63);
655 mCapture->expectFGColor(100, 63);
656 mCapture->expectBGColor(128, 64);
657 }
658}
659
660// A child with a scale transform from its parents should be cropped by its parent bounds.
661TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
662 asTransaction([&](Transaction& t) {
663 t.show(mChild);
664 t.setPosition(mChild, 0, 0);
665 t.setPosition(mFGSurfaceControl, 0, 0);
666 t.setSize(mChild, 200, 200);
667 });
668 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
669
670 {
671 mCapture = screenshot();
672
673 mCapture->expectChildColor(0, 0);
674 mCapture->expectChildColor(63, 63);
675 mCapture->expectBGColor(64, 64);
676 }
677
678 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700679 mFGSurfaceControl->getSurface()->setScalingMode(
680 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
681 // Resubmit buffer with new scaling mode
682 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700683 // Set a scaling by 2.
684 t.setSize(mFGSurfaceControl, 128, 128);
685 });
686
687 // Child should inherit its parents scale but should be cropped by its parent bounds.
688 {
689 mCapture = screenshot();
690 mCapture->expectChildColor(0, 0);
691 mCapture->expectChildColor(127, 127);
692 mCapture->expectBGColor(128, 128);
693 }
694}
695
696// Regression test for b/127368943
697// Child should ignore the buffer transform but apply parent scale transform.
698TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
699 asTransaction([&](Transaction& t) {
700 t.show(mChild);
701 t.setPosition(mChild, 0, 0);
702 t.setPosition(mFGSurfaceControl, 0, 0);
703 });
704
705 {
706 mCapture = screenshot();
707 mCapture->expectChildColor(0, 0);
708 mCapture->expectChildColor(9, 14);
709 mCapture->expectFGColor(10, 15);
710 }
711
712 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
713 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700714 mFGSurfaceControl->getSurface()->setScalingMode(
715 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
716 // Resubmit buffer with new scaling mode
717 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700718 t.setSize(mFGSurfaceControl, 128, 64);
719 });
720 sp<Surface> s = mFGSurfaceControl->getSurface();
721 auto anw = static_cast<ANativeWindow*>(s.get());
722 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
723 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
724 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
725 native_window_set_buffers_dimensions(anw, 32, 64);
726 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
727 waitForPostedBuffers();
728
729 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
730 {
731 mCapture = screenshot();
732 mCapture->expectChildColor(0, 0);
733 mCapture->expectChildColor(19, 29);
734 mCapture->expectFGColor(20, 30);
735 }
736}
737
738TEST_F(ChildLayerTest, Bug36858924) {
739 // Destroy the child layer
740 mChild.clear();
741
742 // Now recreate it as hidden
743 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
744 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
745
746 // Show the child layer in a deferred transaction
747 asTransaction([&](Transaction& t) {
Pablo Gamito11dcc222020-09-12 15:49:39 +0000748 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700749 mFGSurfaceControl->getSurface()->getNextFrameNumber());
750 t.show(mChild);
751 });
752
753 // Render the foreground surface a few times
754 //
755 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
756 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
757 // never acquire/release the first buffer
758 ALOGI("Filling 1");
759 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
760 ALOGI("Filling 2");
761 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
762 ALOGI("Filling 3");
763 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
764 ALOGI("Filling 4");
765 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
766}
767
768TEST_F(ChildLayerTest, Reparent) {
769 asTransaction([&](Transaction& t) {
770 t.show(mChild);
771 t.setPosition(mChild, 10, 10);
772 t.setPosition(mFGSurfaceControl, 64, 64);
773 });
774
775 {
776 mCapture = screenshot();
777 // Top left of foreground must now be visible
778 mCapture->expectFGColor(64, 64);
779 // But 10 pixels in we should see the child surface
780 mCapture->expectChildColor(74, 74);
781 // And 10 more pixels we should be back to the foreground surface
782 mCapture->expectFGColor(84, 84);
783 }
784
Pablo Gamito11dcc222020-09-12 15:49:39 +0000785 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700786
787 {
788 mCapture = screenshot();
789 mCapture->expectFGColor(64, 64);
790 // In reparenting we should have exposed the entire foreground surface.
791 mCapture->expectFGColor(74, 74);
792 // And the child layer should now begin at 10, 10 (since the BG
793 // layer is at (0, 0)).
794 mCapture->expectBGColor(9, 9);
795 mCapture->expectChildColor(10, 10);
796 }
797}
798
799TEST_F(ChildLayerTest, ReparentToNoParent) {
800 asTransaction([&](Transaction& t) {
801 t.show(mChild);
802 t.setPosition(mChild, 10, 10);
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 // But 10 pixels in we should see the child surface
811 mCapture->expectChildColor(74, 74);
812 // And 10 more pixels we should be back to the foreground surface
813 mCapture->expectFGColor(84, 84);
814 }
815 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
816 {
817 mCapture = screenshot();
818 // The surface should now be offscreen.
819 mCapture->expectFGColor(64, 64);
820 mCapture->expectFGColor(74, 74);
821 mCapture->expectFGColor(84, 84);
822 }
823}
824
825TEST_F(ChildLayerTest, ReparentFromNoParent) {
826 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
827 ASSERT_TRUE(newSurface != nullptr);
828 ASSERT_TRUE(newSurface->isValid());
829
830 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
831 asTransaction([&](Transaction& t) {
832 t.hide(mChild);
833 t.show(newSurface);
834 t.setPosition(newSurface, 10, 10);
835 t.setLayer(newSurface, INT32_MAX - 2);
836 t.setPosition(mFGSurfaceControl, 64, 64);
837 });
838
839 {
840 mCapture = screenshot();
841 // Top left of foreground must now be visible
842 mCapture->expectFGColor(64, 64);
843 // At 10, 10 we should see the new surface
844 mCapture->checkPixel(10, 10, 63, 195, 63);
845 }
846
Pablo Gamito11dcc222020-09-12 15:49:39 +0000847 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700848
849 {
850 mCapture = screenshot();
851 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
852 // mFGSurface, putting it at 74, 74.
853 mCapture->expectFGColor(64, 64);
854 mCapture->checkPixel(74, 74, 63, 195, 63);
855 mCapture->expectFGColor(84, 84);
856 }
857}
858
859TEST_F(ChildLayerTest, NestedChildren) {
860 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
861 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
862 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
863
864 {
865 mCapture = screenshot();
866 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
867 // which begins at 64, 64
868 mCapture->checkPixel(64, 64, 50, 50, 50);
869 }
870}
871
872TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
873 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
874 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
875
876 Transaction t;
877 t.setLayer(relative, INT32_MAX)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000878 .setRelativeLayer(mChild, relative, 1)
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700879 .setPosition(mFGSurfaceControl, 0, 0)
880 .apply(true);
881
882 // We expect that the child should have been elevated above our
883 // INT_MAX layer even though it's not a child of it.
884 {
885 mCapture = screenshot();
886 mCapture->expectChildColor(0, 0);
887 mCapture->expectChildColor(9, 9);
888 mCapture->checkPixel(10, 10, 255, 255, 255);
889 }
890}
891
892class BoundlessLayerTest : public LayerUpdateTest {
893protected:
894 std::unique_ptr<ScreenCapture> mCapture;
895};
896
897// Verify setting a size on a buffer layer has no effect.
898TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
899 sp<SurfaceControl> bufferLayer =
900 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
901 mFGSurfaceControl.get());
902 ASSERT_TRUE(bufferLayer->isValid());
903 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
904 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
905 {
906 mCapture = screenshot();
907 // Top left of background must now be visible
908 mCapture->expectBGColor(0, 0);
909 // Foreground Surface bounds must be color layer
910 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
911 // Buffer layer should not extend past buffer bounds
912 mCapture->expectFGColor(95, 95);
913 }
914}
915
916// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
917// which will crop the color layer.
918TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
919 sp<SurfaceControl> colorLayer =
920 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800921 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700922 ASSERT_TRUE(colorLayer->isValid());
923 asTransaction([&](Transaction& t) {
924 t.setColor(colorLayer, half3{0, 0, 0});
925 t.show(colorLayer);
926 });
927 {
928 mCapture = screenshot();
929 // Top left of background must now be visible
930 mCapture->expectBGColor(0, 0);
931 // Foreground Surface bounds must be color layer
932 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
933 // Color layer should not extend past foreground bounds
934 mCapture->expectBGColor(129, 129);
935 }
936}
937
938// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
939// a crop which will be used to crop the color layer.
940TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
941 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
942 0 /* flags */, mFGSurfaceControl.get());
943 ASSERT_TRUE(cropLayer->isValid());
944 sp<SurfaceControl> colorLayer =
945 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800946 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700947 ASSERT_TRUE(colorLayer->isValid());
948 asTransaction([&](Transaction& t) {
949 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
950 t.setColor(colorLayer, half3{0, 0, 0});
951 t.show(cropLayer);
952 t.show(colorLayer);
953 });
954 {
955 mCapture = screenshot();
956 // Top left of background must now be visible
957 mCapture->expectBGColor(0, 0);
958 // Top left of foreground must now be visible
959 mCapture->expectFGColor(64, 64);
960 // 5 pixels from the foreground we should see the child surface
961 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
962 // 10 pixels from the foreground we should be back to the foreground surface
963 mCapture->expectFGColor(74, 74);
964 }
965}
966
967// Verify for boundless layer with no children, their transforms have no effect.
968TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
969 sp<SurfaceControl> colorLayer =
970 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800971 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700972 ASSERT_TRUE(colorLayer->isValid());
973 asTransaction([&](Transaction& t) {
974 t.setPosition(colorLayer, 320, 320);
975 t.setMatrix(colorLayer, 2, 0, 0, 2);
976 t.setColor(colorLayer, half3{0, 0, 0});
977 t.show(colorLayer);
978 });
979 {
980 mCapture = screenshot();
981 // Top left of background must now be visible
982 mCapture->expectBGColor(0, 0);
983 // Foreground Surface bounds must be color layer
984 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
985 // Color layer should not extend past foreground bounds
986 mCapture->expectBGColor(129, 129);
987 }
988}
989
990// Verify for boundless layer with children, their transforms have an effect.
991TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
992 sp<SurfaceControl> boundlessLayerRightShift =
993 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
994 0 /* flags */, mFGSurfaceControl.get());
995 ASSERT_TRUE(boundlessLayerRightShift->isValid());
996 sp<SurfaceControl> boundlessLayerDownShift =
997 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
998 0 /* flags */, boundlessLayerRightShift.get());
999 ASSERT_TRUE(boundlessLayerDownShift->isValid());
1000 sp<SurfaceControl> colorLayer =
1001 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001002 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001003 ASSERT_TRUE(colorLayer->isValid());
1004 asTransaction([&](Transaction& t) {
1005 t.setPosition(boundlessLayerRightShift, 32, 0);
1006 t.show(boundlessLayerRightShift);
1007 t.setPosition(boundlessLayerDownShift, 0, 32);
1008 t.show(boundlessLayerDownShift);
1009 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1010 t.setColor(colorLayer, half3{0, 0, 0});
1011 t.show(colorLayer);
1012 });
1013 {
1014 mCapture = screenshot();
1015 // Top left of background must now be visible
1016 mCapture->expectBGColor(0, 0);
1017 // Top left of foreground must now be visible
1018 mCapture->expectFGColor(64, 64);
1019 // Foreground Surface bounds must be color layer
1020 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1021 // Color layer should not extend past foreground bounds
1022 mCapture->expectBGColor(129, 129);
1023 }
1024}
1025
1026// Verify child layers do not get clipped if they temporarily move into the negative
1027// coordinate space as the result of an intermediate transformation.
1028TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1029 sp<SurfaceControl> boundlessLayer =
1030 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1031 0 /* flags */, mFGSurfaceControl.get());
1032 ASSERT_TRUE(boundlessLayer != nullptr);
1033 ASSERT_TRUE(boundlessLayer->isValid());
1034 sp<SurfaceControl> colorLayer =
1035 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001036 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001037 ASSERT_TRUE(colorLayer != nullptr);
1038 ASSERT_TRUE(colorLayer->isValid());
1039 asTransaction([&](Transaction& t) {
1040 // shift child layer off bounds. If this layer was not boundless, we will
1041 // expect the child layer to be cropped.
1042 t.setPosition(boundlessLayer, 32, 32);
1043 t.show(boundlessLayer);
1044 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1045 // undo shift by parent
1046 t.setPosition(colorLayer, -32, -32);
1047 t.setColor(colorLayer, half3{0, 0, 0});
1048 t.show(colorLayer);
1049 });
1050 {
1051 mCapture = screenshot();
1052 // Top left of background must now be visible
1053 mCapture->expectBGColor(0, 0);
1054 // Foreground Surface bounds must be color layer
1055 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1056 // Color layer should not extend past foreground bounds
1057 mCapture->expectBGColor(129, 129);
1058 }
1059}
1060
1061// Verify for boundless root layers with children, their transforms have an effect.
1062TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1063 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1064 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1065 ASSERT_TRUE(rootBoundlessLayer->isValid());
1066 sp<SurfaceControl> colorLayer =
1067 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001068 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001069
1070 ASSERT_TRUE(colorLayer->isValid());
1071 asTransaction([&](Transaction& t) {
1072 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1073 t.setPosition(rootBoundlessLayer, 32, 32);
1074 t.show(rootBoundlessLayer);
1075 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1076 t.setColor(colorLayer, half3{0, 0, 0});
1077 t.show(colorLayer);
1078 t.hide(mFGSurfaceControl);
1079 });
1080 {
1081 mCapture = screenshot();
1082 // Top left of background must now be visible
1083 mCapture->expectBGColor(0, 0);
1084 // Top left of foreground must now be visible
1085 mCapture->expectBGColor(31, 31);
1086 // Foreground Surface bounds must be color layer
1087 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1088 // Color layer should not extend past foreground bounds
1089 mCapture->expectBGColor(97, 97);
1090 }
1091}
1092
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001093} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001094
1095// TODO(b/129481165): remove the #pragma below and fix conversion issues
1096#pragma clang diagnostic pop // ignored "-Wconversion"