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