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. 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 } 913 void TearDown() override { 914 mChild = 0; 915 TransactionTest::TearDown(); 916 } 917 918 sp<SurfaceControl> mChild; 919 }; 920 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 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 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 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 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 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 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 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 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 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 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: 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 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 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: 1297 void lockAndFillFGBuffer() { fillSurfaceRGBA8(mFGSurfaceControl, RED, false); } 1298 1299 void unlockFGBuffer() { 1300 sp<Surface> s = mFGSurfaceControl->getSurface(); 1301 ASSERT_EQ(NO_ERROR, s->unlockAndPost()); 1302 sFakeComposer->runVSyncAndWait(); 1303 } 1304 1305 void completeFGResize() { 1306 fillSurfaceRGBA8(mFGSurfaceControl, RED); 1307 sFakeComposer->runVSyncAndWait(); 1308 } 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 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 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 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