blob: 84823f519f6ada24e4ad19343a8cdaa98da593d1 [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);
176 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
177 mSyncSurfaceControl->getSurface()->getNextFrameNumber());
178 });
179
180 asTransaction([&](Transaction& t) {
181 t.setPosition(mFGSurfaceControl, 128, 128);
182 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
183 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
483 asTransaction([&](Transaction& t) {
484 t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle());
485 });
486
487 {
488 mCapture = screenshot();
489 mCapture->expectFGColor(64, 64);
490 // In reparenting we should have exposed the entire foreground surface.
491 mCapture->expectFGColor(74, 74);
492 // And the child layer should now begin at 10, 10 (since the BG
493 // layer is at (0, 0)).
494 mCapture->expectBGColor(9, 9);
495 mCapture->expectChildColor(10, 10);
496 }
497}
498
499TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
500 sp<SurfaceControl> mGrandChild =
501 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
502 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
503
504 {
505 SCOPED_TRACE("Grandchild visible");
506 ScreenCapture::captureScreen(&mCapture);
507 mCapture->checkPixel(64, 64, 111, 111, 111);
508 }
509
Robert Carr0e328f62020-02-06 17:12:08 -0800510 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700511 mChild.clear();
512
513 {
514 SCOPED_TRACE("After destroying child");
515 ScreenCapture::captureScreen(&mCapture);
516 mCapture->expectFGColor(64, 64);
517 }
518
519 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl->getHandle()); });
520
521 {
522 SCOPED_TRACE("After reparenting grandchild");
523 ScreenCapture::captureScreen(&mCapture);
524 mCapture->checkPixel(64, 64, 111, 111, 111);
525 }
526}
527
528TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
529 sp<SurfaceControl> mGrandChild =
530 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
531 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
532
533 // draw grand child behind the foreground surface
534 asTransaction([&](Transaction& t) {
535 t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1);
536 });
537
538 {
539 SCOPED_TRACE("Child visible");
540 ScreenCapture::captureScreen(&mCapture);
541 mCapture->checkPixel(64, 64, 200, 200, 200);
542 }
543
544 asTransaction([&](Transaction& t) {
545 t.reparent(mChild, nullptr);
546 t.reparentChildren(mChild, mFGSurfaceControl->getHandle());
547 });
548
549 {
550 SCOPED_TRACE("foreground visible reparenting grandchild");
551 ScreenCapture::captureScreen(&mCapture);
552 mCapture->checkPixel(64, 64, 195, 63, 63);
553 }
554}
555
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700556TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
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 // But it's only 10x15.
568 mCapture->expectFGColor(10, 15);
569 }
570
571 asTransaction([&](Transaction& t) {
572 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
573 // 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) {
679 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
680 // Set a scaling by 2.
681 t.setSize(mFGSurfaceControl, 128, 128);
682 });
683
684 // Child should inherit its parents scale but should be cropped by its parent bounds.
685 {
686 mCapture = screenshot();
687 mCapture->expectChildColor(0, 0);
688 mCapture->expectChildColor(127, 127);
689 mCapture->expectBGColor(128, 128);
690 }
691}
692
693// Regression test for b/127368943
694// Child should ignore the buffer transform but apply parent scale transform.
695TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
696 asTransaction([&](Transaction& t) {
697 t.show(mChild);
698 t.setPosition(mChild, 0, 0);
699 t.setPosition(mFGSurfaceControl, 0, 0);
700 });
701
702 {
703 mCapture = screenshot();
704 mCapture->expectChildColor(0, 0);
705 mCapture->expectChildColor(9, 14);
706 mCapture->expectFGColor(10, 15);
707 }
708
709 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
710 asTransaction([&](Transaction& t) {
711 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
712 t.setSize(mFGSurfaceControl, 128, 64);
713 });
714 sp<Surface> s = mFGSurfaceControl->getSurface();
715 auto anw = static_cast<ANativeWindow*>(s.get());
716 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
717 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
718 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
719 native_window_set_buffers_dimensions(anw, 32, 64);
720 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
721 waitForPostedBuffers();
722
723 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
724 {
725 mCapture = screenshot();
726 mCapture->expectChildColor(0, 0);
727 mCapture->expectChildColor(19, 29);
728 mCapture->expectFGColor(20, 30);
729 }
730}
731
732TEST_F(ChildLayerTest, Bug36858924) {
733 // Destroy the child layer
734 mChild.clear();
735
736 // Now recreate it as hidden
737 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
738 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
739
740 // Show the child layer in a deferred transaction
741 asTransaction([&](Transaction& t) {
742 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl->getHandle(),
743 mFGSurfaceControl->getSurface()->getNextFrameNumber());
744 t.show(mChild);
745 });
746
747 // Render the foreground surface a few times
748 //
749 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
750 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
751 // never acquire/release the first buffer
752 ALOGI("Filling 1");
753 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
754 ALOGI("Filling 2");
755 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
756 ALOGI("Filling 3");
757 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
758 ALOGI("Filling 4");
759 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
760}
761
762TEST_F(ChildLayerTest, Reparent) {
763 asTransaction([&](Transaction& t) {
764 t.show(mChild);
765 t.setPosition(mChild, 10, 10);
766 t.setPosition(mFGSurfaceControl, 64, 64);
767 });
768
769 {
770 mCapture = screenshot();
771 // Top left of foreground must now be visible
772 mCapture->expectFGColor(64, 64);
773 // But 10 pixels in we should see the child surface
774 mCapture->expectChildColor(74, 74);
775 // And 10 more pixels we should be back to the foreground surface
776 mCapture->expectFGColor(84, 84);
777 }
778
779 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl->getHandle()); });
780
781 {
782 mCapture = screenshot();
783 mCapture->expectFGColor(64, 64);
784 // In reparenting we should have exposed the entire foreground surface.
785 mCapture->expectFGColor(74, 74);
786 // And the child layer should now begin at 10, 10 (since the BG
787 // layer is at (0, 0)).
788 mCapture->expectBGColor(9, 9);
789 mCapture->expectChildColor(10, 10);
790 }
791}
792
793TEST_F(ChildLayerTest, ReparentToNoParent) {
794 asTransaction([&](Transaction& t) {
795 t.show(mChild);
796 t.setPosition(mChild, 10, 10);
797 t.setPosition(mFGSurfaceControl, 64, 64);
798 });
799
800 {
801 mCapture = screenshot();
802 // Top left of foreground must now be visible
803 mCapture->expectFGColor(64, 64);
804 // But 10 pixels in we should see the child surface
805 mCapture->expectChildColor(74, 74);
806 // And 10 more pixels we should be back to the foreground surface
807 mCapture->expectFGColor(84, 84);
808 }
809 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
810 {
811 mCapture = screenshot();
812 // The surface should now be offscreen.
813 mCapture->expectFGColor(64, 64);
814 mCapture->expectFGColor(74, 74);
815 mCapture->expectFGColor(84, 84);
816 }
817}
818
819TEST_F(ChildLayerTest, ReparentFromNoParent) {
820 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
821 ASSERT_TRUE(newSurface != nullptr);
822 ASSERT_TRUE(newSurface->isValid());
823
824 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
825 asTransaction([&](Transaction& t) {
826 t.hide(mChild);
827 t.show(newSurface);
828 t.setPosition(newSurface, 10, 10);
829 t.setLayer(newSurface, INT32_MAX - 2);
830 t.setPosition(mFGSurfaceControl, 64, 64);
831 });
832
833 {
834 mCapture = screenshot();
835 // Top left of foreground must now be visible
836 mCapture->expectFGColor(64, 64);
837 // At 10, 10 we should see the new surface
838 mCapture->checkPixel(10, 10, 63, 195, 63);
839 }
840
841 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl->getHandle()); });
842
843 {
844 mCapture = screenshot();
845 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
846 // mFGSurface, putting it at 74, 74.
847 mCapture->expectFGColor(64, 64);
848 mCapture->checkPixel(74, 74, 63, 195, 63);
849 mCapture->expectFGColor(84, 84);
850 }
851}
852
853TEST_F(ChildLayerTest, NestedChildren) {
854 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
855 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
856 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
857
858 {
859 mCapture = screenshot();
860 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
861 // which begins at 64, 64
862 mCapture->checkPixel(64, 64, 50, 50, 50);
863 }
864}
865
866TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
867 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
868 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
869
870 Transaction t;
871 t.setLayer(relative, INT32_MAX)
872 .setRelativeLayer(mChild, relative->getHandle(), 1)
873 .setPosition(mFGSurfaceControl, 0, 0)
874 .apply(true);
875
876 // We expect that the child should have been elevated above our
877 // INT_MAX layer even though it's not a child of it.
878 {
879 mCapture = screenshot();
880 mCapture->expectChildColor(0, 0);
881 mCapture->expectChildColor(9, 9);
882 mCapture->checkPixel(10, 10, 255, 255, 255);
883 }
884}
885
886class BoundlessLayerTest : public LayerUpdateTest {
887protected:
888 std::unique_ptr<ScreenCapture> mCapture;
889};
890
891// Verify setting a size on a buffer layer has no effect.
892TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
893 sp<SurfaceControl> bufferLayer =
894 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
895 mFGSurfaceControl.get());
896 ASSERT_TRUE(bufferLayer->isValid());
897 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
898 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
899 {
900 mCapture = screenshot();
901 // Top left of background must now be visible
902 mCapture->expectBGColor(0, 0);
903 // Foreground Surface bounds must be color layer
904 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
905 // Buffer layer should not extend past buffer bounds
906 mCapture->expectFGColor(95, 95);
907 }
908}
909
910// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
911// which will crop the color layer.
912TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
913 sp<SurfaceControl> colorLayer =
914 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800915 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700916 ASSERT_TRUE(colorLayer->isValid());
917 asTransaction([&](Transaction& t) {
918 t.setColor(colorLayer, half3{0, 0, 0});
919 t.show(colorLayer);
920 });
921 {
922 mCapture = screenshot();
923 // Top left of background must now be visible
924 mCapture->expectBGColor(0, 0);
925 // Foreground Surface bounds must be color layer
926 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
927 // Color layer should not extend past foreground bounds
928 mCapture->expectBGColor(129, 129);
929 }
930}
931
932// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
933// a crop which will be used to crop the color layer.
934TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
935 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
936 0 /* flags */, mFGSurfaceControl.get());
937 ASSERT_TRUE(cropLayer->isValid());
938 sp<SurfaceControl> colorLayer =
939 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800940 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700941 ASSERT_TRUE(colorLayer->isValid());
942 asTransaction([&](Transaction& t) {
943 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
944 t.setColor(colorLayer, half3{0, 0, 0});
945 t.show(cropLayer);
946 t.show(colorLayer);
947 });
948 {
949 mCapture = screenshot();
950 // Top left of background must now be visible
951 mCapture->expectBGColor(0, 0);
952 // Top left of foreground must now be visible
953 mCapture->expectFGColor(64, 64);
954 // 5 pixels from the foreground we should see the child surface
955 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
956 // 10 pixels from the foreground we should be back to the foreground surface
957 mCapture->expectFGColor(74, 74);
958 }
959}
960
961// Verify for boundless layer with no children, their transforms have no effect.
962TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
963 sp<SurfaceControl> colorLayer =
964 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800965 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700966 ASSERT_TRUE(colorLayer->isValid());
967 asTransaction([&](Transaction& t) {
968 t.setPosition(colorLayer, 320, 320);
969 t.setMatrix(colorLayer, 2, 0, 0, 2);
970 t.setColor(colorLayer, half3{0, 0, 0});
971 t.show(colorLayer);
972 });
973 {
974 mCapture = screenshot();
975 // Top left of background must now be visible
976 mCapture->expectBGColor(0, 0);
977 // Foreground Surface bounds must be color layer
978 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
979 // Color layer should not extend past foreground bounds
980 mCapture->expectBGColor(129, 129);
981 }
982}
983
984// Verify for boundless layer with children, their transforms have an effect.
985TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
986 sp<SurfaceControl> boundlessLayerRightShift =
987 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
988 0 /* flags */, mFGSurfaceControl.get());
989 ASSERT_TRUE(boundlessLayerRightShift->isValid());
990 sp<SurfaceControl> boundlessLayerDownShift =
991 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
992 0 /* flags */, boundlessLayerRightShift.get());
993 ASSERT_TRUE(boundlessLayerDownShift->isValid());
994 sp<SurfaceControl> colorLayer =
995 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800996 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700997 ASSERT_TRUE(colorLayer->isValid());
998 asTransaction([&](Transaction& t) {
999 t.setPosition(boundlessLayerRightShift, 32, 0);
1000 t.show(boundlessLayerRightShift);
1001 t.setPosition(boundlessLayerDownShift, 0, 32);
1002 t.show(boundlessLayerDownShift);
1003 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1004 t.setColor(colorLayer, half3{0, 0, 0});
1005 t.show(colorLayer);
1006 });
1007 {
1008 mCapture = screenshot();
1009 // Top left of background must now be visible
1010 mCapture->expectBGColor(0, 0);
1011 // Top left of foreground must now be visible
1012 mCapture->expectFGColor(64, 64);
1013 // Foreground Surface bounds must be color layer
1014 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1015 // Color layer should not extend past foreground bounds
1016 mCapture->expectBGColor(129, 129);
1017 }
1018}
1019
1020// Verify child layers do not get clipped if they temporarily move into the negative
1021// coordinate space as the result of an intermediate transformation.
1022TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1023 sp<SurfaceControl> boundlessLayer =
1024 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1025 0 /* flags */, mFGSurfaceControl.get());
1026 ASSERT_TRUE(boundlessLayer != nullptr);
1027 ASSERT_TRUE(boundlessLayer->isValid());
1028 sp<SurfaceControl> colorLayer =
1029 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001030 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001031 ASSERT_TRUE(colorLayer != nullptr);
1032 ASSERT_TRUE(colorLayer->isValid());
1033 asTransaction([&](Transaction& t) {
1034 // shift child layer off bounds. If this layer was not boundless, we will
1035 // expect the child layer to be cropped.
1036 t.setPosition(boundlessLayer, 32, 32);
1037 t.show(boundlessLayer);
1038 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1039 // undo shift by parent
1040 t.setPosition(colorLayer, -32, -32);
1041 t.setColor(colorLayer, half3{0, 0, 0});
1042 t.show(colorLayer);
1043 });
1044 {
1045 mCapture = screenshot();
1046 // Top left of background must now be visible
1047 mCapture->expectBGColor(0, 0);
1048 // Foreground Surface bounds must be color layer
1049 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1050 // Color layer should not extend past foreground bounds
1051 mCapture->expectBGColor(129, 129);
1052 }
1053}
1054
1055// Verify for boundless root layers with children, their transforms have an effect.
1056TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1057 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1058 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1059 ASSERT_TRUE(rootBoundlessLayer->isValid());
1060 sp<SurfaceControl> colorLayer =
1061 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001062 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001063
1064 ASSERT_TRUE(colorLayer->isValid());
1065 asTransaction([&](Transaction& t) {
1066 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1067 t.setPosition(rootBoundlessLayer, 32, 32);
1068 t.show(rootBoundlessLayer);
1069 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1070 t.setColor(colorLayer, half3{0, 0, 0});
1071 t.show(colorLayer);
1072 t.hide(mFGSurfaceControl);
1073 });
1074 {
1075 mCapture = screenshot();
1076 // Top left of background must now be visible
1077 mCapture->expectBGColor(0, 0);
1078 // Top left of foreground must now be visible
1079 mCapture->expectBGColor(31, 31);
1080 // Foreground Surface bounds must be color layer
1081 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1082 // Color layer should not extend past foreground bounds
1083 mCapture->expectBGColor(97, 97);
1084 }
1085}
1086
1087class ScreenCaptureTest : public LayerUpdateTest {
1088protected:
1089 std::unique_ptr<ScreenCapture> mCapture;
1090};
1091
1092TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
1093 auto bgHandle = mBGSurfaceControl->getHandle();
1094 ScreenCapture::captureLayers(&mCapture, bgHandle);
1095 mCapture->expectBGColor(0, 0);
1096 // Doesn't capture FG layer which is at 64, 64
1097 mCapture->expectBGColor(64, 64);
1098}
1099
1100TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
1101 auto fgHandle = mFGSurfaceControl->getHandle();
1102
1103 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1104 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1105 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1106
1107 SurfaceComposerClient::Transaction().show(child).apply(true);
1108
1109 // Captures mFGSurfaceControl layer and its child.
1110 ScreenCapture::captureLayers(&mCapture, fgHandle);
1111 mCapture->expectFGColor(10, 10);
1112 mCapture->expectChildColor(0, 0);
1113}
1114
1115TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
1116 auto fgHandle = mFGSurfaceControl->getHandle();
1117
1118 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1119 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1120 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1121
1122 SurfaceComposerClient::Transaction().show(child).apply(true);
1123
1124 // Captures mFGSurfaceControl's child
1125 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
1126 mCapture->checkPixel(10, 10, 0, 0, 0);
1127 mCapture->expectChildColor(0, 0);
1128}
1129
1130TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
1131 auto fgHandle = mFGSurfaceControl->getHandle();
1132
1133 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1134 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1135 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1136 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
1137 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1138 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1139
1140 SurfaceComposerClient::Transaction()
1141 .show(child)
1142 .show(child2)
1143 .setLayer(child, 1)
1144 .setLayer(child2, 2)
1145 .apply(true);
1146
1147 // Child2 would be visible but its excluded, so we should see child1 color instead.
1148 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
1149 mCapture->checkPixel(10, 10, 0, 0, 0);
1150 mCapture->checkPixel(0, 0, 200, 200, 200);
1151}
1152
1153// Like the last test but verifies that children are also exclude.
1154TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
1155 auto fgHandle = mFGSurfaceControl->getHandle();
1156
1157 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1158 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1159 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1160 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
1161 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1162 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1163 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
1164 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
1165 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1166
1167 SurfaceComposerClient::Transaction()
1168 .show(child)
1169 .show(child2)
1170 .show(child3)
1171 .setLayer(child, 1)
1172 .setLayer(child2, 2)
1173 .apply(true);
1174
1175 // Child2 would be visible but its excluded, so we should see child1 color instead.
1176 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
1177 mCapture->checkPixel(10, 10, 0, 0, 0);
1178 mCapture->checkPixel(0, 0, 200, 200, 200);
1179}
1180
1181TEST_F(ScreenCaptureTest, CaptureTransparent) {
1182 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1183 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1184
1185 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1186
1187 SurfaceComposerClient::Transaction().show(child).apply(true);
1188
1189 auto childHandle = child->getHandle();
1190
1191 // Captures child
1192 ScreenCapture::captureLayers(&mCapture, childHandle, {0, 0, 10, 20});
1193 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
1194 // Area outside of child's bounds is transparent.
1195 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
1196}
1197
1198TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
1199 auto fgHandle = mFGSurfaceControl->getHandle();
1200
1201 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1202 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1203 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
1204 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
1205 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1206 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
1207
1208 SurfaceComposerClient::Transaction()
1209 .show(child)
1210 // Set relative layer above fg layer so should be shown above when computing all layers.
1211 .setRelativeLayer(relative, fgHandle, 1)
1212 .show(relative)
1213 .apply(true);
1214
1215 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
1216 ScreenCapture::captureLayers(&mCapture, fgHandle);
1217 mCapture->expectFGColor(10, 10);
1218 mCapture->expectChildColor(0, 0);
1219}
1220
1221TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
1222 auto fgHandle = mFGSurfaceControl->getHandle();
1223
1224 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1225 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1226 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
1227 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1228 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1229 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
1230
1231 SurfaceComposerClient::Transaction()
1232 .show(child)
1233 // Set relative layer below fg layer but relative to child layer so it should be shown
1234 // above child layer.
1235 .setLayer(relative, -1)
1236 .setRelativeLayer(relative, child->getHandle(), 1)
1237 .show(relative)
1238 .apply(true);
1239
1240 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
1241 // relative value should be taken into account, placing it above child layer.
1242 ScreenCapture::captureLayers(&mCapture, fgHandle);
1243 mCapture->expectFGColor(10, 10);
1244 // Relative layer is showing on top of child layer
1245 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
1246}
1247
Vishnu Nairefc42e22019-12-03 17:36:12 -08001248TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
1249 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1250 SurfaceComposerClient::Transaction().show(child).apply(true);
1251
1252 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1253 sp<GraphicBuffer> outBuffer;
1254 Rect sourceCrop(0, 0, 10, 10);
1255 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1256 ScreenCapture sc(outBuffer);
1257
1258 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1259}
1260
1261TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
1262 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1263 Rect layerCrop(0, 0, 10, 10);
1264 SurfaceComposerClient::Transaction().setCrop_legacy(child, layerCrop).show(child).apply(true);
1265
1266 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1267 sp<GraphicBuffer> outBuffer;
1268 Rect sourceCrop = Rect();
1269 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1270 ScreenCapture sc(outBuffer);
1271
1272 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1273}
1274
1275TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
1276 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1277 SurfaceComposerClient::Transaction().show(child).apply(true);
1278
1279 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1280 sp<GraphicBuffer> outBuffer;
1281 Rect sourceCrop = Rect();
1282
1283 ASSERT_EQ(BAD_VALUE, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1284}
1285
1286TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
1287 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1288 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1289 SurfaceComposerClient::Transaction().show(child).apply(true);
1290
1291 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1292 sp<GraphicBuffer> outBuffer;
1293 Rect sourceCrop = Rect();
1294 ASSERT_EQ(BAD_VALUE, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1295
1296 TransactionUtils::fillSurfaceRGBA8(child, Color::RED);
1297 SurfaceComposerClient::Transaction().apply(true);
1298 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1299 ScreenCapture sc(outBuffer);
1300 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1301}
1302
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001303// In the following tests we verify successful skipping of a parent layer,
1304// so we use the same verification logic and only change how we mutate
1305// the parent layer to verify that various properties are ignored.
1306class ScreenCaptureChildOnlyTest : public LayerUpdateTest {
1307public:
1308 void SetUp() override {
1309 LayerUpdateTest::SetUp();
1310
1311 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
1312 mFGSurfaceControl.get());
1313 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
1314
1315 SurfaceComposerClient::Transaction().show(mChild).apply(true);
1316 }
1317
1318 void verify(std::function<void()> verifyStartingState) {
1319 // Verify starting state before a screenshot is taken.
1320 verifyStartingState();
1321
1322 // Verify child layer does not inherit any of the properties of its
1323 // parent when its screenshot is captured.
1324 auto fgHandle = mFGSurfaceControl->getHandle();
1325 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
1326 mCapture->checkPixel(10, 10, 0, 0, 0);
1327 mCapture->expectChildColor(0, 0);
1328
1329 // Verify all assumptions are still true after the screenshot is taken.
1330 verifyStartingState();
1331 }
1332
1333 std::unique_ptr<ScreenCapture> mCapture;
1334 sp<SurfaceControl> mChild;
1335};
1336
1337// Regression test b/76099859
1338TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
1339 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
1340
1341 // Even though the parent is hidden we should still capture the child.
1342
1343 // Before and after reparenting, verify child is properly hidden
1344 // when rendering full-screen.
1345 verify([&] { screenshot()->expectBGColor(64, 64); });
1346}
1347
1348TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
1349 SurfaceComposerClient::Transaction()
1350 .setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 1, 1))
1351 .apply(true);
1352
1353 // Even though the parent is cropped out we should still capture the child.
1354
1355 // Before and after reparenting, verify child is cropped by parent.
1356 verify([&] { screenshot()->expectBGColor(65, 65); });
1357}
1358
1359// Regression test b/124372894
1360TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
1361 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
1362
1363 // We should not inherit the parent scaling.
1364
1365 // Before and after reparenting, verify child is properly scaled.
1366 verify([&] { screenshot()->expectChildColor(80, 80); });
1367}
1368
1369TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
1370 auto fgHandle = mFGSurfaceControl->getHandle();
1371
1372 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1373 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1374 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1375
1376 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
1377 PIXEL_FORMAT_RGBA_8888, 0, child.get());
1378
1379 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1380 SurfaceComposerClient::Transaction()
1381 .show(child)
1382 .setPosition(grandchild, 5, 5)
1383 .show(grandchild)
1384 .apply(true);
1385
1386 // Captures mFGSurfaceControl, its child, and the grandchild.
1387 ScreenCapture::captureLayers(&mCapture, fgHandle);
1388 mCapture->expectFGColor(10, 10);
1389 mCapture->expectChildColor(0, 0);
1390 mCapture->checkPixel(5, 5, 50, 50, 50);
1391}
1392
1393TEST_F(ScreenCaptureTest, CaptureChildOnly) {
1394 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1395 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1396 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1397 auto childHandle = child->getHandle();
1398
1399 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
1400
1401 // Captures only the child layer, and not the parent.
1402 ScreenCapture::captureLayers(&mCapture, childHandle);
1403 mCapture->expectChildColor(0, 0);
1404 mCapture->expectChildColor(9, 9);
1405}
1406
1407TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
1408 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1409 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1410 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1411 auto childHandle = child->getHandle();
1412
1413 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
1414 PIXEL_FORMAT_RGBA_8888, 0, child.get());
1415 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1416
1417 SurfaceComposerClient::Transaction()
1418 .show(child)
1419 .setPosition(grandchild, 5, 5)
1420 .show(grandchild)
1421 .apply(true);
1422
1423 auto grandchildHandle = grandchild->getHandle();
1424
1425 // Captures only the grandchild.
1426 ScreenCapture::captureLayers(&mCapture, grandchildHandle);
1427 mCapture->checkPixel(0, 0, 50, 50, 50);
1428 mCapture->checkPixel(4, 4, 50, 50, 50);
1429}
1430
1431TEST_F(ScreenCaptureTest, CaptureCrop) {
1432 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1433 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
1434 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
1435
1436 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1437 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
1438
1439 SurfaceComposerClient::Transaction()
1440 .setLayer(redLayer, INT32_MAX - 1)
1441 .show(redLayer)
1442 .show(blueLayer)
1443 .apply(true);
1444
1445 auto redLayerHandle = redLayer->getHandle();
1446
1447 // Capturing full screen should have both red and blue are visible.
1448 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
1449 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1450 // red area below the blue area
1451 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
1452 // red area to the right of the blue area
1453 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
1454
1455 const Rect crop = Rect(0, 0, 30, 30);
1456 ScreenCapture::captureLayers(&mCapture, redLayerHandle, crop);
1457 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
1458 // area visible.
1459 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1460 mCapture->checkPixel(30, 30, 0, 0, 0);
1461}
1462
1463TEST_F(ScreenCaptureTest, CaptureSize) {
1464 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1465 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
1466 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
1467
1468 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1469 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
1470
1471 SurfaceComposerClient::Transaction()
1472 .setLayer(redLayer, INT32_MAX - 1)
1473 .show(redLayer)
1474 .show(blueLayer)
1475 .apply(true);
1476
1477 auto redLayerHandle = redLayer->getHandle();
1478
1479 // Capturing full screen should have both red and blue are visible.
1480 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
1481 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1482 // red area below the blue area
1483 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
1484 // red area to the right of the blue area
1485 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
1486
1487 ScreenCapture::captureLayers(&mCapture, redLayerHandle, Rect::EMPTY_RECT, 0.5);
1488 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
1489 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
1490 // red area below the blue area
1491 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
1492 // red area to the right of the blue area
1493 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
1494 mCapture->checkPixel(30, 30, 0, 0, 0);
1495}
1496
1497TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
1498 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1499
1500 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1501
1502 auto redLayerHandle = redLayer->getHandle();
Robert Carr0e328f62020-02-06 17:12:08 -08001503 Transaction().reparent(redLayer, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001504 redLayer.clear();
1505 SurfaceComposerClient::Transaction().apply(true);
1506
1507 sp<GraphicBuffer> outBuffer;
1508
1509 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
1510 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1511 ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(redLayerHandle, &outBuffer, Rect::EMPTY_RECT, 1.0));
1512}
1513} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001514
1515// TODO(b/129481165): remove the #pragma below and fix conversion issues
1516#pragma clang diagnostic pop // ignored "-Wconversion"