1 /*
2 * Copyright (C) 2017 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 // #define LOG_NDEBUG 0
18 #undef LOG_TAG
19 #define LOG_TAG "FakeHwcTest"
20
21 #include "FakeComposerClient.h"
22 #include "FakeComposerService.h"
23 #include "FakeComposerUtils.h"
24
25 #include <gui/DisplayEventReceiver.h>
26 #include <gui/ISurfaceComposer.h>
27 #include <gui/LayerDebugInfo.h>
28 #include <gui/LayerState.h>
29 #include <gui/Surface.h>
30 #include <gui/SurfaceComposerClient.h>
31
32 #include <android/hidl/manager/1.0/IServiceManager.h>
33 #include <android/looper.h>
34 #include <android/native_window.h>
35 #include <binder/ProcessState.h>
36 #include <hwbinder/ProcessState.h>
37 #include <log/log.h>
38 #include <private/gui/ComposerService.h>
39 #include <ui/DisplayInfo.h>
40 #include <utils/Looper.h>
41
42 #include <gmock/gmock.h>
43 #include <gtest/gtest.h>
44
45 #include <limits>
46
47 using namespace std::chrono_literals;
48
49 using namespace android;
50 using namespace android::hardware;
51
52 using namespace sftest;
53
54 namespace {
55
56 // Mock test helpers
57 using ::testing::_;
58 using ::testing::DoAll;
59 using ::testing::Invoke;
60 using ::testing::Return;
61 using ::testing::SetArgPointee;
62
63 using Transaction = SurfaceComposerClient::Transaction;
64
65 ///////////////////////////////////////////////
66
67 struct TestColor {
68 public:
69 uint8_t r;
70 uint8_t g;
71 uint8_t b;
72 uint8_t a;
73 };
74
75 constexpr static TestColor RED = {195, 63, 63, 255};
76 constexpr static TestColor LIGHT_RED = {255, 177, 177, 255};
77 constexpr static TestColor GREEN = {63, 195, 63, 255};
78 constexpr static TestColor BLUE = {63, 63, 195, 255};
79 constexpr static TestColor DARK_GRAY = {63, 63, 63, 255};
80 constexpr static TestColor LIGHT_GRAY = {200, 200, 200, 255};
81
82 // Fill an RGBA_8888 formatted surface with a single color.
fillSurfaceRGBA8(const sp<SurfaceControl> & sc,const TestColor & color,bool unlock=true)83 static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, const TestColor& color,
84 bool unlock = true) {
85 ANativeWindow_Buffer outBuffer;
86 sp<Surface> s = sc->getSurface();
87 ASSERT_TRUE(s != nullptr);
88 ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr));
89 uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
90 for (int y = 0; y < outBuffer.height; y++) {
91 for (int x = 0; x < outBuffer.width; x++) {
92 uint8_t* pixel = img + (4 * (y * outBuffer.stride + x));
93 pixel[0] = color.r;
94 pixel[1] = color.g;
95 pixel[2] = color.b;
96 pixel[3] = color.a;
97 }
98 }
99 if (unlock) {
100 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
101 }
102 }
103
makeSimpleRect(int left,int top,int right,int bottom)104 inline RenderState makeSimpleRect(int left, int top, int right, int bottom) {
105 RenderState res;
106 res.mDisplayFrame = hwc_rect_t{left, top, right, bottom};
107 res.mPlaneAlpha = 1.0f;
108 res.mSwapCount = 0;
109 res.mSourceCrop = hwc_frect_t{0.f, 0.f, static_cast<float>(right - left),
110 static_cast<float>(bottom - top)};
111 return res;
112 }
113
makeSimpleRect(unsigned int left,unsigned int top,unsigned int right,unsigned int bottom)114 inline RenderState makeSimpleRect(unsigned int left, unsigned int top, unsigned int right,
115 unsigned int bottom) {
116 EXPECT_LE(left, static_cast<unsigned int>(INT_MAX));
117 EXPECT_LE(top, static_cast<unsigned int>(INT_MAX));
118 EXPECT_LE(right, static_cast<unsigned int>(INT_MAX));
119 EXPECT_LE(bottom, static_cast<unsigned int>(INT_MAX));
120 return makeSimpleRect(static_cast<int>(left), static_cast<int>(top), static_cast<int>(right),
121 static_cast<int>(bottom));
122 }
123
124 ////////////////////////////////////////////////
125
126 class DisplayTest : public ::testing::Test {
127 public:
128 class MockComposerClient : public FakeComposerClient {
129 public:
130 MOCK_METHOD2(getDisplayType, Error(Display display, ComposerClient::DisplayType* outType));
131 MOCK_METHOD4(getDisplayAttribute,
132 Error(Display display, Config config, IComposerClient::Attribute attribute,
133 int32_t* outValue));
134
135 // Re-routing to basic fake implementation
getDisplayAttributeFake(Display display,Config config,IComposerClient::Attribute attribute,int32_t * outValue)136 Error getDisplayAttributeFake(Display display, Config config,
137 IComposerClient::Attribute attribute, int32_t* outValue) {
138 return FakeComposerClient::getDisplayAttribute(display, config, attribute, outValue);
139 }
140 };
141
142 protected:
143 static int processDisplayEvents(int fd, int events, void* data);
144
145 void SetUp() override;
146 void TearDown() override;
147
148 void waitForDisplayTransaction();
149 bool waitForHotplugEvent(PhysicalDisplayId displayId, bool connected);
150
151 sp<IComposer> mFakeService;
152 sp<SurfaceComposerClient> mComposerClient;
153
154 MockComposerClient* mMockComposer;
155
156 std::unique_ptr<DisplayEventReceiver> mReceiver;
157 sp<Looper> mLooper;;
158 std::deque<DisplayEventReceiver::Event> mReceivedDisplayEvents;
159 };
160
SetUp()161 void DisplayTest::SetUp() {
162 // TODO: The mMockComposer should be a unique_ptr, but it needs to
163 // outlive the test class. Currently ComposerClient only dies
164 // when the service is replaced. The Mock deletes itself when
165 // removeClient is called on it, which is ugly. This can be
166 // changed if HIDL ServiceManager allows removing services or
167 // ComposerClient starts taking the ownership of the contained
168 // implementation class. Moving the fake class to the HWC2
169 // interface instead of the current Composer interface might also
170 // change the situation.
171 mMockComposer = new MockComposerClient;
172 sp<ComposerClient> client = new ComposerClient(mMockComposer);
173 mFakeService = new FakeComposerService(client);
174 (void)mFakeService->registerAsService("mock");
175
176 android::hardware::ProcessState::self()->startThreadPool();
177 android::ProcessState::self()->startThreadPool();
178
179 EXPECT_CALL(*mMockComposer, getDisplayType(PRIMARY_DISPLAY, _))
180 .WillOnce(DoAll(SetArgPointee<1>(IComposerClient::DisplayType::PHYSICAL),
181 Return(Error::NONE)));
182 // Primary display will be queried twice for all 5 attributes. One
183 // set of queries comes from the SurfaceFlinger proper an the
184 // other set from the VR composer.
185 // TODO: Is VR composer always present? Change to atLeast(5)?
186 EXPECT_CALL(*mMockComposer, getDisplayAttribute(PRIMARY_DISPLAY, 1, _, _))
187 .Times(2 * 5)
188 .WillRepeatedly(Invoke(mMockComposer, &MockComposerClient::getDisplayAttributeFake));
189
190 startSurfaceFlinger();
191
192 // Fake composer wants to enable VSync injection
193 mMockComposer->onSurfaceFlingerStart();
194
195 mComposerClient = new SurfaceComposerClient;
196 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
197
198 mReceiver.reset(new DisplayEventReceiver());
199 mLooper = new Looper(false);
200 mLooper->addFd(mReceiver->getFd(), 0, ALOOPER_EVENT_INPUT, processDisplayEvents, this);
201 }
202
TearDown()203 void DisplayTest::TearDown() {
204 mLooper = nullptr;
205 mReceiver = nullptr;
206
207 mComposerClient->dispose();
208 mComposerClient = nullptr;
209
210 // Fake composer needs to release SurfaceComposerClient before the stop.
211 mMockComposer->onSurfaceFlingerStop();
212 stopSurfaceFlinger();
213
214 mFakeService = nullptr;
215 // TODO: Currently deleted in FakeComposerClient::removeClient(). Devise better lifetime
216 // management.
217 mMockComposer = nullptr;
218 }
219
220
processDisplayEvents(int,int,void * data)221 int DisplayTest::processDisplayEvents(int /*fd*/, int /*events*/, void* data) {
222 auto self = static_cast<DisplayTest*>(data);
223
224 ssize_t n;
225 DisplayEventReceiver::Event buffer[1];
226
227 while ((n = self->mReceiver->getEvents(buffer, 1)) > 0) {
228 for (int i=0 ; i<n ; i++) {
229 self->mReceivedDisplayEvents.push_back(buffer[i]);
230 }
231 }
232 ALOGD_IF(n < 0, "Error reading events (%s)\n", strerror(-n));
233 return 1;
234 }
235
waitForDisplayTransaction()236 void DisplayTest::waitForDisplayTransaction() {
237 // Both a refresh and a vsync event are needed to apply pending display
238 // transactions.
239 mMockComposer->refreshDisplay(EXTERNAL_DISPLAY);
240 mMockComposer->runVSyncAndWait();
241
242 // Extra vsync and wait to avoid a 10% flake due to a race.
243 mMockComposer->runVSyncAndWait();
244 }
245
waitForHotplugEvent(PhysicalDisplayId displayId,bool connected)246 bool DisplayTest::waitForHotplugEvent(PhysicalDisplayId displayId, bool connected) {
247 int waitCount = 20;
248 while (waitCount--) {
249 while (!mReceivedDisplayEvents.empty()) {
250 auto event = mReceivedDisplayEvents.front();
251 mReceivedDisplayEvents.pop_front();
252
253 ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG,
254 "event hotplug: displayId %" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT
255 ", connected %d\t",
256 event.header.displayId, event.hotplug.connected);
257
258 if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG &&
259 event.header.displayId == displayId && event.hotplug.connected == connected) {
260 return true;
261 }
262 }
263
264 mLooper->pollOnce(1);
265 }
266
267 return false;
268 }
269
TEST_F(DisplayTest,Hotplug)270 TEST_F(DisplayTest, Hotplug) {
271 ALOGD("DisplayTest::Hotplug");
272
273 EXPECT_CALL(*mMockComposer, getDisplayType(EXTERNAL_DISPLAY, _))
274 .Times(2)
275 .WillRepeatedly(DoAll(SetArgPointee<1>(IComposerClient::DisplayType::PHYSICAL),
276 Return(Error::NONE)));
277 // The attribute queries will get done twice. This is for defaults
278 EXPECT_CALL(*mMockComposer, getDisplayAttribute(EXTERNAL_DISPLAY, 1, _, _))
279 .Times(2 * 3)
280 .WillRepeatedly(Invoke(mMockComposer, &MockComposerClient::getDisplayAttributeFake));
281 // ... and then special handling for dimensions. Specifying these
282 // rules later means that gmock will try them first, i.e.,
283 // ordering of width/height vs. the default implementation for
284 // other queries is significant.
285 EXPECT_CALL(*mMockComposer,
286 getDisplayAttribute(EXTERNAL_DISPLAY, 1, IComposerClient::Attribute::WIDTH, _))
287 .Times(2)
288 .WillRepeatedly(DoAll(SetArgPointee<3>(400), Return(Error::NONE)));
289
290 EXPECT_CALL(*mMockComposer,
291 getDisplayAttribute(EXTERNAL_DISPLAY, 1, IComposerClient::Attribute::HEIGHT, _))
292 .Times(2)
293 .WillRepeatedly(DoAll(SetArgPointee<3>(200), Return(Error::NONE)));
294
295 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::CONNECTED);
296
297 waitForDisplayTransaction();
298
299 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
300
301 {
302 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(EXTERNAL_DISPLAY);
303 ASSERT_FALSE(display == nullptr);
304
305 DisplayInfo info;
306 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info));
307 ASSERT_EQ(400u, info.w);
308 ASSERT_EQ(200u, info.h);
309
310 auto surfaceControl =
311 mComposerClient->createSurface(String8("Display Test Surface Foo"), info.w, info.h,
312 PIXEL_FORMAT_RGBA_8888, 0);
313 ASSERT_TRUE(surfaceControl != nullptr);
314 ASSERT_TRUE(surfaceControl->isValid());
315 fillSurfaceRGBA8(surfaceControl, BLUE);
316
317 {
318 TransactionScope ts(*mMockComposer);
319 ts.setDisplayLayerStack(display, 0);
320
321 ts.setLayer(surfaceControl, INT32_MAX - 2)
322 .show(surfaceControl);
323 }
324 }
325
326 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::DISCONNECTED);
327
328 mMockComposer->clearFrames();
329
330 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::CONNECTED);
331
332 waitForDisplayTransaction();
333
334 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
335 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
336
337 {
338 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(EXTERNAL_DISPLAY);
339 ASSERT_FALSE(display == nullptr);
340
341 DisplayInfo info;
342 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info));
343 ASSERT_EQ(400u, info.w);
344 ASSERT_EQ(200u, info.h);
345
346 auto surfaceControl =
347 mComposerClient->createSurface(String8("Display Test Surface Bar"), info.w, info.h,
348 PIXEL_FORMAT_RGBA_8888, 0);
349 ASSERT_TRUE(surfaceControl != nullptr);
350 ASSERT_TRUE(surfaceControl->isValid());
351 fillSurfaceRGBA8(surfaceControl, BLUE);
352
353 {
354 TransactionScope ts(*mMockComposer);
355 ts.setDisplayLayerStack(display, 0);
356
357 ts.setLayer(surfaceControl, INT32_MAX - 2)
358 .show(surfaceControl);
359 }
360 }
361 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::DISCONNECTED);
362 }
363
TEST_F(DisplayTest,HotplugPrimaryDisplay)364 TEST_F(DisplayTest, HotplugPrimaryDisplay) {
365 ALOGD("DisplayTest::HotplugPrimaryDisplay");
366
367 mMockComposer->hotplugDisplay(PRIMARY_DISPLAY, IComposerCallback::Connection::DISCONNECTED);
368
369 waitForDisplayTransaction();
370
371 EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, false));
372
373 {
374 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY);
375 EXPECT_FALSE(display == nullptr);
376
377 DisplayInfo info;
378 auto result = SurfaceComposerClient::getDisplayInfo(display, &info);
379 EXPECT_NE(NO_ERROR, result);
380 }
381
382 mMockComposer->clearFrames();
383
384 EXPECT_CALL(*mMockComposer, getDisplayType(PRIMARY_DISPLAY, _))
385 .Times(2)
386 .WillRepeatedly(DoAll(SetArgPointee<1>(IComposerClient::DisplayType::PHYSICAL),
387 Return(Error::NONE)));
388 // The attribute queries will get done twice. This is for defaults
389 EXPECT_CALL(*mMockComposer, getDisplayAttribute(PRIMARY_DISPLAY, 1, _, _))
390 .Times(2 * 3)
391 .WillRepeatedly(Invoke(mMockComposer, &MockComposerClient::getDisplayAttributeFake));
392 // ... and then special handling for dimensions. Specifying these
393 // rules later means that gmock will try them first, i.e.,
394 // ordering of width/height vs. the default implementation for
395 // other queries is significant.
396 EXPECT_CALL(*mMockComposer,
397 getDisplayAttribute(PRIMARY_DISPLAY, 1, IComposerClient::Attribute::WIDTH, _))
398 .Times(2)
399 .WillRepeatedly(DoAll(SetArgPointee<3>(400), Return(Error::NONE)));
400
401 EXPECT_CALL(*mMockComposer,
402 getDisplayAttribute(PRIMARY_DISPLAY, 1, IComposerClient::Attribute::HEIGHT, _))
403 .Times(2)
404 .WillRepeatedly(DoAll(SetArgPointee<3>(200), Return(Error::NONE)));
405
406 mMockComposer->hotplugDisplay(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED);
407
408 waitForDisplayTransaction();
409
410 EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, true));
411
412 {
413 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY);
414 EXPECT_FALSE(display == nullptr);
415
416 DisplayInfo info;
417 auto result = SurfaceComposerClient::getDisplayInfo(display, &info);
418 EXPECT_EQ(NO_ERROR, result);
419 ASSERT_EQ(400u, info.w);
420 ASSERT_EQ(200u, info.h);
421 }
422 }
423
424 ////////////////////////////////////////////////
425
426 class TransactionTest : public ::testing::Test {
427 protected:
428 // Layer array indexing constants.
429 constexpr static int BG_LAYER = 0;
430 constexpr static int FG_LAYER = 1;
431
432 static void SetUpTestCase();
433 static void TearDownTestCase();
434
435 void SetUp() override;
436 void TearDown() override;
437
438 sp<SurfaceComposerClient> mComposerClient;
439 sp<SurfaceControl> mBGSurfaceControl;
440 sp<SurfaceControl> mFGSurfaceControl;
441 std::vector<RenderState> mBaseFrame;
442 uint32_t mDisplayWidth;
443 uint32_t mDisplayHeight;
444
445 static FakeComposerClient* sFakeComposer;
446 };
447
448 FakeComposerClient* TransactionTest::sFakeComposer;
449
SetUpTestCase()450 void TransactionTest::SetUpTestCase() {
451 // TODO: See TODO comment at DisplayTest::SetUp for background on
452 // the lifetime of the FakeComposerClient.
453 sFakeComposer = new FakeComposerClient;
454 sp<ComposerClient> client = new ComposerClient(sFakeComposer);
455 sp<IComposer> fakeService = new FakeComposerService(client);
456 (void)fakeService->registerAsService("mock");
457
458 android::hardware::ProcessState::self()->startThreadPool();
459 android::ProcessState::self()->startThreadPool();
460
461 startSurfaceFlinger();
462
463 // Fake composer wants to enable VSync injection
464 sFakeComposer->onSurfaceFlingerStart();
465 }
466
TearDownTestCase()467 void TransactionTest::TearDownTestCase() {
468 // Fake composer needs to release SurfaceComposerClient before the stop.
469 sFakeComposer->onSurfaceFlingerStop();
470 stopSurfaceFlinger();
471 // TODO: This is deleted when the ComposerClient calls
472 // removeClient. Devise better lifetime control.
473 sFakeComposer = nullptr;
474 }
475
SetUp()476 void TransactionTest::SetUp() {
477 ALOGI("TransactionTest::SetUp");
478 mComposerClient = new SurfaceComposerClient;
479 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
480
481 ALOGI("TransactionTest::SetUp - display");
482 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY);
483 ASSERT_FALSE(display == nullptr);
484
485 DisplayInfo info;
486 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info));
487
488 mDisplayWidth = info.w;
489 mDisplayHeight = info.h;
490
491 // Background surface
492 mBGSurfaceControl = mComposerClient->createSurface(String8("BG Test Surface"), mDisplayWidth,
493 mDisplayHeight, PIXEL_FORMAT_RGBA_8888, 0);
494 ASSERT_TRUE(mBGSurfaceControl != nullptr);
495 ASSERT_TRUE(mBGSurfaceControl->isValid());
496 fillSurfaceRGBA8(mBGSurfaceControl, BLUE);
497
498 // Foreground surface
499 mFGSurfaceControl = mComposerClient->createSurface(String8("FG Test Surface"), 64, 64,
500 PIXEL_FORMAT_RGBA_8888, 0);
501 ASSERT_TRUE(mFGSurfaceControl != nullptr);
502 ASSERT_TRUE(mFGSurfaceControl->isValid());
503
504 fillSurfaceRGBA8(mFGSurfaceControl, RED);
505
506 Transaction t;
507 t.setDisplayLayerStack(display, 0);
508
509 t.setLayer(mBGSurfaceControl, INT32_MAX - 2);
510 t.show(mBGSurfaceControl);
511
512 t.setLayer(mFGSurfaceControl, INT32_MAX - 1);
513 t.setPosition(mFGSurfaceControl, 64, 64);
514 t.show(mFGSurfaceControl);
515
516 // Synchronous transaction will stop this thread, so we set up a
517 // delayed, off-thread vsync request before closing the
518 // transaction. In the test code this is usually done with
519 // TransactionScope. Leaving here in the 'vanilla' form for
520 // reference.
521 ASSERT_EQ(0, sFakeComposer->getFrameCount());
522 sFakeComposer->runVSyncAfter(1ms);
523 t.apply();
524 sFakeComposer->waitUntilFrame(1);
525
526 // Reference data. This is what the HWC should see.
527 static_assert(BG_LAYER == 0 && FG_LAYER == 1, "Unexpected enum values for array indexing");
528 mBaseFrame.push_back(makeSimpleRect(0u, 0u, mDisplayWidth, mDisplayHeight));
529 mBaseFrame[BG_LAYER].mSwapCount = 1;
530 mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64));
531 mBaseFrame[FG_LAYER].mSwapCount = 1;
532
533 auto frame = sFakeComposer->getFrameRects(0);
534 ASSERT_TRUE(framesAreSame(mBaseFrame, frame));
535 }
536
TearDown()537 void TransactionTest::TearDown() {
538 ALOGD("TransactionTest::TearDown");
539
540 mComposerClient->dispose();
541 mBGSurfaceControl = 0;
542 mFGSurfaceControl = 0;
543 mComposerClient = 0;
544
545 sFakeComposer->runVSyncAndWait();
546 mBaseFrame.clear();
547 sFakeComposer->clearFrames();
548 ASSERT_EQ(0, sFakeComposer->getFrameCount());
549
550 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
551 std::vector<LayerDebugInfo> layers;
552 status_t result = sf->getLayerDebugInfo(&layers);
553 if (result != NO_ERROR) {
554 ALOGE("Failed to get layers %s %d", strerror(-result), result);
555 } else {
556 // If this fails, the test being torn down leaked layers.
557 EXPECT_EQ(0u, layers.size());
558 if (layers.size() > 0) {
559 for (auto layer = layers.begin(); layer != layers.end(); ++layer) {
560 std::cout << to_string(*layer).c_str();
561 }
562 // To ensure the next test has clean slate, will run the class
563 // tear down and setup here.
564 TearDownTestCase();
565 SetUpTestCase();
566 }
567 }
568 ALOGD("TransactionTest::TearDown - complete");
569 }
570
TEST_F(TransactionTest,LayerMove)571 TEST_F(TransactionTest, LayerMove) {
572 ALOGD("TransactionTest::LayerMove");
573
574 // The scope opens and closes a global transaction and, at the
575 // same time, makes sure the SurfaceFlinger progresses one frame
576 // after the transaction closes. The results of the transaction
577 // should be available in the latest frame stored by the fake
578 // composer.
579 {
580 TransactionScope ts(*sFakeComposer);
581 ts.setPosition(mFGSurfaceControl, 128, 128);
582 // NOTE: No changes yet, so vsync will do nothing, HWC does not get any calls.
583 // (How to verify that? Throw in vsync and wait a 2x frame time? Separate test?)
584 //
585 // sFakeComposer->runVSyncAndWait();
586 }
587
588 fillSurfaceRGBA8(mFGSurfaceControl, GREEN);
589 sFakeComposer->runVSyncAndWait();
590
591 ASSERT_EQ(3, sFakeComposer->getFrameCount()); // Make sure the waits didn't time out and there's
592 // no extra frames.
593
594 // NOTE: Frame 0 is produced in the SetUp.
595 auto frame1Ref = mBaseFrame;
596 frame1Ref[FG_LAYER].mDisplayFrame =
597 hwc_rect_t{128, 128, 128 + 64, 128 + 64}; // Top-most layer moves.
598 EXPECT_TRUE(framesAreSame(frame1Ref, sFakeComposer->getFrameRects(1)));
599
600 auto frame2Ref = frame1Ref;
601 frame2Ref[FG_LAYER].mSwapCount++;
602 EXPECT_TRUE(framesAreSame(frame2Ref, sFakeComposer->getFrameRects(2)));
603 }
604
TEST_F(TransactionTest,LayerResize)605 TEST_F(TransactionTest, LayerResize) {
606 ALOGD("TransactionTest::LayerResize");
607 {
608 TransactionScope ts(*sFakeComposer);
609 ts.setSize(mFGSurfaceControl, 128, 128);
610 }
611
612 fillSurfaceRGBA8(mFGSurfaceControl, GREEN);
613 sFakeComposer->runVSyncAndWait();
614
615 ASSERT_EQ(3, sFakeComposer->getFrameCount()); // Make sure the waits didn't time out and there's
616 // no extra frames.
617
618 auto frame1Ref = mBaseFrame;
619 // NOTE: The resize should not be visible for frame 1 as there's no buffer with new size posted.
620 EXPECT_TRUE(framesAreSame(frame1Ref, sFakeComposer->getFrameRects(1)));
621
622 auto frame2Ref = frame1Ref;
623 frame2Ref[FG_LAYER].mSwapCount++;
624 frame2Ref[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 128, 64 + 128};
625 frame2Ref[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 128.f, 128.f};
626 EXPECT_TRUE(framesAreSame(frame2Ref, sFakeComposer->getFrameRects(2)));
627 }
628
TEST_F(TransactionTest,LayerCrop)629 TEST_F(TransactionTest, LayerCrop) {
630 // TODO: Add scaling to confirm that crop happens in buffer space?
631 {
632 TransactionScope ts(*sFakeComposer);
633 Rect cropRect(16, 16, 32, 32);
634 ts.setCrop_legacy(mFGSurfaceControl, cropRect);
635 }
636 ASSERT_EQ(2, sFakeComposer->getFrameCount());
637
638 auto referenceFrame = mBaseFrame;
639 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{16.f, 16.f, 32.f, 32.f};
640 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64 + 16, 64 + 16, 64 + 32, 64 + 32};
641 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
642 }
643
TEST_F(TransactionTest,LayerSetLayer)644 TEST_F(TransactionTest, LayerSetLayer) {
645 {
646 TransactionScope ts(*sFakeComposer);
647 ts.setLayer(mFGSurfaceControl, INT_MAX - 3);
648 }
649 ASSERT_EQ(2, sFakeComposer->getFrameCount());
650
651 // The layers will switch order, but both are rendered because the background layer is
652 // transparent (RGBA8888).
653 std::vector<RenderState> referenceFrame(2);
654 referenceFrame[0] = mBaseFrame[FG_LAYER];
655 referenceFrame[1] = mBaseFrame[BG_LAYER];
656 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
657 }
658
TEST_F(TransactionTest,LayerSetLayerOpaque)659 TEST_F(TransactionTest, LayerSetLayerOpaque) {
660 {
661 TransactionScope ts(*sFakeComposer);
662 ts.setLayer(mFGSurfaceControl, INT_MAX - 3);
663 ts.setFlags(mBGSurfaceControl, layer_state_t::eLayerOpaque,
664 layer_state_t::eLayerOpaque);
665 }
666 ASSERT_EQ(2, sFakeComposer->getFrameCount());
667
668 // The former foreground layer is now covered with opaque layer - it should have disappeared
669 std::vector<RenderState> referenceFrame(1);
670 referenceFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
671 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
672 }
673
TEST_F(TransactionTest,SetLayerStack)674 TEST_F(TransactionTest, SetLayerStack) {
675 ALOGD("TransactionTest::SetLayerStack");
676 {
677 TransactionScope ts(*sFakeComposer);
678 ts.setLayerStack(mFGSurfaceControl, 1);
679 }
680
681 // Foreground layer should have disappeared.
682 ASSERT_EQ(2, sFakeComposer->getFrameCount());
683 std::vector<RenderState> refFrame(1);
684 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
685 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
686 }
687
TEST_F(TransactionTest,LayerShowHide)688 TEST_F(TransactionTest, LayerShowHide) {
689 ALOGD("TransactionTest::LayerShowHide");
690 {
691 TransactionScope ts(*sFakeComposer);
692 ts.hide(mFGSurfaceControl);
693 }
694
695 // Foreground layer should have disappeared.
696 ASSERT_EQ(2, sFakeComposer->getFrameCount());
697 std::vector<RenderState> refFrame(1);
698 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
699 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
700
701 {
702 TransactionScope ts(*sFakeComposer);
703 ts.show(mFGSurfaceControl);
704 }
705
706 // Foreground layer should be back
707 ASSERT_EQ(3, sFakeComposer->getFrameCount());
708 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
709 }
710
TEST_F(TransactionTest,LayerSetAlpha)711 TEST_F(TransactionTest, LayerSetAlpha) {
712 {
713 TransactionScope ts(*sFakeComposer);
714 ts.setAlpha(mFGSurfaceControl, 0.75f);
715 }
716
717 ASSERT_EQ(2, sFakeComposer->getFrameCount());
718 auto referenceFrame = mBaseFrame;
719 referenceFrame[FG_LAYER].mPlaneAlpha = 0.75f;
720 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
721 }
722
TEST_F(TransactionTest,LayerSetFlags)723 TEST_F(TransactionTest, LayerSetFlags) {
724 {
725 TransactionScope ts(*sFakeComposer);
726 ts.setFlags(mFGSurfaceControl, layer_state_t::eLayerHidden,
727 layer_state_t::eLayerHidden);
728 }
729
730 // Foreground layer should have disappeared.
731 ASSERT_EQ(2, sFakeComposer->getFrameCount());
732 std::vector<RenderState> refFrame(1);
733 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
734 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
735 }
736
TEST_F(TransactionTest,LayerSetMatrix)737 TEST_F(TransactionTest, LayerSetMatrix) {
738 struct matrixTestData {
739 float matrix[4];
740 hwc_transform_t expectedTransform;
741 hwc_rect_t expectedDisplayFrame;
742 };
743
744 // The matrix operates on the display frame and is applied before
745 // the position is added. So, the foreground layer rect is (0, 0,
746 // 64, 64) is first transformed, potentially yielding negative
747 // coordinates and then the position (64, 64) is added yielding
748 // the final on-screen rectangles given.
749
750 const matrixTestData MATRIX_TESTS[7] = // clang-format off
751 {{{-1.f, 0.f, 0.f, 1.f}, HWC_TRANSFORM_FLIP_H, {0, 64, 64, 128}},
752 {{1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_FLIP_V, {64, 0, 128, 64}},
753 {{0.f, 1.f, -1.f, 0.f}, HWC_TRANSFORM_ROT_90, {0, 64, 64, 128}},
754 {{-1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_ROT_180, {0, 0, 64, 64}},
755 {{0.f, -1.f, 1.f, 0.f}, HWC_TRANSFORM_ROT_270, {64, 0, 128, 64}},
756 {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_H_ROT_90, {64, 64, 128, 128}},
757 {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_V_ROT_90, {64, 64, 128, 128}}};
758 // clang-format on
759 constexpr int TEST_COUNT = sizeof(MATRIX_TESTS) / sizeof(matrixTestData);
760
761 for (int i = 0; i < TEST_COUNT; i++) {
762 // TODO: How to leverage the HWC2 stringifiers?
763 const matrixTestData& xform = MATRIX_TESTS[i];
764 SCOPED_TRACE(i);
765 {
766 TransactionScope ts(*sFakeComposer);
767 ts.setMatrix(mFGSurfaceControl, xform.matrix[0], xform.matrix[1],
768 xform.matrix[2], xform.matrix[3]);
769 }
770
771 auto referenceFrame = mBaseFrame;
772 referenceFrame[FG_LAYER].mTransform = xform.expectedTransform;
773 referenceFrame[FG_LAYER].mDisplayFrame = xform.expectedDisplayFrame;
774
775 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
776 }
777 }
778
779 #if 0
780 TEST_F(TransactionTest, LayerSetMatrix2) {
781 {
782 TransactionScope ts(*sFakeComposer);
783 // TODO: PLEASE SPEC THE FUNCTION!
784 ts.setMatrix(mFGSurfaceControl, 0.11f, 0.123f,
785 -2.33f, 0.22f);
786 }
787 auto referenceFrame = mBaseFrame;
788 // TODO: Is this correct for sure?
789 //referenceFrame[FG_LAYER].mTransform = HWC_TRANSFORM_FLIP_V & HWC_TRANSFORM_ROT_90;
790
791 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
792 }
793 #endif
794
TEST_F(TransactionTest,DeferredTransaction)795 TEST_F(TransactionTest, DeferredTransaction) {
796 // Synchronization surface
797 constexpr static int SYNC_LAYER = 2;
798 auto syncSurfaceControl = mComposerClient->createSurface(String8("Sync Test Surface"), 1, 1,
799 PIXEL_FORMAT_RGBA_8888, 0);
800 ASSERT_TRUE(syncSurfaceControl != nullptr);
801 ASSERT_TRUE(syncSurfaceControl->isValid());
802
803 fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY);
804
805 {
806 TransactionScope ts(*sFakeComposer);
807 ts.setLayer(syncSurfaceControl, INT32_MAX - 1);
808 ts.setPosition(syncSurfaceControl, mDisplayWidth - 2, mDisplayHeight - 2);
809 ts.show(syncSurfaceControl);
810 }
811 auto referenceFrame = mBaseFrame;
812 referenceFrame.push_back(makeSimpleRect(mDisplayWidth - 2, mDisplayHeight - 2,
813 mDisplayWidth - 1, mDisplayHeight - 1));
814 referenceFrame[SYNC_LAYER].mSwapCount = 1;
815 EXPECT_EQ(2, sFakeComposer->getFrameCount());
816 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
817
818 // set up two deferred transactions on different frames - these should not yield composited
819 // frames
820 {
821 TransactionScope ts(*sFakeComposer);
822 ts.setAlpha(mFGSurfaceControl, 0.75);
823 ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl->getHandle(),
824 syncSurfaceControl->getSurface()->getNextFrameNumber());
825 }
826 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
827
828 {
829 TransactionScope ts(*sFakeComposer);
830 ts.setPosition(mFGSurfaceControl, 128, 128);
831 ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl->getHandle(),
832 syncSurfaceControl->getSurface()->getNextFrameNumber() + 1);
833 }
834 EXPECT_EQ(4, sFakeComposer->getFrameCount());
835 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
836
837 // should trigger the first deferred transaction, but not the second one
838 fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY);
839 sFakeComposer->runVSyncAndWait();
840 EXPECT_EQ(5, sFakeComposer->getFrameCount());
841
842 referenceFrame[FG_LAYER].mPlaneAlpha = 0.75f;
843 referenceFrame[SYNC_LAYER].mSwapCount++;
844 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
845
846 // should show up immediately since it's not deferred
847 {
848 TransactionScope ts(*sFakeComposer);
849 ts.setAlpha(mFGSurfaceControl, 1.0);
850 }
851 referenceFrame[FG_LAYER].mPlaneAlpha = 1.f;
852 EXPECT_EQ(6, sFakeComposer->getFrameCount());
853 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
854
855 // trigger the second deferred transaction
856 fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY);
857 sFakeComposer->runVSyncAndWait();
858 // TODO: Compute from layer size?
859 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{128, 128, 128 + 64, 128 + 64};
860 referenceFrame[SYNC_LAYER].mSwapCount++;
861 EXPECT_EQ(7, sFakeComposer->getFrameCount());
862 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
863 }
864
TEST_F(TransactionTest,SetRelativeLayer)865 TEST_F(TransactionTest, SetRelativeLayer) {
866 constexpr int RELATIVE_LAYER = 2;
867 auto relativeSurfaceControl = mComposerClient->createSurface(String8("Test Surface"), 64, 64,
868 PIXEL_FORMAT_RGBA_8888, 0);
869 fillSurfaceRGBA8(relativeSurfaceControl, LIGHT_RED);
870
871 // Now we stack the surface above the foreground surface and make sure it is visible.
872 {
873 TransactionScope ts(*sFakeComposer);
874 ts.setPosition(relativeSurfaceControl, 64, 64);
875 ts.show(relativeSurfaceControl);
876 ts.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl->getHandle(), 1);
877 }
878 auto referenceFrame = mBaseFrame;
879 // NOTE: All three layers will be visible as the surfaces are
880 // transparent because of the RGBA format.
881 referenceFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64));
882 referenceFrame[RELATIVE_LAYER].mSwapCount = 1;
883 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
884
885 // A call to setLayer will override a call to setRelativeLayer
886 {
887 TransactionScope ts(*sFakeComposer);
888 ts.setLayer(relativeSurfaceControl, 0);
889 }
890
891 // Previous top layer will now appear at the bottom.
892 auto referenceFrame2 = mBaseFrame;
893 referenceFrame2.insert(referenceFrame2.begin(), referenceFrame[RELATIVE_LAYER]);
894 EXPECT_EQ(3, sFakeComposer->getFrameCount());
895 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
896 }
897
898 class ChildLayerTest : public TransactionTest {
899 protected:
900 constexpr static int CHILD_LAYER = 2;
901
SetUp()902 void SetUp() override {
903 TransactionTest::SetUp();
904 mChild = mComposerClient->createSurface(String8("Child surface"), 10, 10,
905 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
906 fillSurfaceRGBA8(mChild, LIGHT_GRAY);
907
908 sFakeComposer->runVSyncAndWait();
909 mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10));
910 mBaseFrame[CHILD_LAYER].mSwapCount = 1;
911 ASSERT_EQ(2, sFakeComposer->getFrameCount());
912 ASSERT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
913 }
TearDown()914 void TearDown() override {
915 mChild = 0;
916 TransactionTest::TearDown();
917 }
918
919 sp<SurfaceControl> mChild;
920 };
921
TEST_F(ChildLayerTest,Positioning)922 TEST_F(ChildLayerTest, Positioning) {
923 {
924 TransactionScope ts(*sFakeComposer);
925 ts.show(mChild);
926 ts.setPosition(mChild, 10, 10);
927 // Move to the same position as in the original setup.
928 ts.setPosition(mFGSurfaceControl, 64, 64);
929 }
930
931 auto referenceFrame = mBaseFrame;
932 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
933 referenceFrame[CHILD_LAYER].mDisplayFrame =
934 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
935 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
936
937 {
938 TransactionScope ts(*sFakeComposer);
939 ts.setPosition(mFGSurfaceControl, 0, 0);
940 }
941
942 auto referenceFrame2 = mBaseFrame;
943 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 64, 0 + 64};
944 referenceFrame2[CHILD_LAYER].mDisplayFrame =
945 hwc_rect_t{0 + 10, 0 + 10, 0 + 10 + 10, 0 + 10 + 10};
946 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
947 }
948
TEST_F(ChildLayerTest,Cropping)949 TEST_F(ChildLayerTest, Cropping) {
950 {
951 TransactionScope ts(*sFakeComposer);
952 ts.show(mChild);
953 ts.setPosition(mChild, 0, 0);
954 ts.setPosition(mFGSurfaceControl, 0, 0);
955 ts.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5));
956 }
957 // NOTE: The foreground surface would be occluded by the child
958 // now, but is included in the stack because the child is
959 // transparent.
960 auto referenceFrame = mBaseFrame;
961 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
962 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
963 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
964 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
965 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
966 }
967
TEST_F(ChildLayerTest,Constraints)968 TEST_F(ChildLayerTest, Constraints) {
969 {
970 TransactionScope ts(*sFakeComposer);
971 ts.show(mChild);
972 ts.setPosition(mFGSurfaceControl, 0, 0);
973 ts.setPosition(mChild, 63, 63);
974 }
975 auto referenceFrame = mBaseFrame;
976 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
977 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{63, 63, 64, 64};
978 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 1.f, 1.f};
979 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
980 }
981
TEST_F(ChildLayerTest,Scaling)982 TEST_F(ChildLayerTest, Scaling) {
983 {
984 TransactionScope ts(*sFakeComposer);
985 ts.setPosition(mFGSurfaceControl, 0, 0);
986 }
987 auto referenceFrame = mBaseFrame;
988 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
989 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
990 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
991
992 {
993 TransactionScope ts(*sFakeComposer);
994 ts.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0);
995 }
996
997 auto referenceFrame2 = mBaseFrame;
998 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 128, 128};
999 referenceFrame2[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 20, 20};
1000 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1001 }
1002
TEST_F(ChildLayerTest,LayerAlpha)1003 TEST_F(ChildLayerTest, LayerAlpha) {
1004 {
1005 TransactionScope ts(*sFakeComposer);
1006 ts.show(mChild);
1007 ts.setPosition(mChild, 0, 0);
1008 ts.setPosition(mFGSurfaceControl, 0, 0);
1009 ts.setAlpha(mChild, 0.5);
1010 }
1011
1012 auto referenceFrame = mBaseFrame;
1013 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1014 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1015 referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f;
1016 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1017
1018 {
1019 TransactionScope ts(*sFakeComposer);
1020 ts.setAlpha(mFGSurfaceControl, 0.5);
1021 }
1022
1023 auto referenceFrame2 = referenceFrame;
1024 referenceFrame2[FG_LAYER].mPlaneAlpha = 0.5f;
1025 referenceFrame2[CHILD_LAYER].mPlaneAlpha = 0.25f;
1026 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1027 }
1028
TEST_F(ChildLayerTest,ReparentChildren)1029 TEST_F(ChildLayerTest, ReparentChildren) {
1030 {
1031 TransactionScope ts(*sFakeComposer);
1032 ts.show(mChild);
1033 ts.setPosition(mChild, 10, 10);
1034 ts.setPosition(mFGSurfaceControl, 64, 64);
1035 }
1036 auto referenceFrame = mBaseFrame;
1037 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1038 referenceFrame[CHILD_LAYER].mDisplayFrame =
1039 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
1040 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1041
1042 {
1043 TransactionScope ts(*sFakeComposer);
1044 ts.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle());
1045 }
1046
1047 auto referenceFrame2 = referenceFrame;
1048 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1049 referenceFrame2[CHILD_LAYER].mDisplayFrame = hwc_rect_t{10, 10, 10 + 10, 10 + 10};
1050 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1051 }
1052
TEST_F(ChildLayerTest,DetachChildrenSameClient)1053 TEST_F(ChildLayerTest, DetachChildrenSameClient) {
1054 {
1055 TransactionScope ts(*sFakeComposer);
1056 ts.show(mChild);
1057 ts.setPosition(mChild, 10, 10);
1058 ts.setPosition(mFGSurfaceControl, 64, 64);
1059 }
1060
1061 auto referenceFrame = mBaseFrame;
1062 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1063 referenceFrame[CHILD_LAYER].mDisplayFrame =
1064 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
1065 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1066
1067 {
1068 TransactionScope ts(*sFakeComposer);
1069 ts.setPosition(mFGSurfaceControl, 0, 0);
1070 ts.detachChildren(mFGSurfaceControl);
1071 }
1072
1073 {
1074 TransactionScope ts(*sFakeComposer);
1075 ts.setPosition(mFGSurfaceControl, 64, 64);
1076 ts.hide(mChild);
1077 }
1078
1079 std::vector<RenderState> refFrame(2);
1080 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
1081 refFrame[FG_LAYER] = mBaseFrame[FG_LAYER];
1082
1083 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
1084 }
1085
TEST_F(ChildLayerTest,DetachChildrenDifferentClient)1086 TEST_F(ChildLayerTest, DetachChildrenDifferentClient) {
1087 sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
1088 sp<SurfaceControl> childNewClient =
1089 newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
1090 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1091 ASSERT_TRUE(childNewClient != nullptr);
1092 ASSERT_TRUE(childNewClient->isValid());
1093 fillSurfaceRGBA8(childNewClient, LIGHT_GRAY);
1094
1095 {
1096 TransactionScope ts(*sFakeComposer);
1097 ts.hide(mChild);
1098 ts.show(childNewClient);
1099 ts.setPosition(childNewClient, 10, 10);
1100 ts.setPosition(mFGSurfaceControl, 64, 64);
1101 }
1102
1103 auto referenceFrame = mBaseFrame;
1104 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1105 referenceFrame[CHILD_LAYER].mDisplayFrame =
1106 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
1107 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1108
1109 {
1110 TransactionScope ts(*sFakeComposer);
1111 ts.detachChildren(mFGSurfaceControl);
1112 ts.setPosition(mFGSurfaceControl, 0, 0);
1113 }
1114
1115 {
1116 TransactionScope ts(*sFakeComposer);
1117 ts.setPosition(mFGSurfaceControl, 64, 64);
1118 ts.setPosition(childNewClient, 0, 0);
1119 ts.hide(childNewClient);
1120 }
1121
1122 // Nothing should have changed. The child control becomes a no-op
1123 // zombie on detach. See comments for detachChildren in the
1124 // SurfaceControl.h file.
1125 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1126 }
1127
TEST_F(ChildLayerTest,InheritNonTransformScalingFromParent)1128 TEST_F(ChildLayerTest, InheritNonTransformScalingFromParent) {
1129 {
1130 TransactionScope ts(*sFakeComposer);
1131 ts.show(mChild);
1132 ts.setPosition(mChild, 0, 0);
1133 ts.setPosition(mFGSurfaceControl, 0, 0);
1134 }
1135
1136 {
1137 TransactionScope ts(*sFakeComposer);
1138 ts.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1139 // We cause scaling by 2.
1140 ts.setSize(mFGSurfaceControl, 128, 128);
1141 }
1142
1143 auto referenceFrame = mBaseFrame;
1144 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 128, 128};
1145 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 64.f, 64.f};
1146 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 20, 20};
1147 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 10.f, 10.f};
1148 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1149 }
1150
1151 // Regression test for b/37673612
TEST_F(ChildLayerTest,ChildrenWithParentBufferTransform)1152 TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
1153 {
1154 TransactionScope ts(*sFakeComposer);
1155 ts.show(mChild);
1156 ts.setPosition(mChild, 0, 0);
1157 ts.setPosition(mFGSurfaceControl, 0, 0);
1158 }
1159
1160 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
1161 // the WM specified state size.
1162 {
1163 TransactionScope ts(*sFakeComposer);
1164 ts.setSize(mFGSurfaceControl, 128, 64);
1165 }
1166
1167 sp<Surface> s = mFGSurfaceControl->getSurface();
1168 auto anw = static_cast<ANativeWindow*>(s.get());
1169 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
1170 native_window_set_buffers_dimensions(anw, 64, 128);
1171 fillSurfaceRGBA8(mFGSurfaceControl, RED);
1172 sFakeComposer->runVSyncAndWait();
1173
1174 // The child should still be in the same place and not have any strange scaling as in
1175 // b/37673612.
1176 auto referenceFrame = mBaseFrame;
1177 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 128, 64};
1178 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 64.f, 128.f};
1179 referenceFrame[FG_LAYER].mSwapCount++;
1180 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1181 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1182 }
1183
TEST_F(ChildLayerTest,Bug36858924)1184 TEST_F(ChildLayerTest, Bug36858924) {
1185 // Destroy the child layer
1186 mChild.clear();
1187
1188 // Now recreate it as hidden
1189 mChild = mComposerClient->createSurface(String8("Child surface"), 10, 10,
1190 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eHidden,
1191 mFGSurfaceControl.get());
1192
1193 // Show the child layer in a deferred transaction
1194 {
1195 TransactionScope ts(*sFakeComposer);
1196 ts.deferTransactionUntil_legacy(mChild, mFGSurfaceControl->getHandle(),
1197 mFGSurfaceControl->getSurface()->getNextFrameNumber());
1198 ts.show(mChild);
1199 }
1200
1201 // Render the foreground surface a few times
1202 //
1203 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
1204 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
1205 // never acquire/release the first buffer
1206 ALOGI("Filling 1");
1207 fillSurfaceRGBA8(mFGSurfaceControl, GREEN);
1208 sFakeComposer->runVSyncAndWait();
1209 ALOGI("Filling 2");
1210 fillSurfaceRGBA8(mFGSurfaceControl, BLUE);
1211 sFakeComposer->runVSyncAndWait();
1212 ALOGI("Filling 3");
1213 fillSurfaceRGBA8(mFGSurfaceControl, RED);
1214 sFakeComposer->runVSyncAndWait();
1215 ALOGI("Filling 4");
1216 fillSurfaceRGBA8(mFGSurfaceControl, GREEN);
1217 sFakeComposer->runVSyncAndWait();
1218 }
1219
1220 class ChildColorLayerTest : public ChildLayerTest {
1221 protected:
SetUp()1222 void SetUp() override {
1223 TransactionTest::SetUp();
1224 mChild = mComposerClient->createSurface(String8("Child surface"), 0, 0,
1225 PIXEL_FORMAT_RGBA_8888,
1226 ISurfaceComposerClient::eFXSurfaceColor,
1227 mFGSurfaceControl.get());
1228 {
1229 TransactionScope ts(*sFakeComposer);
1230 ts.setColor(mChild,
1231 {LIGHT_GRAY.r / 255.0f, LIGHT_GRAY.g / 255.0f, LIGHT_GRAY.b / 255.0f});
1232 ts.setCrop_legacy(mChild, Rect(0, 0, 10, 10));
1233 }
1234
1235 sFakeComposer->runVSyncAndWait();
1236 mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10));
1237 mBaseFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.0f, 0.0f, 0.0f, 0.0f};
1238 mBaseFrame[CHILD_LAYER].mSwapCount = 0;
1239 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1240 ASSERT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1241 }
1242 };
1243
TEST_F(ChildColorLayerTest,LayerAlpha)1244 TEST_F(ChildColorLayerTest, LayerAlpha) {
1245 {
1246 TransactionScope ts(*sFakeComposer);
1247 ts.show(mChild);
1248 ts.setPosition(mChild, 0, 0);
1249 ts.setPosition(mFGSurfaceControl, 0, 0);
1250 ts.setAlpha(mChild, 0.5);
1251 }
1252
1253 auto referenceFrame = mBaseFrame;
1254 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1255 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1256 referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f;
1257 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1258
1259 {
1260 TransactionScope ts(*sFakeComposer);
1261 ts.setAlpha(mFGSurfaceControl, 0.5);
1262 }
1263
1264 auto referenceFrame2 = referenceFrame;
1265 referenceFrame2[FG_LAYER].mPlaneAlpha = 0.5f;
1266 referenceFrame2[CHILD_LAYER].mPlaneAlpha = 0.25f;
1267 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1268 }
1269
TEST_F(ChildColorLayerTest,LayerZeroAlpha)1270 TEST_F(ChildColorLayerTest, LayerZeroAlpha) {
1271 {
1272 TransactionScope ts(*sFakeComposer);
1273 ts.show(mChild);
1274 ts.setPosition(mChild, 0, 0);
1275 ts.setPosition(mFGSurfaceControl, 0, 0);
1276 ts.setAlpha(mChild, 0.5);
1277 }
1278
1279 auto referenceFrame = mBaseFrame;
1280 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1281 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1282 referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f;
1283 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1284
1285 {
1286 TransactionScope ts(*sFakeComposer);
1287 ts.setAlpha(mFGSurfaceControl, 0.0f);
1288 }
1289
1290 std::vector<RenderState> refFrame(1);
1291 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
1292
1293 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
1294 }
1295
1296 class LatchingTest : public TransactionTest {
1297 protected:
lockAndFillFGBuffer()1298 void lockAndFillFGBuffer() { fillSurfaceRGBA8(mFGSurfaceControl, RED, false); }
1299
unlockFGBuffer()1300 void unlockFGBuffer() {
1301 sp<Surface> s = mFGSurfaceControl->getSurface();
1302 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
1303 sFakeComposer->runVSyncAndWait();
1304 }
1305
completeFGResize()1306 void completeFGResize() {
1307 fillSurfaceRGBA8(mFGSurfaceControl, RED);
1308 sFakeComposer->runVSyncAndWait();
1309 }
restoreInitialState()1310 void restoreInitialState() {
1311 TransactionScope ts(*sFakeComposer);
1312 ts.setSize(mFGSurfaceControl, 64, 64);
1313 ts.setPosition(mFGSurfaceControl, 64, 64);
1314 ts.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 64, 64));
1315 }
1316 };
1317
TEST_F(LatchingTest,SurfacePositionLatching)1318 TEST_F(LatchingTest, SurfacePositionLatching) {
1319 // By default position can be updated even while
1320 // a resize is pending.
1321 {
1322 TransactionScope ts(*sFakeComposer);
1323 ts.setSize(mFGSurfaceControl, 32, 32);
1324 ts.setPosition(mFGSurfaceControl, 100, 100);
1325 }
1326
1327 // The size should not have updated as we have not provided a new buffer.
1328 auto referenceFrame1 = mBaseFrame;
1329 referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{100, 100, 100 + 64, 100 + 64};
1330 EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame()));
1331
1332 restoreInitialState();
1333
1334 // Now we repeat with setGeometryAppliesWithResize
1335 // and verify the position DOESN'T latch.
1336 {
1337 TransactionScope ts(*sFakeComposer);
1338 ts.setGeometryAppliesWithResize(mFGSurfaceControl);
1339 ts.setSize(mFGSurfaceControl, 32, 32);
1340 ts.setPosition(mFGSurfaceControl, 100, 100);
1341 }
1342 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1343
1344 completeFGResize();
1345
1346 auto referenceFrame2 = mBaseFrame;
1347 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{100, 100, 100 + 32, 100 + 32};
1348 referenceFrame2[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 32.f, 32.f};
1349 referenceFrame2[FG_LAYER].mSwapCount++;
1350 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1351 }
1352
TEST_F(LatchingTest,CropLatching)1353 TEST_F(LatchingTest, CropLatching) {
1354 // Normally the crop applies immediately even while a resize is pending.
1355 {
1356 TransactionScope ts(*sFakeComposer);
1357 ts.setSize(mFGSurfaceControl, 128, 128);
1358 ts.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 63, 63));
1359 }
1360
1361 auto referenceFrame1 = mBaseFrame;
1362 referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 63, 64 + 63};
1363 referenceFrame1[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 63.f, 63.f};
1364 EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame()));
1365
1366 restoreInitialState();
1367
1368 {
1369 TransactionScope ts(*sFakeComposer);
1370 ts.setSize(mFGSurfaceControl, 128, 128);
1371 ts.setGeometryAppliesWithResize(mFGSurfaceControl);
1372 ts.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 63, 63));
1373 }
1374 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1375
1376 completeFGResize();
1377
1378 auto referenceFrame2 = mBaseFrame;
1379 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 63, 64 + 63};
1380 referenceFrame2[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 63.f, 63.f};
1381 referenceFrame2[FG_LAYER].mSwapCount++;
1382 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1383 }
1384
1385 } // namespace
1386
main(int argc,char ** argv)1387 int main(int argc, char** argv) {
1388 ::testing::InitGoogleTest(&argc, argv);
1389
1390 sftest::FakeHwcEnvironment* fakeEnvironment = new sftest::FakeHwcEnvironment;
1391 ::testing::AddGlobalTestEnvironment(fakeEnvironment);
1392 ::testing::InitGoogleMock(&argc, argv);
1393 return RUN_ALL_TESTS();
1394 }
1395