blob: e5c2ec8bfb0d748d8c8d8de14b2a68a4ba5f6e56 [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
465TEST_F(ChildLayerTest, ReparentChildren) {
466 asTransaction([&](Transaction& t) {
467 t.show(mChild);
468 t.setPosition(mChild, 10, 10);
469 t.setPosition(mFGSurfaceControl, 64, 64);
470 });
471
472 {
473 mCapture = screenshot();
474 // Top left of foreground must now be visible
475 mCapture->expectFGColor(64, 64);
476 // But 10 pixels in we should see the child surface
477 mCapture->expectChildColor(74, 74);
478 // And 10 more pixels we should be back to the foreground surface
479 mCapture->expectFGColor(84, 84);
480 }
481
Pablo Gamito11dcc222020-09-12 15:49:39 +0000482 asTransaction(
483 [&](Transaction& t) { t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700484
485 {
486 mCapture = screenshot();
487 mCapture->expectFGColor(64, 64);
488 // In reparenting we should have exposed the entire foreground surface.
489 mCapture->expectFGColor(74, 74);
490 // And the child layer should now begin at 10, 10 (since the BG
491 // layer is at (0, 0)).
492 mCapture->expectBGColor(9, 9);
493 mCapture->expectChildColor(10, 10);
494 }
495}
496
497TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
498 sp<SurfaceControl> mGrandChild =
499 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
500 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
501
502 {
503 SCOPED_TRACE("Grandchild visible");
504 ScreenCapture::captureScreen(&mCapture);
505 mCapture->checkPixel(64, 64, 111, 111, 111);
506 }
507
Robert Carr0e328f62020-02-06 17:12:08 -0800508 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700509 mChild.clear();
510
511 {
512 SCOPED_TRACE("After destroying child");
513 ScreenCapture::captureScreen(&mCapture);
514 mCapture->expectFGColor(64, 64);
515 }
516
Pablo Gamito11dcc222020-09-12 15:49:39 +0000517 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700518
519 {
520 SCOPED_TRACE("After reparenting grandchild");
521 ScreenCapture::captureScreen(&mCapture);
522 mCapture->checkPixel(64, 64, 111, 111, 111);
523 }
524}
525
526TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
527 sp<SurfaceControl> mGrandChild =
528 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
529 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
530
531 // draw grand child behind the foreground surface
Pablo Gamito11dcc222020-09-12 15:49:39 +0000532 asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700533
534 {
535 SCOPED_TRACE("Child visible");
536 ScreenCapture::captureScreen(&mCapture);
537 mCapture->checkPixel(64, 64, 200, 200, 200);
538 }
539
540 asTransaction([&](Transaction& t) {
541 t.reparent(mChild, nullptr);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000542 t.reparentChildren(mChild, mFGSurfaceControl);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700543 });
544
545 {
546 SCOPED_TRACE("foreground visible reparenting grandchild");
547 ScreenCapture::captureScreen(&mCapture);
548 mCapture->checkPixel(64, 64, 195, 63, 63);
549 }
550}
551
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700552TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
553 asTransaction([&](Transaction& t) {
554 t.show(mChild);
555 t.setPosition(mChild, 0, 0);
556 t.setPosition(mFGSurfaceControl, 0, 0);
557 });
558
559 {
560 mCapture = screenshot();
561 // We've positioned the child in the top left.
562 mCapture->expectChildColor(0, 0);
563 // But it's only 10x15.
564 mCapture->expectFGColor(10, 15);
565 }
566
567 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700568 mFGSurfaceControl->getSurface()->setScalingMode(
569 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
570 // Resubmit buffer with new scaling mode
571 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700572 // We cause scaling by 2.
573 t.setSize(mFGSurfaceControl, 128, 128);
574 });
575
576 {
577 mCapture = screenshot();
578 // We've positioned the child in the top left.
579 mCapture->expectChildColor(0, 0);
580 mCapture->expectChildColor(10, 10);
581 mCapture->expectChildColor(19, 29);
582 // And now it should be scaled all the way to 20x30
583 mCapture->expectFGColor(20, 30);
584 }
585}
586
587// Regression test for b/37673612
588TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
589 asTransaction([&](Transaction& t) {
590 t.show(mChild);
591 t.setPosition(mChild, 0, 0);
592 t.setPosition(mFGSurfaceControl, 0, 0);
593 });
594
595 {
596 mCapture = screenshot();
597 // We've positioned the child in the top left.
598 mCapture->expectChildColor(0, 0);
599 mCapture->expectChildColor(9, 14);
600 // But it's only 10x15.
601 mCapture->expectFGColor(10, 15);
602 }
603 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
604 // the WM specified state size.
605 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
606 sp<Surface> s = mFGSurfaceControl->getSurface();
607 auto anw = static_cast<ANativeWindow*>(s.get());
608 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
609 native_window_set_buffers_dimensions(anw, 64, 128);
610 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
611 waitForPostedBuffers();
612
613 {
614 // The child should still be in the same place and not have any strange scaling as in
615 // b/37673612.
616 mCapture = screenshot();
617 mCapture->expectChildColor(0, 0);
618 mCapture->expectFGColor(10, 10);
619 }
620}
621
622// A child with a buffer transform from its parents should be cropped by its parent bounds.
623TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
624 asTransaction([&](Transaction& t) {
625 t.show(mChild);
626 t.setPosition(mChild, 0, 0);
627 t.setPosition(mFGSurfaceControl, 0, 0);
628 t.setSize(mChild, 100, 100);
629 });
630 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
631
632 {
633 mCapture = screenshot();
634
635 mCapture->expectChildColor(0, 0);
636 mCapture->expectChildColor(63, 63);
637 mCapture->expectBGColor(64, 64);
638 }
639
640 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
641 sp<Surface> s = mFGSurfaceControl->getSurface();
642 auto anw = static_cast<ANativeWindow*>(s.get());
643 // Apply a 90 transform on the buffer.
644 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
645 native_window_set_buffers_dimensions(anw, 64, 128);
646 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
647 waitForPostedBuffers();
648
649 // The child should be cropped by the new parent bounds.
650 {
651 mCapture = screenshot();
652 mCapture->expectChildColor(0, 0);
653 mCapture->expectChildColor(99, 63);
654 mCapture->expectFGColor(100, 63);
655 mCapture->expectBGColor(128, 64);
656 }
657}
658
659// A child with a scale transform from its parents should be cropped by its parent bounds.
660TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
661 asTransaction([&](Transaction& t) {
662 t.show(mChild);
663 t.setPosition(mChild, 0, 0);
664 t.setPosition(mFGSurfaceControl, 0, 0);
665 t.setSize(mChild, 200, 200);
666 });
667 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
668
669 {
670 mCapture = screenshot();
671
672 mCapture->expectChildColor(0, 0);
673 mCapture->expectChildColor(63, 63);
674 mCapture->expectBGColor(64, 64);
675 }
676
677 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700678 mFGSurfaceControl->getSurface()->setScalingMode(
679 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
680 // Resubmit buffer with new scaling mode
681 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700682 // Set a scaling by 2.
683 t.setSize(mFGSurfaceControl, 128, 128);
684 });
685
686 // Child should inherit its parents scale but should be cropped by its parent bounds.
687 {
688 mCapture = screenshot();
689 mCapture->expectChildColor(0, 0);
690 mCapture->expectChildColor(127, 127);
691 mCapture->expectBGColor(128, 128);
692 }
693}
694
695// Regression test for b/127368943
696// Child should ignore the buffer transform but apply parent scale transform.
697TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
698 asTransaction([&](Transaction& t) {
699 t.show(mChild);
700 t.setPosition(mChild, 0, 0);
701 t.setPosition(mFGSurfaceControl, 0, 0);
702 });
703
704 {
705 mCapture = screenshot();
706 mCapture->expectChildColor(0, 0);
707 mCapture->expectChildColor(9, 14);
708 mCapture->expectFGColor(10, 15);
709 }
710
711 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
712 asTransaction([&](Transaction& t) {
Robert Carr916b0362020-10-06 13:53:03 -0700713 mFGSurfaceControl->getSurface()->setScalingMode(
714 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
715 // Resubmit buffer with new scaling mode
716 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700717 t.setSize(mFGSurfaceControl, 128, 64);
718 });
719 sp<Surface> s = mFGSurfaceControl->getSurface();
720 auto anw = static_cast<ANativeWindow*>(s.get());
721 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
722 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
723 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
724 native_window_set_buffers_dimensions(anw, 32, 64);
725 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
726 waitForPostedBuffers();
727
728 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
729 {
730 mCapture = screenshot();
731 mCapture->expectChildColor(0, 0);
732 mCapture->expectChildColor(19, 29);
733 mCapture->expectFGColor(20, 30);
734 }
735}
736
737TEST_F(ChildLayerTest, Bug36858924) {
738 // Destroy the child layer
739 mChild.clear();
740
741 // Now recreate it as hidden
742 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
743 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
744
745 // Show the child layer in a deferred transaction
746 asTransaction([&](Transaction& t) {
Pablo Gamito11dcc222020-09-12 15:49:39 +0000747 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl,
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700748 mFGSurfaceControl->getSurface()->getNextFrameNumber());
749 t.show(mChild);
750 });
751
752 // Render the foreground surface a few times
753 //
754 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
755 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
756 // never acquire/release the first buffer
757 ALOGI("Filling 1");
758 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
759 ALOGI("Filling 2");
760 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
761 ALOGI("Filling 3");
762 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
763 ALOGI("Filling 4");
764 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
765}
766
767TEST_F(ChildLayerTest, Reparent) {
768 asTransaction([&](Transaction& t) {
769 t.show(mChild);
770 t.setPosition(mChild, 10, 10);
771 t.setPosition(mFGSurfaceControl, 64, 64);
772 });
773
774 {
775 mCapture = screenshot();
776 // Top left of foreground must now be visible
777 mCapture->expectFGColor(64, 64);
778 // But 10 pixels in we should see the child surface
779 mCapture->expectChildColor(74, 74);
780 // And 10 more pixels we should be back to the foreground surface
781 mCapture->expectFGColor(84, 84);
782 }
783
Pablo Gamito11dcc222020-09-12 15:49:39 +0000784 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700785
786 {
787 mCapture = screenshot();
788 mCapture->expectFGColor(64, 64);
789 // In reparenting we should have exposed the entire foreground surface.
790 mCapture->expectFGColor(74, 74);
791 // And the child layer should now begin at 10, 10 (since the BG
792 // layer is at (0, 0)).
793 mCapture->expectBGColor(9, 9);
794 mCapture->expectChildColor(10, 10);
795 }
796}
797
798TEST_F(ChildLayerTest, ReparentToNoParent) {
799 asTransaction([&](Transaction& t) {
800 t.show(mChild);
801 t.setPosition(mChild, 10, 10);
802 t.setPosition(mFGSurfaceControl, 64, 64);
803 });
804
805 {
806 mCapture = screenshot();
807 // Top left of foreground must now be visible
808 mCapture->expectFGColor(64, 64);
809 // But 10 pixels in we should see the child surface
810 mCapture->expectChildColor(74, 74);
811 // And 10 more pixels we should be back to the foreground surface
812 mCapture->expectFGColor(84, 84);
813 }
814 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
815 {
816 mCapture = screenshot();
817 // The surface should now be offscreen.
818 mCapture->expectFGColor(64, 64);
819 mCapture->expectFGColor(74, 74);
820 mCapture->expectFGColor(84, 84);
821 }
822}
823
824TEST_F(ChildLayerTest, ReparentFromNoParent) {
825 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
826 ASSERT_TRUE(newSurface != nullptr);
827 ASSERT_TRUE(newSurface->isValid());
828
829 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
830 asTransaction([&](Transaction& t) {
831 t.hide(mChild);
832 t.show(newSurface);
833 t.setPosition(newSurface, 10, 10);
834 t.setLayer(newSurface, INT32_MAX - 2);
835 t.setPosition(mFGSurfaceControl, 64, 64);
836 });
837
838 {
839 mCapture = screenshot();
840 // Top left of foreground must now be visible
841 mCapture->expectFGColor(64, 64);
842 // At 10, 10 we should see the new surface
843 mCapture->checkPixel(10, 10, 63, 195, 63);
844 }
845
Pablo Gamito11dcc222020-09-12 15:49:39 +0000846 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700847
848 {
849 mCapture = screenshot();
850 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
851 // mFGSurface, putting it at 74, 74.
852 mCapture->expectFGColor(64, 64);
853 mCapture->checkPixel(74, 74, 63, 195, 63);
854 mCapture->expectFGColor(84, 84);
855 }
856}
857
858TEST_F(ChildLayerTest, NestedChildren) {
859 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
860 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
861 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
862
863 {
864 mCapture = screenshot();
865 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
866 // which begins at 64, 64
867 mCapture->checkPixel(64, 64, 50, 50, 50);
868 }
869}
870
871TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
872 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
873 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
874
875 Transaction t;
876 t.setLayer(relative, INT32_MAX)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000877 .setRelativeLayer(mChild, relative, 1)
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700878 .setPosition(mFGSurfaceControl, 0, 0)
879 .apply(true);
880
881 // We expect that the child should have been elevated above our
882 // INT_MAX layer even though it's not a child of it.
883 {
884 mCapture = screenshot();
885 mCapture->expectChildColor(0, 0);
886 mCapture->expectChildColor(9, 9);
887 mCapture->checkPixel(10, 10, 255, 255, 255);
888 }
889}
890
891class BoundlessLayerTest : public LayerUpdateTest {
892protected:
893 std::unique_ptr<ScreenCapture> mCapture;
894};
895
896// Verify setting a size on a buffer layer has no effect.
897TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
898 sp<SurfaceControl> bufferLayer =
899 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
900 mFGSurfaceControl.get());
901 ASSERT_TRUE(bufferLayer->isValid());
902 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
903 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
904 {
905 mCapture = screenshot();
906 // Top left of background must now be visible
907 mCapture->expectBGColor(0, 0);
908 // Foreground Surface bounds must be color layer
909 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
910 // Buffer layer should not extend past buffer bounds
911 mCapture->expectFGColor(95, 95);
912 }
913}
914
915// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
916// which will crop the color layer.
917TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
918 sp<SurfaceControl> colorLayer =
919 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800920 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700921 ASSERT_TRUE(colorLayer->isValid());
922 asTransaction([&](Transaction& t) {
923 t.setColor(colorLayer, half3{0, 0, 0});
924 t.show(colorLayer);
925 });
926 {
927 mCapture = screenshot();
928 // Top left of background must now be visible
929 mCapture->expectBGColor(0, 0);
930 // Foreground Surface bounds must be color layer
931 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
932 // Color layer should not extend past foreground bounds
933 mCapture->expectBGColor(129, 129);
934 }
935}
936
937// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
938// a crop which will be used to crop the color layer.
939TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
940 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
941 0 /* flags */, mFGSurfaceControl.get());
942 ASSERT_TRUE(cropLayer->isValid());
943 sp<SurfaceControl> colorLayer =
944 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800945 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700946 ASSERT_TRUE(colorLayer->isValid());
947 asTransaction([&](Transaction& t) {
chaviw25714502021-02-11 10:01:08 -0800948 t.setCrop(cropLayer, Rect(5, 5, 10, 10));
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700949 t.setColor(colorLayer, half3{0, 0, 0});
950 t.show(cropLayer);
951 t.show(colorLayer);
952 });
953 {
954 mCapture = screenshot();
955 // Top left of background must now be visible
956 mCapture->expectBGColor(0, 0);
957 // Top left of foreground must now be visible
958 mCapture->expectFGColor(64, 64);
959 // 5 pixels from the foreground we should see the child surface
960 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
961 // 10 pixels from the foreground we should be back to the foreground surface
962 mCapture->expectFGColor(74, 74);
963 }
964}
965
966// Verify for boundless layer with no children, their transforms have no effect.
967TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
968 sp<SurfaceControl> colorLayer =
969 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800970 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700971 ASSERT_TRUE(colorLayer->isValid());
972 asTransaction([&](Transaction& t) {
973 t.setPosition(colorLayer, 320, 320);
974 t.setMatrix(colorLayer, 2, 0, 0, 2);
975 t.setColor(colorLayer, half3{0, 0, 0});
976 t.show(colorLayer);
977 });
978 {
979 mCapture = screenshot();
980 // Top left of background must now be visible
981 mCapture->expectBGColor(0, 0);
982 // Foreground Surface bounds must be color layer
983 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
984 // Color layer should not extend past foreground bounds
985 mCapture->expectBGColor(129, 129);
986 }
987}
988
989// Verify for boundless layer with children, their transforms have an effect.
990TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
991 sp<SurfaceControl> boundlessLayerRightShift =
992 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
993 0 /* flags */, mFGSurfaceControl.get());
994 ASSERT_TRUE(boundlessLayerRightShift->isValid());
995 sp<SurfaceControl> boundlessLayerDownShift =
996 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
997 0 /* flags */, boundlessLayerRightShift.get());
998 ASSERT_TRUE(boundlessLayerDownShift->isValid());
999 sp<SurfaceControl> colorLayer =
1000 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001001 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001002 ASSERT_TRUE(colorLayer->isValid());
1003 asTransaction([&](Transaction& t) {
1004 t.setPosition(boundlessLayerRightShift, 32, 0);
1005 t.show(boundlessLayerRightShift);
1006 t.setPosition(boundlessLayerDownShift, 0, 32);
1007 t.show(boundlessLayerDownShift);
chaviw25714502021-02-11 10:01:08 -08001008 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001009 t.setColor(colorLayer, half3{0, 0, 0});
1010 t.show(colorLayer);
1011 });
1012 {
1013 mCapture = screenshot();
1014 // Top left of background must now be visible
1015 mCapture->expectBGColor(0, 0);
1016 // Top left of foreground must now be visible
1017 mCapture->expectFGColor(64, 64);
1018 // Foreground Surface bounds must be color layer
1019 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1020 // Color layer should not extend past foreground bounds
1021 mCapture->expectBGColor(129, 129);
1022 }
1023}
1024
1025// Verify child layers do not get clipped if they temporarily move into the negative
1026// coordinate space as the result of an intermediate transformation.
1027TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1028 sp<SurfaceControl> boundlessLayer =
1029 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -07001030 0 /* flags */, mFGSurfaceControl->getHandle());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001031 ASSERT_TRUE(boundlessLayer != nullptr);
1032 ASSERT_TRUE(boundlessLayer->isValid());
1033 sp<SurfaceControl> colorLayer =
1034 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nair992496b2020-10-22 17:27:21 -07001035 ISurfaceComposerClient::eFXSurfaceEffect,
1036 boundlessLayer->getHandle());
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);
chaviw25714502021-02-11 10:01:08 -08001044 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001045 // 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);
chaviw25714502021-02-11 10:01:08 -08001075 t.setCrop(colorLayer, Rect(0, 0, 64, 64));
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001076 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"