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(uint32_t id, 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(uint32_t id,bool connected)245 bool DisplayTest::waitForHotplugEvent(uint32_t id, 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: id %d, connected %d\t", event.header.id,
254 event.hotplug.connected);
255
256 if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG &&
257 event.header.id == id && event.hotplug.connected == connected) {
258 return true;
259 }
260 }
261
262 mLooper->pollOnce(1);
263 }
264
265 return false;
266 }
267
TEST_F(DisplayTest,Hotplug)268 TEST_F(DisplayTest, Hotplug) {
269 ALOGD("DisplayTest::Hotplug");
270
271 EXPECT_CALL(*mMockComposer, getDisplayType(EXTERNAL_DISPLAY, _))
272 .Times(2)
273 .WillRepeatedly(DoAll(SetArgPointee<1>(IComposerClient::DisplayType::PHYSICAL),
274 Return(Error::NONE)));
275 // The attribute queries will get done twice. This is for defaults
276 EXPECT_CALL(*mMockComposer, getDisplayAttribute(EXTERNAL_DISPLAY, 1, _, _))
277 .Times(2 * 3)
278 .WillRepeatedly(Invoke(mMockComposer, &MockComposerClient::getDisplayAttributeFake));
279 // ... and then special handling for dimensions. Specifying these
280 // rules later means that gmock will try them first, i.e.,
281 // ordering of width/height vs. the default implementation for
282 // other queries is significant.
283 EXPECT_CALL(*mMockComposer,
284 getDisplayAttribute(EXTERNAL_DISPLAY, 1, IComposerClient::Attribute::WIDTH, _))
285 .Times(2)
286 .WillRepeatedly(DoAll(SetArgPointee<3>(400), Return(Error::NONE)));
287
288 EXPECT_CALL(*mMockComposer,
289 getDisplayAttribute(EXTERNAL_DISPLAY, 1, IComposerClient::Attribute::HEIGHT, _))
290 .Times(2)
291 .WillRepeatedly(DoAll(SetArgPointee<3>(200), Return(Error::NONE)));
292
293 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::CONNECTED);
294
295 waitForDisplayTransaction();
296
297 EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, true));
298
299 {
300 sp<android::IBinder> display(
301 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdHdmi));
302 DisplayInfo info;
303 SurfaceComposerClient::getDisplayInfo(display, &info);
304 ASSERT_EQ(400u, info.w);
305 ASSERT_EQ(200u, info.h);
306
307 auto surfaceControl =
308 mComposerClient->createSurface(String8("Display Test Surface Foo"), info.w, info.h,
309 PIXEL_FORMAT_RGBA_8888, 0);
310 ASSERT_TRUE(surfaceControl != nullptr);
311 ASSERT_TRUE(surfaceControl->isValid());
312 fillSurfaceRGBA8(surfaceControl, BLUE);
313
314 {
315 TransactionScope ts(*mMockComposer);
316 ts.setDisplayLayerStack(display, 0);
317
318 ts.setLayer(surfaceControl, INT32_MAX - 2)
319 .show(surfaceControl);
320 }
321 }
322
323 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::DISCONNECTED);
324
325 mMockComposer->clearFrames();
326
327 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::CONNECTED);
328
329 waitForDisplayTransaction();
330
331 EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, false));
332 EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, true));
333
334 {
335 sp<android::IBinder> display(
336 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdHdmi));
337 DisplayInfo info;
338 SurfaceComposerClient::getDisplayInfo(display, &info);
339 ASSERT_EQ(400u, info.w);
340 ASSERT_EQ(200u, info.h);
341
342 auto surfaceControl =
343 mComposerClient->createSurface(String8("Display Test Surface Bar"), info.w, info.h,
344 PIXEL_FORMAT_RGBA_8888, 0);
345 ASSERT_TRUE(surfaceControl != nullptr);
346 ASSERT_TRUE(surfaceControl->isValid());
347 fillSurfaceRGBA8(surfaceControl, BLUE);
348
349 {
350 TransactionScope ts(*mMockComposer);
351 ts.setDisplayLayerStack(display, 0);
352
353 ts.setLayer(surfaceControl, INT32_MAX - 2)
354 .show(surfaceControl);
355 }
356 }
357 mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::DISCONNECTED);
358 }
359
TEST_F(DisplayTest,HotplugPrimaryDisplay)360 TEST_F(DisplayTest, HotplugPrimaryDisplay) {
361 ALOGD("DisplayTest::HotplugPrimaryDisplay");
362
363 mMockComposer->hotplugDisplay(PRIMARY_DISPLAY, IComposerCallback::Connection::DISCONNECTED);
364
365 waitForDisplayTransaction();
366
367 EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdMain, false));
368
369 {
370 sp<android::IBinder> display(
371 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
372 DisplayInfo info;
373 auto result = SurfaceComposerClient::getDisplayInfo(display, &info);
374 EXPECT_NE(NO_ERROR, result);
375 }
376
377 mMockComposer->clearFrames();
378
379 EXPECT_CALL(*mMockComposer, getDisplayType(PRIMARY_DISPLAY, _))
380 .Times(2)
381 .WillRepeatedly(DoAll(SetArgPointee<1>(IComposerClient::DisplayType::PHYSICAL),
382 Return(Error::NONE)));
383 // The attribute queries will get done twice. This is for defaults
384 EXPECT_CALL(*mMockComposer, getDisplayAttribute(PRIMARY_DISPLAY, 1, _, _))
385 .Times(2 * 3)
386 .WillRepeatedly(Invoke(mMockComposer, &MockComposerClient::getDisplayAttributeFake));
387 // ... and then special handling for dimensions. Specifying these
388 // rules later means that gmock will try them first, i.e.,
389 // ordering of width/height vs. the default implementation for
390 // other queries is significant.
391 EXPECT_CALL(*mMockComposer,
392 getDisplayAttribute(PRIMARY_DISPLAY, 1, IComposerClient::Attribute::WIDTH, _))
393 .Times(2)
394 .WillRepeatedly(DoAll(SetArgPointee<3>(400), Return(Error::NONE)));
395
396 EXPECT_CALL(*mMockComposer,
397 getDisplayAttribute(PRIMARY_DISPLAY, 1, IComposerClient::Attribute::HEIGHT, _))
398 .Times(2)
399 .WillRepeatedly(DoAll(SetArgPointee<3>(200), Return(Error::NONE)));
400
401 mMockComposer->hotplugDisplay(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED);
402
403 waitForDisplayTransaction();
404
405 EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdMain, true));
406
407 {
408 sp<android::IBinder> display(
409 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
410 DisplayInfo info;
411 auto result = SurfaceComposerClient::getDisplayInfo(display, &info);
412 EXPECT_EQ(NO_ERROR, result);
413 ASSERT_EQ(400u, info.w);
414 ASSERT_EQ(200u, info.h);
415 }
416 }
417
418 ////////////////////////////////////////////////
419
420 class TransactionTest : public ::testing::Test {
421 protected:
422 // Layer array indexing constants.
423 constexpr static int BG_LAYER = 0;
424 constexpr static int FG_LAYER = 1;
425
426 static void SetUpTestCase();
427 static void TearDownTestCase();
428
429 void SetUp() override;
430 void TearDown() override;
431
432 sp<SurfaceComposerClient> mComposerClient;
433 sp<SurfaceControl> mBGSurfaceControl;
434 sp<SurfaceControl> mFGSurfaceControl;
435 std::vector<RenderState> mBaseFrame;
436 uint32_t mDisplayWidth;
437 uint32_t mDisplayHeight;
438
439 static FakeComposerClient* sFakeComposer;
440 };
441
442 FakeComposerClient* TransactionTest::sFakeComposer;
443
SetUpTestCase()444 void TransactionTest::SetUpTestCase() {
445 // TODO: See TODO comment at DisplayTest::SetUp for background on
446 // the lifetime of the FakeComposerClient.
447 sFakeComposer = new FakeComposerClient;
448 sp<ComposerClient> client = new ComposerClient(sFakeComposer);
449 sp<IComposer> fakeService = new FakeComposerService(client);
450 (void)fakeService->registerAsService("mock");
451
452 android::hardware::ProcessState::self()->startThreadPool();
453 android::ProcessState::self()->startThreadPool();
454
455 startSurfaceFlinger();
456
457 // Fake composer wants to enable VSync injection
458 sFakeComposer->onSurfaceFlingerStart();
459 }
460
TearDownTestCase()461 void TransactionTest::TearDownTestCase() {
462 // Fake composer needs to release SurfaceComposerClient before the stop.
463 sFakeComposer->onSurfaceFlingerStop();
464 stopSurfaceFlinger();
465 // TODO: This is deleted when the ComposerClient calls
466 // removeClient. Devise better lifetime control.
467 sFakeComposer = nullptr;
468 }
469
SetUp()470 void TransactionTest::SetUp() {
471 ALOGI("TransactionTest::SetUp");
472 mComposerClient = new SurfaceComposerClient;
473 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
474
475 ALOGI("TransactionTest::SetUp - display");
476 sp<android::IBinder> display(
477 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
478 DisplayInfo info;
479 SurfaceComposerClient::getDisplayInfo(display, &info);
480
481 mDisplayWidth = info.w;
482 mDisplayHeight = info.h;
483
484 // Background surface
485 mBGSurfaceControl = mComposerClient->createSurface(String8("BG Test Surface"), mDisplayWidth,
486 mDisplayHeight, PIXEL_FORMAT_RGBA_8888, 0);
487 ASSERT_TRUE(mBGSurfaceControl != nullptr);
488 ASSERT_TRUE(mBGSurfaceControl->isValid());
489 fillSurfaceRGBA8(mBGSurfaceControl, BLUE);
490
491 // Foreground surface
492 mFGSurfaceControl = mComposerClient->createSurface(String8("FG Test Surface"), 64, 64,
493 PIXEL_FORMAT_RGBA_8888, 0);
494 ASSERT_TRUE(mFGSurfaceControl != nullptr);
495 ASSERT_TRUE(mFGSurfaceControl->isValid());
496
497 fillSurfaceRGBA8(mFGSurfaceControl, RED);
498
499 Transaction t;
500 t.setDisplayLayerStack(display, 0);
501
502 t.setLayer(mBGSurfaceControl, INT32_MAX - 2);
503 t.show(mBGSurfaceControl);
504
505 t.setLayer(mFGSurfaceControl, INT32_MAX - 1);
506 t.setPosition(mFGSurfaceControl, 64, 64);
507 t.show(mFGSurfaceControl);
508
509 // Synchronous transaction will stop this thread, so we set up a
510 // delayed, off-thread vsync request before closing the
511 // transaction. In the test code this is usually done with
512 // TransactionScope. Leaving here in the 'vanilla' form for
513 // reference.
514 ASSERT_EQ(0, sFakeComposer->getFrameCount());
515 sFakeComposer->runVSyncAfter(1ms);
516 t.apply();
517 sFakeComposer->waitUntilFrame(1);
518
519 // Reference data. This is what the HWC should see.
520 static_assert(BG_LAYER == 0 && FG_LAYER == 1, "Unexpected enum values for array indexing");
521 mBaseFrame.push_back(makeSimpleRect(0u, 0u, mDisplayWidth, mDisplayHeight));
522 mBaseFrame[BG_LAYER].mSwapCount = 1;
523 mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64));
524 mBaseFrame[FG_LAYER].mSwapCount = 1;
525
526 auto frame = sFakeComposer->getFrameRects(0);
527 ASSERT_TRUE(framesAreSame(mBaseFrame, frame));
528 }
529
TearDown()530 void TransactionTest::TearDown() {
531 ALOGD("TransactionTest::TearDown");
532
533 mComposerClient->dispose();
534 mBGSurfaceControl = 0;
535 mFGSurfaceControl = 0;
536 mComposerClient = 0;
537
538 sFakeComposer->runVSyncAndWait();
539 mBaseFrame.clear();
540 sFakeComposer->clearFrames();
541 ASSERT_EQ(0, sFakeComposer->getFrameCount());
542
543 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
544 std::vector<LayerDebugInfo> layers;
545 status_t result = sf->getLayerDebugInfo(&layers);
546 if (result != NO_ERROR) {
547 ALOGE("Failed to get layers %s %d", strerror(-result), result);
548 } else {
549 // If this fails, the test being torn down leaked layers.
550 EXPECT_EQ(0u, layers.size());
551 if (layers.size() > 0) {
552 for (auto layer = layers.begin(); layer != layers.end(); ++layer) {
553 std::cout << to_string(*layer).c_str();
554 }
555 // To ensure the next test has clean slate, will run the class
556 // tear down and setup here.
557 TearDownTestCase();
558 SetUpTestCase();
559 }
560 }
561 ALOGD("TransactionTest::TearDown - complete");
562 }
563
TEST_F(TransactionTest,LayerMove)564 TEST_F(TransactionTest, LayerMove) {
565 ALOGD("TransactionTest::LayerMove");
566
567 // The scope opens and closes a global transaction and, at the
568 // same time, makes sure the SurfaceFlinger progresses one frame
569 // after the transaction closes. The results of the transaction
570 // should be available in the latest frame stored by the fake
571 // composer.
572 {
573 TransactionScope ts(*sFakeComposer);
574 ts.setPosition(mFGSurfaceControl, 128, 128);
575 // NOTE: No changes yet, so vsync will do nothing, HWC does not get any calls.
576 // (How to verify that? Throw in vsync and wait a 2x frame time? Separate test?)
577 //
578 // sFakeComposer->runVSyncAndWait();
579 }
580
581 fillSurfaceRGBA8(mFGSurfaceControl, GREEN);
582 sFakeComposer->runVSyncAndWait();
583
584 ASSERT_EQ(3, sFakeComposer->getFrameCount()); // Make sure the waits didn't time out and there's
585 // no extra frames.
586
587 // NOTE: Frame 0 is produced in the SetUp.
588 auto frame1Ref = mBaseFrame;
589 frame1Ref[FG_LAYER].mDisplayFrame =
590 hwc_rect_t{128, 128, 128 + 64, 128 + 64}; // Top-most layer moves.
591 EXPECT_TRUE(framesAreSame(frame1Ref, sFakeComposer->getFrameRects(1)));
592
593 auto frame2Ref = frame1Ref;
594 frame2Ref[FG_LAYER].mSwapCount++;
595 EXPECT_TRUE(framesAreSame(frame2Ref, sFakeComposer->getFrameRects(2)));
596 }
597
TEST_F(TransactionTest,LayerResize)598 TEST_F(TransactionTest, LayerResize) {
599 ALOGD("TransactionTest::LayerResize");
600 {
601 TransactionScope ts(*sFakeComposer);
602 ts.setSize(mFGSurfaceControl, 128, 128);
603 }
604
605 fillSurfaceRGBA8(mFGSurfaceControl, GREEN);
606 sFakeComposer->runVSyncAndWait();
607
608 ASSERT_EQ(3, sFakeComposer->getFrameCount()); // Make sure the waits didn't time out and there's
609 // no extra frames.
610
611 auto frame1Ref = mBaseFrame;
612 // NOTE: The resize should not be visible for frame 1 as there's no buffer with new size posted.
613 EXPECT_TRUE(framesAreSame(frame1Ref, sFakeComposer->getFrameRects(1)));
614
615 auto frame2Ref = frame1Ref;
616 frame2Ref[FG_LAYER].mSwapCount++;
617 frame2Ref[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 128, 64 + 128};
618 frame2Ref[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 128.f, 128.f};
619 EXPECT_TRUE(framesAreSame(frame2Ref, sFakeComposer->getFrameRects(2)));
620 }
621
TEST_F(TransactionTest,LayerCrop)622 TEST_F(TransactionTest, LayerCrop) {
623 // TODO: Add scaling to confirm that crop happens in buffer space?
624 {
625 TransactionScope ts(*sFakeComposer);
626 Rect cropRect(16, 16, 32, 32);
627 ts.setCrop(mFGSurfaceControl, cropRect);
628 }
629 ASSERT_EQ(2, sFakeComposer->getFrameCount());
630
631 auto referenceFrame = mBaseFrame;
632 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{16.f, 16.f, 32.f, 32.f};
633 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64 + 16, 64 + 16, 64 + 32, 64 + 32};
634 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
635 }
636
TEST_F(TransactionTest,LayerFinalCrop)637 TEST_F(TransactionTest, LayerFinalCrop) {
638 // TODO: Add scaling to confirm that crop happens in display space?
639 {
640 TransactionScope ts(*sFakeComposer);
641 Rect cropRect(32, 32, 32 + 64, 32 + 64);
642 ts.setFinalCrop(mFGSurfaceControl, cropRect);
643 }
644 ASSERT_EQ(2, sFakeComposer->getFrameCount());
645
646 // In display space we are cropping with [32, 32, 96, 96] against display rect
647 // [64, 64, 128, 128]. Should yield display rect [64, 64, 96, 96]
648 auto referenceFrame = mBaseFrame;
649 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 32.f, 32.f};
650 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 32, 64 + 32};
651
652 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
653 }
654
TEST_F(TransactionTest,LayerFinalCropEmpty)655 TEST_F(TransactionTest, LayerFinalCropEmpty) {
656 // TODO: Add scaling to confirm that crop happens in display space?
657 {
658 TransactionScope ts(*sFakeComposer);
659 Rect cropRect(16, 16, 32, 32);
660 ts.setFinalCrop(mFGSurfaceControl, cropRect);
661 }
662 ASSERT_EQ(2, sFakeComposer->getFrameCount());
663
664 // In display space we are cropping with [16, 16, 32, 32] against display rect
665 // [64, 64, 128, 128]. The intersection is empty and only the background layer is composited.
666 std::vector<RenderState> referenceFrame(1);
667 referenceFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
668 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
669 }
670
TEST_F(TransactionTest,LayerSetLayer)671 TEST_F(TransactionTest, LayerSetLayer) {
672 {
673 TransactionScope ts(*sFakeComposer);
674 ts.setLayer(mFGSurfaceControl, INT_MAX - 3);
675 }
676 ASSERT_EQ(2, sFakeComposer->getFrameCount());
677
678 // The layers will switch order, but both are rendered because the background layer is
679 // transparent (RGBA8888).
680 std::vector<RenderState> referenceFrame(2);
681 referenceFrame[0] = mBaseFrame[FG_LAYER];
682 referenceFrame[1] = mBaseFrame[BG_LAYER];
683 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
684 }
685
TEST_F(TransactionTest,LayerSetLayerOpaque)686 TEST_F(TransactionTest, LayerSetLayerOpaque) {
687 {
688 TransactionScope ts(*sFakeComposer);
689 ts.setLayer(mFGSurfaceControl, INT_MAX - 3);
690 ts.setFlags(mBGSurfaceControl, layer_state_t::eLayerOpaque,
691 layer_state_t::eLayerOpaque);
692 }
693 ASSERT_EQ(2, sFakeComposer->getFrameCount());
694
695 // The former foreground layer is now covered with opaque layer - it should have disappeared
696 std::vector<RenderState> referenceFrame(1);
697 referenceFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
698 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
699 }
700
TEST_F(TransactionTest,SetLayerStack)701 TEST_F(TransactionTest, SetLayerStack) {
702 ALOGD("TransactionTest::SetLayerStack");
703 {
704 TransactionScope ts(*sFakeComposer);
705 ts.setLayerStack(mFGSurfaceControl, 1);
706 }
707
708 // Foreground layer should have disappeared.
709 ASSERT_EQ(2, sFakeComposer->getFrameCount());
710 std::vector<RenderState> refFrame(1);
711 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
712 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
713 }
714
TEST_F(TransactionTest,LayerShowHide)715 TEST_F(TransactionTest, LayerShowHide) {
716 ALOGD("TransactionTest::LayerShowHide");
717 {
718 TransactionScope ts(*sFakeComposer);
719 ts.hide(mFGSurfaceControl);
720 }
721
722 // Foreground layer should have disappeared.
723 ASSERT_EQ(2, sFakeComposer->getFrameCount());
724 std::vector<RenderState> refFrame(1);
725 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
726 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
727
728 {
729 TransactionScope ts(*sFakeComposer);
730 ts.show(mFGSurfaceControl);
731 }
732
733 // Foreground layer should be back
734 ASSERT_EQ(3, sFakeComposer->getFrameCount());
735 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
736 }
737
TEST_F(TransactionTest,LayerSetAlpha)738 TEST_F(TransactionTest, LayerSetAlpha) {
739 {
740 TransactionScope ts(*sFakeComposer);
741 ts.setAlpha(mFGSurfaceControl, 0.75f);
742 }
743
744 ASSERT_EQ(2, sFakeComposer->getFrameCount());
745 auto referenceFrame = mBaseFrame;
746 referenceFrame[FG_LAYER].mPlaneAlpha = 0.75f;
747 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
748 }
749
TEST_F(TransactionTest,LayerSetFlags)750 TEST_F(TransactionTest, LayerSetFlags) {
751 {
752 TransactionScope ts(*sFakeComposer);
753 ts.setFlags(mFGSurfaceControl, layer_state_t::eLayerHidden,
754 layer_state_t::eLayerHidden);
755 }
756
757 // Foreground layer should have disappeared.
758 ASSERT_EQ(2, sFakeComposer->getFrameCount());
759 std::vector<RenderState> refFrame(1);
760 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
761 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
762 }
763
TEST_F(TransactionTest,LayerSetMatrix)764 TEST_F(TransactionTest, LayerSetMatrix) {
765 struct matrixTestData {
766 float matrix[4];
767 hwc_transform_t expectedTransform;
768 hwc_rect_t expectedDisplayFrame;
769 };
770
771 // The matrix operates on the display frame and is applied before
772 // the position is added. So, the foreground layer rect is (0, 0,
773 // 64, 64) is first transformed, potentially yielding negative
774 // coordinates and then the position (64, 64) is added yielding
775 // the final on-screen rectangles given.
776
777 const matrixTestData MATRIX_TESTS[7] = // clang-format off
778 {{{-1.f, 0.f, 0.f, 1.f}, HWC_TRANSFORM_FLIP_H, {0, 64, 64, 128}},
779 {{1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_FLIP_V, {64, 0, 128, 64}},
780 {{0.f, 1.f, -1.f, 0.f}, HWC_TRANSFORM_ROT_90, {0, 64, 64, 128}},
781 {{-1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_ROT_180, {0, 0, 64, 64}},
782 {{0.f, -1.f, 1.f, 0.f}, HWC_TRANSFORM_ROT_270, {64, 0, 128, 64}},
783 {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_H_ROT_90, {64, 64, 128, 128}},
784 {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_V_ROT_90, {64, 64, 128, 128}}};
785 // clang-format on
786 constexpr int TEST_COUNT = sizeof(MATRIX_TESTS) / sizeof(matrixTestData);
787
788 for (int i = 0; i < TEST_COUNT; i++) {
789 // TODO: How to leverage the HWC2 stringifiers?
790 const matrixTestData& xform = MATRIX_TESTS[i];
791 SCOPED_TRACE(i);
792 {
793 TransactionScope ts(*sFakeComposer);
794 ts.setMatrix(mFGSurfaceControl, xform.matrix[0], xform.matrix[1],
795 xform.matrix[2], xform.matrix[3]);
796 }
797
798 auto referenceFrame = mBaseFrame;
799 referenceFrame[FG_LAYER].mTransform = xform.expectedTransform;
800 referenceFrame[FG_LAYER].mDisplayFrame = xform.expectedDisplayFrame;
801
802 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
803 }
804 }
805
806 #if 0
807 TEST_F(TransactionTest, LayerSetMatrix2) {
808 {
809 TransactionScope ts(*sFakeComposer);
810 // TODO: PLEASE SPEC THE FUNCTION!
811 ts.setMatrix(mFGSurfaceControl, 0.11f, 0.123f,
812 -2.33f, 0.22f);
813 }
814 auto referenceFrame = mBaseFrame;
815 // TODO: Is this correct for sure?
816 //referenceFrame[FG_LAYER].mTransform = HWC_TRANSFORM_FLIP_V & HWC_TRANSFORM_ROT_90;
817
818 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
819 }
820 #endif
821
TEST_F(TransactionTest,DeferredTransaction)822 TEST_F(TransactionTest, DeferredTransaction) {
823 // Synchronization surface
824 constexpr static int SYNC_LAYER = 2;
825 auto syncSurfaceControl = mComposerClient->createSurface(String8("Sync Test Surface"), 1, 1,
826 PIXEL_FORMAT_RGBA_8888, 0);
827 ASSERT_TRUE(syncSurfaceControl != nullptr);
828 ASSERT_TRUE(syncSurfaceControl->isValid());
829
830 fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY);
831
832 {
833 TransactionScope ts(*sFakeComposer);
834 ts.setLayer(syncSurfaceControl, INT32_MAX - 1);
835 ts.setPosition(syncSurfaceControl, mDisplayWidth - 2, mDisplayHeight - 2);
836 ts.show(syncSurfaceControl);
837 }
838 auto referenceFrame = mBaseFrame;
839 referenceFrame.push_back(makeSimpleRect(mDisplayWidth - 2, mDisplayHeight - 2,
840 mDisplayWidth - 1, mDisplayHeight - 1));
841 referenceFrame[SYNC_LAYER].mSwapCount = 1;
842 EXPECT_EQ(2, sFakeComposer->getFrameCount());
843 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
844
845 // set up two deferred transactions on different frames - these should not yield composited
846 // frames
847 {
848 TransactionScope ts(*sFakeComposer);
849 ts.setAlpha(mFGSurfaceControl, 0.75);
850 ts.deferTransactionUntil(mFGSurfaceControl,
851 syncSurfaceControl->getHandle(),
852 syncSurfaceControl->getSurface()->getNextFrameNumber());
853 }
854 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
855
856 {
857 TransactionScope ts(*sFakeComposer);
858 ts.setPosition(mFGSurfaceControl, 128, 128);
859 ts.deferTransactionUntil(mFGSurfaceControl,
860 syncSurfaceControl->getHandle(),
861 syncSurfaceControl->getSurface()->getNextFrameNumber() + 1);
862 }
863 EXPECT_EQ(4, sFakeComposer->getFrameCount());
864 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
865
866 // should trigger the first deferred transaction, but not the second one
867 fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY);
868 sFakeComposer->runVSyncAndWait();
869 EXPECT_EQ(5, sFakeComposer->getFrameCount());
870
871 referenceFrame[FG_LAYER].mPlaneAlpha = 0.75f;
872 referenceFrame[SYNC_LAYER].mSwapCount++;
873 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
874
875 // should show up immediately since it's not deferred
876 {
877 TransactionScope ts(*sFakeComposer);
878 ts.setAlpha(mFGSurfaceControl, 1.0);
879 }
880 referenceFrame[FG_LAYER].mPlaneAlpha = 1.f;
881 EXPECT_EQ(6, sFakeComposer->getFrameCount());
882 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
883
884 // trigger the second deferred transaction
885 fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY);
886 sFakeComposer->runVSyncAndWait();
887 // TODO: Compute from layer size?
888 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{128, 128, 128 + 64, 128 + 64};
889 referenceFrame[SYNC_LAYER].mSwapCount++;
890 EXPECT_EQ(7, sFakeComposer->getFrameCount());
891 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
892 }
893
TEST_F(TransactionTest,SetRelativeLayer)894 TEST_F(TransactionTest, SetRelativeLayer) {
895 constexpr int RELATIVE_LAYER = 2;
896 auto relativeSurfaceControl = mComposerClient->createSurface(String8("Test Surface"), 64, 64,
897 PIXEL_FORMAT_RGBA_8888, 0);
898 fillSurfaceRGBA8(relativeSurfaceControl, LIGHT_RED);
899
900 // Now we stack the surface above the foreground surface and make sure it is visible.
901 {
902 TransactionScope ts(*sFakeComposer);
903 ts.setPosition(relativeSurfaceControl, 64, 64);
904 ts.show(relativeSurfaceControl);
905 ts.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl->getHandle(), 1);
906 }
907 auto referenceFrame = mBaseFrame;
908 // NOTE: All three layers will be visible as the surfaces are
909 // transparent because of the RGBA format.
910 referenceFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64));
911 referenceFrame[RELATIVE_LAYER].mSwapCount = 1;
912 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
913
914 // A call to setLayer will override a call to setRelativeLayer
915 {
916 TransactionScope ts(*sFakeComposer);
917 ts.setLayer(relativeSurfaceControl, 0);
918 }
919
920 // Previous top layer will now appear at the bottom.
921 auto referenceFrame2 = mBaseFrame;
922 referenceFrame2.insert(referenceFrame2.begin(), referenceFrame[RELATIVE_LAYER]);
923 EXPECT_EQ(3, sFakeComposer->getFrameCount());
924 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
925 }
926
927 class ChildLayerTest : public TransactionTest {
928 protected:
929 constexpr static int CHILD_LAYER = 2;
930
SetUp()931 void SetUp() override {
932 TransactionTest::SetUp();
933 mChild = mComposerClient->createSurface(String8("Child surface"), 10, 10,
934 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
935 fillSurfaceRGBA8(mChild, LIGHT_GRAY);
936
937 sFakeComposer->runVSyncAndWait();
938 mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10));
939 mBaseFrame[CHILD_LAYER].mSwapCount = 1;
940 ASSERT_EQ(2, sFakeComposer->getFrameCount());
941 ASSERT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
942 }
TearDown()943 void TearDown() override {
944 mChild = 0;
945 TransactionTest::TearDown();
946 }
947
948 sp<SurfaceControl> mChild;
949 };
950
TEST_F(ChildLayerTest,Positioning)951 TEST_F(ChildLayerTest, Positioning) {
952 {
953 TransactionScope ts(*sFakeComposer);
954 ts.show(mChild);
955 ts.setPosition(mChild, 10, 10);
956 // Move to the same position as in the original setup.
957 ts.setPosition(mFGSurfaceControl, 64, 64);
958 }
959
960 auto referenceFrame = mBaseFrame;
961 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
962 referenceFrame[CHILD_LAYER].mDisplayFrame =
963 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
964 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
965
966 {
967 TransactionScope ts(*sFakeComposer);
968 ts.setPosition(mFGSurfaceControl, 0, 0);
969 }
970
971 auto referenceFrame2 = mBaseFrame;
972 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 64, 0 + 64};
973 referenceFrame2[CHILD_LAYER].mDisplayFrame =
974 hwc_rect_t{0 + 10, 0 + 10, 0 + 10 + 10, 0 + 10 + 10};
975 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
976 }
977
TEST_F(ChildLayerTest,Cropping)978 TEST_F(ChildLayerTest, Cropping) {
979 {
980 TransactionScope ts(*sFakeComposer);
981 ts.show(mChild);
982 ts.setPosition(mChild, 0, 0);
983 ts.setPosition(mFGSurfaceControl, 0, 0);
984 ts.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5));
985 }
986 // NOTE: The foreground surface would be occluded by the child
987 // now, but is included in the stack because the child is
988 // transparent.
989 auto referenceFrame = mBaseFrame;
990 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
991 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
992 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
993 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
994 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
995 }
996
TEST_F(ChildLayerTest,FinalCropping)997 TEST_F(ChildLayerTest, FinalCropping) {
998 {
999 TransactionScope ts(*sFakeComposer);
1000 ts.show(mChild);
1001 ts.setPosition(mChild, 0, 0);
1002 ts.setPosition(mFGSurfaceControl, 0, 0);
1003 ts.setFinalCrop(mFGSurfaceControl, Rect(0, 0, 5, 5));
1004 }
1005 auto referenceFrame = mBaseFrame;
1006 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
1007 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
1008 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
1009 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
1010 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1011 }
1012
TEST_F(ChildLayerTest,Constraints)1013 TEST_F(ChildLayerTest, Constraints) {
1014 {
1015 TransactionScope ts(*sFakeComposer);
1016 ts.show(mChild);
1017 ts.setPosition(mFGSurfaceControl, 0, 0);
1018 ts.setPosition(mChild, 63, 63);
1019 }
1020 auto referenceFrame = mBaseFrame;
1021 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1022 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{63, 63, 64, 64};
1023 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 1.f, 1.f};
1024 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1025 }
1026
TEST_F(ChildLayerTest,Scaling)1027 TEST_F(ChildLayerTest, Scaling) {
1028 {
1029 TransactionScope ts(*sFakeComposer);
1030 ts.setPosition(mFGSurfaceControl, 0, 0);
1031 }
1032 auto referenceFrame = mBaseFrame;
1033 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1034 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1035 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1036
1037 {
1038 TransactionScope ts(*sFakeComposer);
1039 ts.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0);
1040 }
1041
1042 auto referenceFrame2 = mBaseFrame;
1043 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 128, 128};
1044 referenceFrame2[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 20, 20};
1045 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1046 }
1047
TEST_F(ChildLayerTest,LayerAlpha)1048 TEST_F(ChildLayerTest, LayerAlpha) {
1049 {
1050 TransactionScope ts(*sFakeComposer);
1051 ts.show(mChild);
1052 ts.setPosition(mChild, 0, 0);
1053 ts.setPosition(mFGSurfaceControl, 0, 0);
1054 ts.setAlpha(mChild, 0.5);
1055 }
1056
1057 auto referenceFrame = mBaseFrame;
1058 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1059 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1060 referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f;
1061 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1062
1063 {
1064 TransactionScope ts(*sFakeComposer);
1065 ts.setAlpha(mFGSurfaceControl, 0.5);
1066 }
1067
1068 auto referenceFrame2 = referenceFrame;
1069 referenceFrame2[FG_LAYER].mPlaneAlpha = 0.5f;
1070 referenceFrame2[CHILD_LAYER].mPlaneAlpha = 0.25f;
1071 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1072 }
1073
TEST_F(ChildLayerTest,ReparentChildren)1074 TEST_F(ChildLayerTest, ReparentChildren) {
1075 {
1076 TransactionScope ts(*sFakeComposer);
1077 ts.show(mChild);
1078 ts.setPosition(mChild, 10, 10);
1079 ts.setPosition(mFGSurfaceControl, 64, 64);
1080 }
1081 auto referenceFrame = mBaseFrame;
1082 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1083 referenceFrame[CHILD_LAYER].mDisplayFrame =
1084 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
1085 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1086
1087 {
1088 TransactionScope ts(*sFakeComposer);
1089 ts.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle());
1090 }
1091
1092 auto referenceFrame2 = referenceFrame;
1093 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1094 referenceFrame2[CHILD_LAYER].mDisplayFrame = hwc_rect_t{10, 10, 10 + 10, 10 + 10};
1095 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1096 }
1097
TEST_F(ChildLayerTest,DetachChildren)1098 TEST_F(ChildLayerTest, DetachChildren) {
1099 {
1100 TransactionScope ts(*sFakeComposer);
1101 ts.show(mChild);
1102 ts.setPosition(mChild, 10, 10);
1103 ts.setPosition(mFGSurfaceControl, 64, 64);
1104 }
1105
1106 auto referenceFrame = mBaseFrame;
1107 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1108 referenceFrame[CHILD_LAYER].mDisplayFrame =
1109 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
1110 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1111
1112 {
1113 TransactionScope ts(*sFakeComposer);
1114 ts.detachChildren(mFGSurfaceControl);
1115 }
1116
1117 {
1118 TransactionScope ts(*sFakeComposer);
1119 ts.hide(mChild);
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(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 LatchingTest : public TransactionTest {
1221 protected:
lockAndFillFGBuffer()1222 void lockAndFillFGBuffer() { fillSurfaceRGBA8(mFGSurfaceControl, RED, false); }
1223
unlockFGBuffer()1224 void unlockFGBuffer() {
1225 sp<Surface> s = mFGSurfaceControl->getSurface();
1226 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
1227 sFakeComposer->runVSyncAndWait();
1228 }
1229
completeFGResize()1230 void completeFGResize() {
1231 fillSurfaceRGBA8(mFGSurfaceControl, RED);
1232 sFakeComposer->runVSyncAndWait();
1233 }
restoreInitialState()1234 void restoreInitialState() {
1235 TransactionScope ts(*sFakeComposer);
1236 ts.setSize(mFGSurfaceControl, 64, 64);
1237 ts.setPosition(mFGSurfaceControl, 64, 64);
1238 ts.setCrop(mFGSurfaceControl, Rect(0, 0, 64, 64));
1239 ts.setFinalCrop(mFGSurfaceControl, Rect(0, 0, -1, -1));
1240 }
1241 };
1242
TEST_F(LatchingTest,SurfacePositionLatching)1243 TEST_F(LatchingTest, SurfacePositionLatching) {
1244 // By default position can be updated even while
1245 // a resize is pending.
1246 {
1247 TransactionScope ts(*sFakeComposer);
1248 ts.setSize(mFGSurfaceControl, 32, 32);
1249 ts.setPosition(mFGSurfaceControl, 100, 100);
1250 }
1251
1252 // The size should not have updated as we have not provided a new buffer.
1253 auto referenceFrame1 = mBaseFrame;
1254 referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{100, 100, 100 + 64, 100 + 64};
1255 EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame()));
1256
1257 restoreInitialState();
1258
1259 // Now we repeat with setGeometryAppliesWithResize
1260 // and verify the position DOESN'T latch.
1261 {
1262 TransactionScope ts(*sFakeComposer);
1263 ts.setGeometryAppliesWithResize(mFGSurfaceControl);
1264 ts.setSize(mFGSurfaceControl, 32, 32);
1265 ts.setPosition(mFGSurfaceControl, 100, 100);
1266 }
1267 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1268
1269 completeFGResize();
1270
1271 auto referenceFrame2 = mBaseFrame;
1272 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{100, 100, 100 + 32, 100 + 32};
1273 referenceFrame2[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 32.f, 32.f};
1274 referenceFrame2[FG_LAYER].mSwapCount++;
1275 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1276 }
1277
TEST_F(LatchingTest,CropLatching)1278 TEST_F(LatchingTest, CropLatching) {
1279 // Normally the crop applies immediately even while a resize is pending.
1280 {
1281 TransactionScope ts(*sFakeComposer);
1282 ts.setSize(mFGSurfaceControl, 128, 128);
1283 ts.setCrop(mFGSurfaceControl, Rect(0, 0, 63, 63));
1284 }
1285
1286 auto referenceFrame1 = mBaseFrame;
1287 referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 63, 64 + 63};
1288 referenceFrame1[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 63.f, 63.f};
1289 EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame()));
1290
1291 restoreInitialState();
1292
1293 {
1294 TransactionScope ts(*sFakeComposer);
1295 ts.setSize(mFGSurfaceControl, 128, 128);
1296 ts.setGeometryAppliesWithResize(mFGSurfaceControl);
1297 ts.setCrop(mFGSurfaceControl, Rect(0, 0, 63, 63));
1298 }
1299 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1300
1301 completeFGResize();
1302
1303 auto referenceFrame2 = mBaseFrame;
1304 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 63, 64 + 63};
1305 referenceFrame2[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 63.f, 63.f};
1306 referenceFrame2[FG_LAYER].mSwapCount++;
1307 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1308 }
1309
TEST_F(LatchingTest,FinalCropLatching)1310 TEST_F(LatchingTest, FinalCropLatching) {
1311 // Normally the crop applies immediately even while a resize is pending.
1312 {
1313 TransactionScope ts(*sFakeComposer);
1314 ts.setSize(mFGSurfaceControl, 128, 128);
1315 ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127));
1316 }
1317
1318 auto referenceFrame1 = mBaseFrame;
1319 referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127};
1320 referenceFrame1[FG_LAYER].mSourceCrop =
1321 hwc_frect_t{0.f, 0.f, static_cast<float>(127 - 64), static_cast<float>(127 - 64)};
1322 EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame()));
1323
1324 restoreInitialState();
1325
1326 {
1327 TransactionScope ts(*sFakeComposer);
1328 ts.setSize(mFGSurfaceControl, 128, 128);
1329 ts.setGeometryAppliesWithResize(mFGSurfaceControl);
1330 ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127));
1331 }
1332 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1333
1334 completeFGResize();
1335
1336 auto referenceFrame2 = mBaseFrame;
1337 referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127};
1338 referenceFrame2[FG_LAYER].mSourceCrop =
1339 hwc_frect_t{0.f, 0.f, static_cast<float>(127 - 64), static_cast<float>(127 - 64)};
1340 referenceFrame2[FG_LAYER].mSwapCount++;
1341 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1342 }
1343
1344 // In this test we ensure that setGeometryAppliesWithResize actually demands
1345 // a buffer of the new size, and not just any size.
TEST_F(LatchingTest,FinalCropLatchingBufferOldSize)1346 TEST_F(LatchingTest, FinalCropLatchingBufferOldSize) {
1347 // Normally the crop applies immediately even while a resize is pending.
1348 {
1349 TransactionScope ts(*sFakeComposer);
1350 ts.setSize(mFGSurfaceControl, 128, 128);
1351 ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127));
1352 }
1353
1354 auto referenceFrame1 = mBaseFrame;
1355 referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127};
1356 referenceFrame1[FG_LAYER].mSourceCrop =
1357 hwc_frect_t{0.f, 0.f, static_cast<float>(127 - 64), static_cast<float>(127 - 64)};
1358 EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame()));
1359
1360 restoreInitialState();
1361
1362 // In order to prepare to submit a buffer at the wrong size, we acquire it prior to
1363 // initiating the resize.
1364 lockAndFillFGBuffer();
1365
1366 {
1367 TransactionScope ts(*sFakeComposer);
1368 ts.setSize(mFGSurfaceControl, 128, 128);
1369 ts.setGeometryAppliesWithResize(mFGSurfaceControl);
1370 ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127));
1371 }
1372 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1373
1374 // We now submit our old buffer, at the old size, and ensure it doesn't
1375 // trigger geometry latching.
1376 unlockFGBuffer();
1377
1378 auto referenceFrame2 = mBaseFrame;
1379 referenceFrame2[FG_LAYER].mSwapCount++;
1380 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1381
1382 completeFGResize();
1383 auto referenceFrame3 = referenceFrame2;
1384 referenceFrame3[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127};
1385 referenceFrame3[FG_LAYER].mSourceCrop =
1386 hwc_frect_t{0.f, 0.f, static_cast<float>(127 - 64), static_cast<float>(127 - 64)};
1387 referenceFrame3[FG_LAYER].mSwapCount++;
1388 EXPECT_TRUE(framesAreSame(referenceFrame3, sFakeComposer->getLatestFrame()));
1389 }
1390
TEST_F(LatchingTest,FinalCropLatchingRegressionForb37531386)1391 TEST_F(LatchingTest, FinalCropLatchingRegressionForb37531386) {
1392 // In this scenario, we attempt to set the final crop a second time while the resize
1393 // is still pending, and ensure we are successful. Success meaning the second crop
1394 // is the one which eventually latches and not the first.
1395 {
1396 TransactionScope ts(*sFakeComposer);
1397 ts.setSize(mFGSurfaceControl, 128, 128);
1398 ts.setGeometryAppliesWithResize(mFGSurfaceControl);
1399 ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127));
1400 }
1401
1402 {
1403 TransactionScope ts(*sFakeComposer);
1404 ts.setFinalCrop(mFGSurfaceControl, Rect(0, 0, -1, -1));
1405 }
1406 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1407
1408 completeFGResize();
1409
1410 auto referenceFrame = mBaseFrame;
1411 referenceFrame[FG_LAYER].mSwapCount++;
1412 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1413 }
1414
1415 } // namespace
1416
main(int argc,char ** argv)1417 int main(int argc, char** argv) {
1418 ::testing::InitGoogleTest(&argc, argv);
1419
1420 sftest::FakeHwcEnvironment* fakeEnvironment = new sftest::FakeHwcEnvironment;
1421 ::testing::AddGlobalTestEnvironment(fakeEnvironment);
1422 ::testing::InitGoogleMock(&argc, argv);
1423 return RUN_ALL_TESTS();
1424 }
1425