xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/tests/LayerUpdate_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
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 
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 
21 #include "LayerTransactionTest.h"
22 
23 namespace android {
24 
25 using android::hardware::graphics::common::V1_1::BufferUsage;
26 
27 ::testing::Environment* const binderEnv =
28         ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
29 
30 class LayerUpdateTest : public LayerTransactionTest {
31 protected:
SetUp()32     virtual void SetUp() {
33         LayerTransactionTest::SetUp();
34         ASSERT_EQ(NO_ERROR, mClient->initCheck());
35 
36         const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
37         ASSERT_FALSE(ids.empty());
38         const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
39         ASSERT_FALSE(display == nullptr);
40 
41         ui::DisplayMode mode;
42         ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
43         const ui::Size& resolution = mode.resolution;
44 
45         // Background surface
46         mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
47                                         resolution.getHeight(), 0);
48         ASSERT_TRUE(mBGSurfaceControl != nullptr);
49         ASSERT_TRUE(mBGSurfaceControl->isValid());
50         TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
51 
52         // Foreground surface
53         mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
54 
55         ASSERT_TRUE(mFGSurfaceControl != nullptr);
56         ASSERT_TRUE(mFGSurfaceControl->isValid());
57 
58         TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
59 
60         // Synchronization surface
61         mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
62         ASSERT_TRUE(mSyncSurfaceControl != nullptr);
63         ASSERT_TRUE(mSyncSurfaceControl->isValid());
64 
65         TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
66 
67         asTransaction([&](Transaction& t) {
68             t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK);
69 
70             t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
71 
72             t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
73                     .setPosition(mFGSurfaceControl, 64, 64)
74                     .show(mFGSurfaceControl);
75 
76             t.setLayer(mSyncSurfaceControl, INT32_MAX - 1)
77                     .setPosition(mSyncSurfaceControl, resolution.getWidth() - 2,
78                                  resolution.getHeight() - 2)
79                     .show(mSyncSurfaceControl);
80         });
81     }
82 
TearDown()83     virtual void TearDown() {
84         LayerTransactionTest::TearDown();
85         mBGSurfaceControl = 0;
86         mFGSurfaceControl = 0;
87         mSyncSurfaceControl = 0;
88     }
89 
waitForPostedBuffers()90     void waitForPostedBuffers() {
91         // Since the sync surface is in synchronous mode (i.e. double buffered)
92         // posting three buffers to it should ensure that at least two
93         // SurfaceFlinger::handlePageFlip calls have been made, which should
94         // guaranteed that a buffer posted to another Surface has been retired.
95         TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
96         TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
97         TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
98     }
99 
100     sp<SurfaceControl> mBGSurfaceControl;
101     sp<SurfaceControl> mFGSurfaceControl;
102 
103     // This surface is used to ensure that the buffers posted to
104     // mFGSurfaceControl have been picked up by SurfaceFlinger.
105     sp<SurfaceControl> mSyncSurfaceControl;
106 };
107 
108 class GeometryLatchingTest : public LayerUpdateTest {
109 protected:
EXPECT_INITIAL_STATE(const char * trace)110     void EXPECT_INITIAL_STATE(const char* trace) {
111         SCOPED_TRACE(trace);
112         ScreenCapture::captureScreen(&sc);
113         // We find the leading edge of the FG surface.
114         sc->expectFGColor(127, 127);
115         sc->expectBGColor(128, 128);
116     }
117 
lockAndFillFGBuffer()118     void lockAndFillFGBuffer() {
119         TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false);
120     }
121 
unlockFGBuffer()122     void unlockFGBuffer() {
123         sp<Surface> s = mFGSurfaceControl->getSurface();
124         ASSERT_EQ(NO_ERROR, s->unlockAndPost());
125         waitForPostedBuffers();
126     }
127 
completeFGResize()128     void completeFGResize() {
129         TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
130         waitForPostedBuffers();
131     }
132 
133     std::unique_ptr<ScreenCapture> sc;
134 };
135 
136 class CropLatchingTest : public GeometryLatchingTest {
137 protected:
EXPECT_CROPPED_STATE(const char * trace)138     void EXPECT_CROPPED_STATE(const char* trace) {
139         SCOPED_TRACE(trace);
140         ScreenCapture::captureScreen(&sc);
141         // The edge should be moved back one pixel by our crop.
142         sc->expectFGColor(126, 126);
143         sc->expectBGColor(127, 127);
144         sc->expectBGColor(128, 128);
145     }
146 
EXPECT_RESIZE_STATE(const char * trace)147     void EXPECT_RESIZE_STATE(const char* trace) {
148         SCOPED_TRACE(trace);
149         ScreenCapture::captureScreen(&sc);
150         // The FG is now resized too 128,128 at 64,64
151         sc->expectFGColor(64, 64);
152         sc->expectFGColor(191, 191);
153         sc->expectBGColor(192, 192);
154     }
155 };
156 
TEST_F(LayerUpdateTest,LayerWithNoBuffersResizesImmediately)157 TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
158     std::unique_ptr<ScreenCapture> sc;
159 
160     sp<SurfaceControl> childNoBuffer =
161             createSurface(mClient, "Bufferless child", 0 /* buffer width */, 0 /* buffer height */,
162                           PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
163     sp<SurfaceControl> childBuffer = createSurface(mClient, "Buffered child", 20, 20,
164                                                    PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
165     TransactionUtils::fillSurfaceRGBA8(childBuffer, 200, 200, 200);
166     SurfaceComposerClient::Transaction{}
167             .setCrop(childNoBuffer, Rect(0, 0, 10, 10))
168             .show(childNoBuffer)
169             .show(childBuffer)
170             .apply(true);
171     {
172         ScreenCapture::captureScreen(&sc);
173         sc->expectChildColor(73, 73);
174         sc->expectFGColor(74, 74);
175     }
176     SurfaceComposerClient::Transaction{}.setCrop(childNoBuffer, Rect(0, 0, 20, 20)).apply(true);
177     {
178         ScreenCapture::captureScreen(&sc);
179         sc->expectChildColor(73, 73);
180         sc->expectChildColor(74, 74);
181     }
182 }
183 
TEST_F(LayerUpdateTest,MergingTransactions)184 TEST_F(LayerUpdateTest, MergingTransactions) {
185     std::unique_ptr<ScreenCapture> sc;
186     {
187         SCOPED_TRACE("before move");
188         ScreenCapture::captureScreen(&sc);
189         sc->expectBGColor(0, 12);
190         sc->expectFGColor(75, 75);
191         sc->expectBGColor(145, 145);
192     }
193 
194     Transaction t1, t2;
195     t1.setPosition(mFGSurfaceControl, 128, 128);
196     t2.setPosition(mFGSurfaceControl, 0, 0);
197     // We expect that the position update from t2 now
198     // overwrites the position update from t1.
199     t1.merge(std::move(t2));
200     t1.apply();
201 
202     {
203         ScreenCapture::captureScreen(&sc);
204         sc->expectFGColor(1, 1);
205     }
206 }
207 
TEST_F(LayerUpdateTest,MergingTransactionFlags)208 TEST_F(LayerUpdateTest, MergingTransactionFlags) {
209     Transaction().hide(mFGSurfaceControl).apply();
210     std::unique_ptr<ScreenCapture> sc;
211     {
212         SCOPED_TRACE("before merge");
213         ScreenCapture::captureScreen(&sc);
214         sc->expectBGColor(0, 12);
215         sc->expectBGColor(75, 75);
216         sc->expectBGColor(145, 145);
217     }
218 
219     Transaction t1, t2;
220     t1.show(mFGSurfaceControl);
221     t2.setFlags(mFGSurfaceControl, 0 /* flags */, layer_state_t::eLayerSecure /* mask */);
222     t1.merge(std::move(t2));
223     t1.apply();
224 
225     {
226         SCOPED_TRACE("after merge");
227         ScreenCapture::captureScreen(&sc);
228         sc->expectFGColor(75, 75);
229     }
230 }
231 
232 class ChildLayerTest : public LayerUpdateTest {
233 protected:
SetUp()234     void SetUp() override {
235         LayerUpdateTest::SetUp();
236         mChild = createSurface(mClient, "Child surface", 10, 15, PIXEL_FORMAT_RGBA_8888, 0,
237                                mFGSurfaceControl.get());
238         TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
239         waitForPostedBuffers();
240 
241         {
242             SCOPED_TRACE("before anything");
243             mCapture = screenshot();
244             mCapture->expectChildColor(64, 64);
245         }
246     }
TearDown()247     void TearDown() override {
248         LayerUpdateTest::TearDown();
249         mChild = 0;
250     }
251 
252     sp<SurfaceControl> mChild;
253     std::unique_ptr<ScreenCapture> mCapture;
254 };
255 
TEST_F(ChildLayerTest,ChildLayerPositioning)256 TEST_F(ChildLayerTest, ChildLayerPositioning) {
257     asTransaction([&](Transaction& t) {
258         t.show(mChild);
259         t.setPosition(mChild, 10, 10);
260         t.setPosition(mFGSurfaceControl, 64, 64);
261     });
262 
263     {
264         mCapture = screenshot();
265         // Top left of foreground must now be visible
266         mCapture->expectFGColor(64, 64);
267         // But 10 pixels in we should see the child surface
268         mCapture->expectChildColor(74, 74);
269         // And 10 more pixels we should be back to the foreground surface
270         mCapture->expectFGColor(84, 84);
271     }
272 
273     asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
274 
275     {
276         mCapture = screenshot();
277         // Top left of foreground should now be at 0, 0
278         mCapture->expectFGColor(0, 0);
279         // But 10 pixels in we should see the child surface
280         mCapture->expectChildColor(10, 10);
281         // And 10 more pixels we should be back to the foreground surface
282         mCapture->expectFGColor(20, 20);
283     }
284 }
285 
TEST_F(ChildLayerTest,ChildLayerCropping)286 TEST_F(ChildLayerTest, ChildLayerCropping) {
287     asTransaction([&](Transaction& t) {
288         t.show(mChild);
289         t.setPosition(mChild, 0, 0);
290         t.setPosition(mFGSurfaceControl, 0, 0);
291         t.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5));
292     });
293 
294     {
295         mCapture = screenshot();
296         mCapture->expectChildColor(0, 0);
297         mCapture->expectChildColor(4, 4);
298         mCapture->expectBGColor(5, 5);
299     }
300 }
301 
TEST_F(ChildLayerTest,ChildLayerConstraints)302 TEST_F(ChildLayerTest, ChildLayerConstraints) {
303     asTransaction([&](Transaction& t) {
304         t.show(mChild);
305         t.setPosition(mFGSurfaceControl, 0, 0);
306         t.setPosition(mChild, 63, 63);
307     });
308 
309     {
310         mCapture = screenshot();
311         mCapture->expectFGColor(0, 0);
312         // Last pixel in foreground should now be the child.
313         mCapture->expectChildColor(63, 63);
314         // But the child should be constrained and the next pixel
315         // must be the background
316         mCapture->expectBGColor(64, 64);
317     }
318 }
319 
TEST_F(ChildLayerTest,ChildLayerScaling)320 TEST_F(ChildLayerTest, ChildLayerScaling) {
321     asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
322 
323     // Find the boundary between the parent and child
324     {
325         mCapture = screenshot();
326         mCapture->expectChildColor(9, 9);
327         mCapture->expectFGColor(10, 10);
328     }
329 
330     asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
331 
332     // The boundary should be twice as far from the origin now.
333     // The pixels from the last test should all be child now
334     {
335         mCapture = screenshot();
336         mCapture->expectChildColor(9, 9);
337         mCapture->expectChildColor(10, 10);
338         mCapture->expectChildColor(19, 19);
339         mCapture->expectFGColor(20, 20);
340     }
341 }
342 
343 // A child with a scale transform should be cropped by its parent bounds.
TEST_F(ChildLayerTest,ChildLayerScalingCroppedByParent)344 TEST_F(ChildLayerTest, ChildLayerScalingCroppedByParent) {
345     asTransaction([&](Transaction& t) {
346         t.setPosition(mFGSurfaceControl, 0, 0);
347         t.setPosition(mChild, 0, 0);
348     });
349 
350     // Find the boundary between the parent and child.
351     {
352         mCapture = screenshot();
353         mCapture->expectChildColor(0, 0);
354         mCapture->expectChildColor(9, 9);
355         mCapture->expectFGColor(10, 10);
356     }
357 
358     asTransaction([&](Transaction& t) { t.setMatrix(mChild, 10.0, 0, 0, 10.0); });
359 
360     // The child should fill its parent bounds and be cropped by it.
361     {
362         mCapture = screenshot();
363         mCapture->expectChildColor(0, 0);
364         mCapture->expectChildColor(63, 63);
365         mCapture->expectBGColor(64, 64);
366     }
367 }
368 
TEST_F(ChildLayerTest,ChildLayerAlpha)369 TEST_F(ChildLayerTest, ChildLayerAlpha) {
370     TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
371     TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
372     TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
373     waitForPostedBuffers();
374 
375     asTransaction([&](Transaction& t) {
376         t.show(mChild);
377         t.setPosition(mChild, 0, 0);
378         t.setPosition(mFGSurfaceControl, 0, 0);
379     });
380 
381     {
382         mCapture = screenshot();
383         // Unblended child color
384         mCapture->checkPixel(0, 0, 0, 254, 0);
385     }
386 
387     asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
388 
389     {
390         mCapture = screenshot();
391         // Child and BG blended. See b/175352694 for tolerance.
392         mCapture->expectColor(Rect(0, 0, 1, 1), Color{127, 127, 0, 255}, 1);
393     }
394 
395     asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
396 
397     {
398         mCapture = screenshot();
399         // Child and BG blended. See b/175352694 for tolerance.
400         mCapture->expectColor(Rect(0, 0, 1, 1), Color{95, 64, 95, 255}, 1);
401     }
402 }
403 
TEST_F(ChildLayerTest,ChildrenSurviveParentDestruction)404 TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
405     sp<SurfaceControl> mGrandChild =
406             createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
407     TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
408 
409     {
410         SCOPED_TRACE("Grandchild visible");
411         ScreenCapture::captureScreen(&mCapture);
412         mCapture->checkPixel(64, 64, 111, 111, 111);
413     }
414 
415     Transaction().reparent(mChild, nullptr).apply();
416     mChild.clear();
417 
418     {
419         SCOPED_TRACE("After destroying child");
420         ScreenCapture::captureScreen(&mCapture);
421         mCapture->expectFGColor(64, 64);
422     }
423 
424     asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl); });
425 
426     {
427         SCOPED_TRACE("After reparenting grandchild");
428         ScreenCapture::captureScreen(&mCapture);
429         mCapture->checkPixel(64, 64, 111, 111, 111);
430     }
431 }
432 
TEST_F(ChildLayerTest,ChildrenRelativeZSurvivesParentDestruction)433 TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
434     sp<SurfaceControl> mGrandChild =
435             createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
436     TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
437 
438     // draw grand child behind the foreground surface
439     asTransaction([&](Transaction& t) { t.setRelativeLayer(mGrandChild, mFGSurfaceControl, -1); });
440 
441     {
442         SCOPED_TRACE("Child visible");
443         ScreenCapture::captureScreen(&mCapture);
444         mCapture->checkPixel(64, 64, 200, 200, 200);
445     }
446 
447     asTransaction([&](Transaction& t) {
448         t.reparent(mChild, nullptr);
449         t.reparent(mGrandChild, mFGSurfaceControl);
450     });
451 
452     {
453         SCOPED_TRACE("foreground visible reparenting grandchild");
454         ScreenCapture::captureScreen(&mCapture);
455         mCapture->checkPixel(64, 64, 195, 63, 63);
456     }
457 }
458 
TEST_F(ChildLayerTest,Reparent)459 TEST_F(ChildLayerTest, Reparent) {
460     asTransaction([&](Transaction& t) {
461         t.show(mChild);
462         t.setPosition(mChild, 10, 10);
463         t.setPosition(mFGSurfaceControl, 64, 64);
464     });
465 
466     {
467         mCapture = screenshot();
468         // Top left of foreground must now be visible
469         mCapture->expectFGColor(64, 64);
470         // But 10 pixels in we should see the child surface
471         mCapture->expectChildColor(74, 74);
472         // And 10 more pixels we should be back to the foreground surface
473         mCapture->expectFGColor(84, 84);
474     }
475 
476     asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl); });
477 
478     {
479         mCapture = screenshot();
480         mCapture->expectFGColor(64, 64);
481         // In reparenting we should have exposed the entire foreground surface.
482         mCapture->expectFGColor(74, 74);
483         // And the child layer should now begin at 10, 10 (since the BG
484         // layer is at (0, 0)).
485         mCapture->expectBGColor(9, 9);
486         mCapture->expectChildColor(10, 10);
487     }
488 }
489 
TEST_F(ChildLayerTest,ReparentToNoParent)490 TEST_F(ChildLayerTest, ReparentToNoParent) {
491     asTransaction([&](Transaction& t) {
492         t.show(mChild);
493         t.setPosition(mChild, 10, 10);
494         t.setPosition(mFGSurfaceControl, 64, 64);
495     });
496 
497     {
498         mCapture = screenshot();
499         // Top left of foreground must now be visible
500         mCapture->expectFGColor(64, 64);
501         // But 10 pixels in we should see the child surface
502         mCapture->expectChildColor(74, 74);
503         // And 10 more pixels we should be back to the foreground surface
504         mCapture->expectFGColor(84, 84);
505     }
506     asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
507     {
508         mCapture = screenshot();
509         // The surface should now be offscreen.
510         mCapture->expectFGColor(64, 64);
511         mCapture->expectFGColor(74, 74);
512         mCapture->expectFGColor(84, 84);
513     }
514 }
515 
TEST_F(ChildLayerTest,ReparentFromNoParent)516 TEST_F(ChildLayerTest, ReparentFromNoParent) {
517     sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
518     ASSERT_TRUE(newSurface != nullptr);
519     ASSERT_TRUE(newSurface->isValid());
520 
521     TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
522     asTransaction([&](Transaction& t) {
523         t.hide(mChild);
524         t.show(newSurface);
525         t.setPosition(newSurface, 10, 10);
526         t.setLayer(newSurface, INT32_MAX - 2);
527         t.setPosition(mFGSurfaceControl, 64, 64);
528     });
529 
530     {
531         mCapture = screenshot();
532         // Top left of foreground must now be visible
533         mCapture->expectFGColor(64, 64);
534         // At 10, 10 we should see the new surface
535         mCapture->checkPixel(10, 10, 63, 195, 63);
536     }
537 
538     asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl); });
539 
540     {
541         mCapture = screenshot();
542         // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
543         // mFGSurface, putting it at 74, 74.
544         mCapture->expectFGColor(64, 64);
545         mCapture->checkPixel(74, 74, 63, 195, 63);
546         mCapture->expectFGColor(84, 84);
547     }
548 }
549 
TEST_F(ChildLayerTest,NestedChildren)550 TEST_F(ChildLayerTest, NestedChildren) {
551     sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
552                                                   PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
553     TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
554 
555     {
556         mCapture = screenshot();
557         // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
558         // which begins at 64, 64
559         mCapture->checkPixel(64, 64, 50, 50, 50);
560     }
561 }
562 
TEST_F(ChildLayerTest,ChildLayerRelativeLayer)563 TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
564     sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
565     TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
566 
567     Transaction t;
568     t.setLayer(relative, INT32_MAX)
569             .setRelativeLayer(mChild, relative, 1)
570             .setPosition(mFGSurfaceControl, 0, 0)
571             .apply(true);
572 
573     // We expect that the child should have been elevated above our
574     // INT_MAX layer even though it's not a child of it.
575     {
576         mCapture = screenshot();
577         mCapture->expectChildColor(0, 0);
578         mCapture->expectChildColor(9, 9);
579         mCapture->checkPixel(10, 10, 255, 255, 255);
580     }
581 }
582 
583 class BoundlessLayerTest : public LayerUpdateTest {
584 protected:
585     std::unique_ptr<ScreenCapture> mCapture;
586 };
587 
588 // Verify setting a size on a buffer layer has no effect.
TEST_F(BoundlessLayerTest,BufferLayerIgnoresSize)589 TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
590     sp<SurfaceControl> bufferLayer =
591             createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
592                           mFGSurfaceControl.get());
593     ASSERT_TRUE(bufferLayer->isValid());
594     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
595     asTransaction([&](Transaction& t) { t.show(bufferLayer); });
596     {
597         mCapture = screenshot();
598         // Top left of background must now be visible
599         mCapture->expectBGColor(0, 0);
600         // Foreground Surface bounds must be color layer
601         mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
602         // Buffer layer should not extend past buffer bounds
603         mCapture->expectFGColor(95, 95);
604     }
605 }
606 
607 // Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
608 // which will crop the color layer.
TEST_F(BoundlessLayerTest,BoundlessColorLayerFillsParentBufferBounds)609 TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
610     sp<SurfaceControl> colorLayer =
611             createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
612                           ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
613     ASSERT_TRUE(colorLayer->isValid());
614     asTransaction([&](Transaction& t) {
615         t.setColor(colorLayer, half3{0, 0, 0});
616         t.show(colorLayer);
617     });
618     {
619         mCapture = screenshot();
620         // Top left of background must now be visible
621         mCapture->expectBGColor(0, 0);
622         // Foreground Surface bounds must be color layer
623         mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
624         // Color layer should not extend past foreground bounds
625         mCapture->expectBGColor(129, 129);
626     }
627 }
628 
629 // Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
630 // a crop which will be used to crop the color layer.
TEST_F(BoundlessLayerTest,BoundlessColorLayerFillsParentCropBounds)631 TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
632     sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
633                                                  0 /* flags */, mFGSurfaceControl.get());
634     ASSERT_TRUE(cropLayer->isValid());
635     sp<SurfaceControl> colorLayer =
636             createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
637                           ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
638     ASSERT_TRUE(colorLayer->isValid());
639     asTransaction([&](Transaction& t) {
640         t.setCrop(cropLayer, Rect(5, 5, 10, 10));
641         t.setColor(colorLayer, half3{0, 0, 0});
642         t.show(cropLayer);
643         t.show(colorLayer);
644     });
645     {
646         mCapture = screenshot();
647         // Top left of background must now be visible
648         mCapture->expectBGColor(0, 0);
649         // Top left of foreground must now be visible
650         mCapture->expectFGColor(64, 64);
651         // 5 pixels from the foreground we should see the child surface
652         mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
653         // 10 pixels from the foreground we should be back to the foreground surface
654         mCapture->expectFGColor(74, 74);
655     }
656 }
657 
658 // Verify for boundless layer with no children, their transforms have no effect.
TEST_F(BoundlessLayerTest,BoundlessColorLayerTransformHasNoEffect)659 TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
660     sp<SurfaceControl> colorLayer =
661             createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
662                           ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
663     ASSERT_TRUE(colorLayer->isValid());
664     asTransaction([&](Transaction& t) {
665         t.setPosition(colorLayer, 320, 320);
666         t.setMatrix(colorLayer, 2, 0, 0, 2);
667         t.setColor(colorLayer, half3{0, 0, 0});
668         t.show(colorLayer);
669     });
670     {
671         mCapture = screenshot();
672         // Top left of background must now be visible
673         mCapture->expectBGColor(0, 0);
674         // Foreground Surface bounds must be color layer
675         mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
676         // Color layer should not extend past foreground bounds
677         mCapture->expectBGColor(129, 129);
678     }
679 }
680 
681 // Verify for boundless layer with children, their transforms have an effect.
TEST_F(BoundlessLayerTest,IntermediateBoundlessLayerCanSetTransform)682 TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
683     sp<SurfaceControl> boundlessLayerRightShift =
684             createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
685                           0 /* flags */, mFGSurfaceControl.get());
686     ASSERT_TRUE(boundlessLayerRightShift->isValid());
687     sp<SurfaceControl> boundlessLayerDownShift =
688             createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
689                           0 /* flags */, boundlessLayerRightShift.get());
690     ASSERT_TRUE(boundlessLayerDownShift->isValid());
691     sp<SurfaceControl> colorLayer =
692             createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
693                           ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
694     ASSERT_TRUE(colorLayer->isValid());
695     asTransaction([&](Transaction& t) {
696         t.setPosition(boundlessLayerRightShift, 32, 0);
697         t.show(boundlessLayerRightShift);
698         t.setPosition(boundlessLayerDownShift, 0, 32);
699         t.show(boundlessLayerDownShift);
700         t.setCrop(colorLayer, Rect(0, 0, 64, 64));
701         t.setColor(colorLayer, half3{0, 0, 0});
702         t.show(colorLayer);
703     });
704     {
705         mCapture = screenshot();
706         // Top left of background must now be visible
707         mCapture->expectBGColor(0, 0);
708         // Top left of foreground must now be visible
709         mCapture->expectFGColor(64, 64);
710         // Foreground Surface bounds must be color layer
711         mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
712         // Color layer should not extend past foreground bounds
713         mCapture->expectBGColor(129, 129);
714     }
715 }
716 
717 // Verify child layers do not get clipped if they temporarily move into the negative
718 // coordinate space as the result of an intermediate transformation.
TEST_F(BoundlessLayerTest,IntermediateBoundlessLayerDoNotCrop)719 TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
720     sp<SurfaceControl> boundlessLayer =
721             mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
722                                    0 /* flags */, mFGSurfaceControl->getHandle());
723     ASSERT_TRUE(boundlessLayer != nullptr);
724     ASSERT_TRUE(boundlessLayer->isValid());
725     sp<SurfaceControl> colorLayer =
726             mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
727                                    ISurfaceComposerClient::eFXSurfaceEffect,
728                                    boundlessLayer->getHandle());
729     ASSERT_TRUE(colorLayer != nullptr);
730     ASSERT_TRUE(colorLayer->isValid());
731     asTransaction([&](Transaction& t) {
732         // shift child layer off bounds. If this layer was not boundless, we will
733         // expect the child layer to be cropped.
734         t.setPosition(boundlessLayer, 32, 32);
735         t.show(boundlessLayer);
736         t.setCrop(colorLayer, Rect(0, 0, 64, 64));
737         // undo shift by parent
738         t.setPosition(colorLayer, -32, -32);
739         t.setColor(colorLayer, half3{0, 0, 0});
740         t.show(colorLayer);
741     });
742     {
743         mCapture = screenshot();
744         // Top left of background must now be visible
745         mCapture->expectBGColor(0, 0);
746         // Foreground Surface bounds must be color layer
747         mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
748         // Color layer should not extend past foreground bounds
749         mCapture->expectBGColor(129, 129);
750     }
751 }
752 
753 // Verify for boundless root layers with children, their transforms have an effect.
TEST_F(BoundlessLayerTest,RootBoundlessLayerCanSetTransform)754 TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
755     sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
756                                                           PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
757     ASSERT_TRUE(rootBoundlessLayer->isValid());
758     sp<SurfaceControl> colorLayer =
759             createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
760                           ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
761 
762     ASSERT_TRUE(colorLayer->isValid());
763     asTransaction([&](Transaction& t) {
764         t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
765         t.setPosition(rootBoundlessLayer, 32, 32);
766         t.show(rootBoundlessLayer);
767         t.setCrop(colorLayer, Rect(0, 0, 64, 64));
768         t.setColor(colorLayer, half3{0, 0, 0});
769         t.show(colorLayer);
770         t.hide(mFGSurfaceControl);
771     });
772     {
773         mCapture = screenshot();
774         // Top left of background must now be visible
775         mCapture->expectBGColor(0, 0);
776         // Top left of foreground must now be visible
777         mCapture->expectBGColor(31, 31);
778         // Foreground Surface bounds must be color layer
779         mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
780         // Color layer should not extend past foreground bounds
781         mCapture->expectBGColor(97, 97);
782     }
783 }
784 
785 } // namespace android
786 
787 // TODO(b/129481165): remove the #pragma below and fix conversion issues
788 #pragma clang diagnostic pop // ignored "-Wconversion"
789