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 "FakeComposer" 20 21 #include "FakeComposerClient.h" 22 23 #include <gui/SurfaceComposerClient.h> 24 25 #include <log/log.h> 26 27 #include <gtest/gtest.h> 28 29 #include <inttypes.h> 30 #include <time.h> 31 #include <algorithm> 32 #include <condition_variable> 33 #include <iostream> 34 #include <mutex> 35 #include <set> 36 #include <thread> 37 38 constexpr Config NULL_DISPLAY_CONFIG = static_cast<Config>(0); 39 40 using namespace sftest; 41 42 using android::Condition; 43 using android::Mutex; 44 45 using Clock = std::chrono::steady_clock; 46 using TimePoint = std::chrono::time_point<Clock>; 47 48 namespace { 49 50 // Internal state of a layer in the HWC API. 51 class LayerImpl { 52 public: 53 LayerImpl() = default; 54 55 bool mValid = true; 56 RenderState mRenderState; 57 uint32_t mZ = 0; 58 }; 59 60 // Struct for storing per frame rectangle state. Contains the render 61 // state shared to the test case. Basically a snapshot and a subset of 62 // LayerImpl sufficient to re-create the pixels of a layer for the 63 // frame. 64 struct FrameRect { 65 public: 66 FrameRect(Layer layer_, const RenderState& state, uint32_t z_) 67 : layer(layer_), renderState(state), z(z_) {} 68 69 const Layer layer; 70 const RenderState renderState; 71 const uint32_t z; 72 }; 73 74 // Collection of FrameRects forming one rendered frame. Could store 75 // related fences and other data in the future. 76 class Frame { 77 public: 78 Frame() = default; 79 std::vector<std::unique_ptr<FrameRect>> rectangles; 80 }; 81 82 class DelayedEventGenerator { 83 public: 84 explicit DelayedEventGenerator(std::function<void()> onTimerExpired) 85 : mOnTimerExpired(onTimerExpired), mThread([this]() { loop(); }) {} 86 87 ~DelayedEventGenerator() { 88 ALOGI("DelayedEventGenerator exiting."); 89 { 90 std::unique_lock<std::mutex> lock(mMutex); 91 mRunning = false; 92 mWakeups.clear(); 93 mCondition.notify_one(); 94 } 95 mThread.join(); 96 ALOGI("DelayedEventGenerator exited."); 97 } 98 99 void wakeAfter(std::chrono::nanoseconds waitTime) { 100 std::unique_lock<std::mutex> lock(mMutex); 101 mWakeups.insert(Clock::now() + waitTime); 102 mCondition.notify_one(); 103 } 104 105 private: 106 void loop() { 107 while (true) { 108 // Lock scope 109 { 110 std::unique_lock<std::mutex> lock(mMutex); 111 mCondition.wait(lock, [this]() { return !mRunning || !mWakeups.empty(); }); 112 if (!mRunning && mWakeups.empty()) { 113 // This thread should only exit once the destructor has been called and all 114 // wakeups have been processed 115 return; 116 } 117 118 // At this point, mWakeups will not be empty 119 120 TimePoint target = *(mWakeups.begin()); 121 auto status = mCondition.wait_until(lock, target); 122 while (status == std::cv_status::no_timeout) { 123 // This was either a spurious wakeup or another wakeup was added, so grab the 124 // oldest point and wait again 125 target = *(mWakeups.begin()); 126 status = mCondition.wait_until(lock, target); 127 } 128 129 // status must have been timeout, so we can finally clear this point 130 mWakeups.erase(target); 131 } 132 // Callback *without* locks! 133 mOnTimerExpired(); 134 } 135 } 136 137 std::function<void()> mOnTimerExpired; 138 std::thread mThread; 139 std::mutex mMutex; 140 std::condition_variable mCondition; 141 bool mRunning = true; 142 std::set<TimePoint> mWakeups; 143 }; 144 145 } // namespace 146 147 FakeComposerClient::FakeComposerClient() 148 : mEventCallback(nullptr), 149 mCurrentConfig(NULL_DISPLAY_CONFIG), 150 mVsyncEnabled(false), 151 mLayers(), 152 mDelayedEventGenerator( 153 std::make_unique<DelayedEventGenerator>([this]() { this->requestVSync(); })), 154 mSurfaceComposer(nullptr) {} 155 156 FakeComposerClient::~FakeComposerClient() {} 157 158 bool FakeComposerClient::hasCapability(hwc2_capability_t /*capability*/) { 159 return false; 160 } 161 162 std::string FakeComposerClient::dumpDebugInfo() { 163 return {}; 164 } 165 166 void FakeComposerClient::registerEventCallback(EventCallback* callback) { 167 ALOGV("registerEventCallback"); 168 mEventCallback = callback; 169 if (mEventCallback) { 170 mEventCallback->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED); 171 } 172 } 173 174 void FakeComposerClient::unregisterEventCallback() { 175 ALOGV("unregisterEventCallback"); 176 mEventCallback = nullptr; 177 } 178 179 void FakeComposerClient::hotplugDisplay(Display display, IComposerCallback::Connection state) { 180 if (mEventCallback) { 181 mEventCallback->onHotplug(display, state); 182 } 183 } 184 185 void FakeComposerClient::refreshDisplay(Display display) { 186 if (mEventCallback) { 187 mEventCallback->onRefresh(display); 188 } 189 } 190 191 uint32_t FakeComposerClient::getMaxVirtualDisplayCount() { 192 ALOGV("getMaxVirtualDisplayCount"); 193 return 1; 194 } 195 196 Error FakeComposerClient::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/, 197 PixelFormat* /*format*/, Display* /*outDisplay*/) { 198 ALOGV("createVirtualDisplay"); 199 return Error::NONE; 200 } 201 202 Error FakeComposerClient::destroyVirtualDisplay(Display /*display*/) { 203 ALOGV("destroyVirtualDisplay"); 204 return Error::NONE; 205 } 206 207 Error FakeComposerClient::createLayer(Display /*display*/, Layer* outLayer) { 208 ALOGV("createLayer"); 209 *outLayer = mLayers.size(); 210 auto newLayer = std::make_unique<LayerImpl>(); 211 mLayers.push_back(std::move(newLayer)); 212 return Error::NONE; 213 } 214 215 Error FakeComposerClient::destroyLayer(Display /*display*/, Layer layer) { 216 ALOGV("destroyLayer"); 217 mLayers[layer]->mValid = false; 218 return Error::NONE; 219 } 220 221 Error FakeComposerClient::getActiveConfig(Display /*display*/, Config* outConfig) { 222 ALOGV("getActiveConfig"); 223 224 // TODO Assert outConfig != nullptr 225 226 // TODO This is my reading of the 227 // IComposerClient::getActiveConfig, but returning BAD_CONFIG 228 // seems to not fit SurfaceFlinger plans. See version 2 below. 229 // if (mCurrentConfig == NULL_DISPLAY_CONFIG) { 230 // return Error::BAD_CONFIG; 231 // } 232 //*outConfig = mCurrentConfig; 233 *outConfig = 1; // Very special config for you my friend 234 return Error::NONE; 235 } 236 237 Error FakeComposerClient::getClientTargetSupport(Display /*display*/, uint32_t /*width*/, 238 uint32_t /*height*/, PixelFormat /*format*/, 239 Dataspace /*dataspace*/) { 240 ALOGV("getClientTargetSupport"); 241 return Error::NONE; 242 } 243 244 Error FakeComposerClient::getColorModes(Display /*display*/, hidl_vec<ColorMode>* /*outModes*/) { 245 ALOGV("getColorModes"); 246 return Error::NONE; 247 } 248 249 Error FakeComposerClient::getDisplayAttribute(Display display, Config config, 250 IComposerClient::Attribute attribute, 251 int32_t* outValue) { 252 ALOGV("getDisplayAttribute (%d, %d, %d, %p)", static_cast<int>(display), 253 static_cast<int>(config), static_cast<int>(attribute), outValue); 254 255 // TODO: SOOO much fun to be had with these alone 256 switch (attribute) { 257 case IComposerClient::Attribute::WIDTH: 258 *outValue = 1920; 259 break; 260 case IComposerClient::Attribute::HEIGHT: 261 *outValue = 1080; 262 break; 263 case IComposerClient::Attribute::VSYNC_PERIOD: 264 *outValue = 1666666666; 265 break; // TOOD: Tests break down if lowered to 16ms? 266 case IComposerClient::Attribute::DPI_X: 267 *outValue = 240; 268 break; 269 case IComposerClient::Attribute::DPI_Y: 270 *outValue = 240; 271 break; 272 default: 273 LOG_ALWAYS_FATAL("Say what!?! New attribute"); 274 } 275 276 return Error::NONE; 277 } 278 279 Error FakeComposerClient::getDisplayConfigs(Display /*display*/, hidl_vec<Config>* outConfigs) { 280 ALOGV("getDisplayConfigs"); 281 // TODO assert display == 1, outConfigs != nullptr 282 283 outConfigs->resize(1); 284 (*outConfigs)[0] = 1; 285 286 return Error::NONE; 287 } 288 289 Error FakeComposerClient::getDisplayName(Display /*display*/, hidl_string* /*outName*/) { 290 ALOGV("getDisplayName"); 291 return Error::NONE; 292 } 293 294 Error FakeComposerClient::getDisplayType(Display /*display*/, 295 IComposerClient::DisplayType* outType) { 296 ALOGV("getDisplayType"); 297 // TODO: This setting nothing on the output had no effect on initial trials. Is first display 298 // assumed to be physical? 299 *outType = static_cast<IComposerClient::DisplayType>(HWC2_DISPLAY_TYPE_PHYSICAL); 300 return Error::NONE; 301 } 302 303 Error FakeComposerClient::getDozeSupport(Display /*display*/, bool* /*outSupport*/) { 304 ALOGV("getDozeSupport"); 305 return Error::NONE; 306 } 307 308 Error FakeComposerClient::getHdrCapabilities(Display /*display*/, hidl_vec<Hdr>* /*outTypes*/, 309 float* /*outMaxLuminance*/, 310 float* /*outMaxAverageLuminance*/, 311 float* /*outMinLuminance*/) { 312 ALOGV("getHdrCapabilities"); 313 return Error::NONE; 314 } 315 316 Error FakeComposerClient::setActiveConfig(Display /*display*/, Config config) { 317 ALOGV("setActiveConfig"); 318 mCurrentConfig = config; 319 return Error::NONE; 320 } 321 322 Error FakeComposerClient::setColorMode(Display /*display*/, ColorMode /*mode*/) { 323 ALOGV("setColorMode"); 324 return Error::NONE; 325 } 326 327 Error FakeComposerClient::setPowerMode(Display /*display*/, IComposerClient::PowerMode /*mode*/) { 328 ALOGV("setPowerMode"); 329 return Error::NONE; 330 } 331 332 Error FakeComposerClient::setVsyncEnabled(Display /*display*/, IComposerClient::Vsync enabled) { 333 mVsyncEnabled = (enabled == IComposerClient::Vsync::ENABLE); 334 ALOGV("setVsyncEnabled(%s)", mVsyncEnabled ? "ENABLE" : "DISABLE"); 335 return Error::NONE; 336 } 337 338 Error FakeComposerClient::setColorTransform(Display /*display*/, const float* /*matrix*/, 339 int32_t /*hint*/) { 340 ALOGV("setColorTransform"); 341 return Error::NONE; 342 } 343 344 Error FakeComposerClient::setClientTarget(Display /*display*/, buffer_handle_t /*target*/, 345 int32_t /*acquireFence*/, int32_t /*dataspace*/, 346 const std::vector<hwc_rect_t>& /*damage*/) { 347 ALOGV("setClientTarget"); 348 return Error::NONE; 349 } 350 351 Error FakeComposerClient::setOutputBuffer(Display /*display*/, buffer_handle_t /*buffer*/, 352 int32_t /*releaseFence*/) { 353 ALOGV("setOutputBuffer"); 354 return Error::NONE; 355 } 356 357 Error FakeComposerClient::validateDisplay( 358 Display /*display*/, std::vector<Layer>* /*outChangedLayers*/, 359 std::vector<IComposerClient::Composition>* /*outCompositionTypes*/, 360 uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/, 361 std::vector<uint32_t>* /*outRequestMasks*/) { 362 ALOGV("validateDisplay"); 363 // TODO: Assume touching nothing means All Korrekt! 364 return Error::NONE; 365 } 366 367 Error FakeComposerClient::acceptDisplayChanges(Display /*display*/) { 368 ALOGV("acceptDisplayChanges"); 369 // Didn't ask for changes because software is omnipotent. 370 return Error::NONE; 371 } 372 373 bool layerZOrdering(const std::unique_ptr<FrameRect>& a, const std::unique_ptr<FrameRect>& b) { 374 return a->z <= b->z; 375 } 376 377 Error FakeComposerClient::presentDisplay(Display /*display*/, int32_t* /*outPresentFence*/, 378 std::vector<Layer>* /*outLayers*/, 379 std::vector<int32_t>* /*outReleaseFences*/) { 380 ALOGV("presentDisplay"); 381 // TODO Leaving layers and their fences out for now. Doing so 382 // means that we've already processed everything. Important to 383 // test that the fences are respected, though. (How?) 384 385 std::unique_ptr<Frame> newFrame(new Frame); 386 for (uint64_t layer = 0; layer < mLayers.size(); layer++) { 387 const LayerImpl& layerImpl = *mLayers[layer]; 388 389 if (!layerImpl.mValid) continue; 390 391 auto rect = std::make_unique<FrameRect>(layer, layerImpl.mRenderState, layerImpl.mZ); 392 newFrame->rectangles.push_back(std::move(rect)); 393 } 394 std::sort(newFrame->rectangles.begin(), newFrame->rectangles.end(), layerZOrdering); 395 { 396 Mutex::Autolock _l(mStateMutex); 397 mFrames.push_back(std::move(newFrame)); 398 mFramesAvailable.broadcast(); 399 } 400 return Error::NONE; 401 } 402 403 Error FakeComposerClient::setLayerCursorPosition(Display /*display*/, Layer /*layer*/, 404 int32_t /*x*/, int32_t /*y*/) { 405 ALOGV("setLayerCursorPosition"); 406 return Error::NONE; 407 } 408 409 Error FakeComposerClient::setLayerBuffer(Display /*display*/, Layer layer, buffer_handle_t buffer, 410 int32_t acquireFence) { 411 ALOGV("setLayerBuffer"); 412 LayerImpl& l = getLayerImpl(layer); 413 if (buffer != l.mRenderState.mBuffer) { 414 l.mRenderState.mSwapCount++; // TODO: Is setting to same value a swap or not? 415 } 416 l.mRenderState.mBuffer = buffer; 417 l.mRenderState.mAcquireFence = acquireFence; 418 419 return Error::NONE; 420 } 421 422 Error FakeComposerClient::setLayerSurfaceDamage(Display /*display*/, Layer /*layer*/, 423 const std::vector<hwc_rect_t>& /*damage*/) { 424 ALOGV("setLayerSurfaceDamage"); 425 return Error::NONE; 426 } 427 428 Error FakeComposerClient::setLayerBlendMode(Display /*display*/, Layer layer, int32_t mode) { 429 ALOGV("setLayerBlendMode"); 430 getLayerImpl(layer).mRenderState.mBlendMode = static_cast<hwc2_blend_mode_t>(mode); 431 return Error::NONE; 432 } 433 434 Error FakeComposerClient::setLayerColor(Display /*display*/, Layer layer, 435 IComposerClient::Color color) { 436 ALOGV("setLayerColor"); 437 getLayerImpl(layer).mRenderState.mLayerColor.r = color.r; 438 getLayerImpl(layer).mRenderState.mLayerColor.g = color.g; 439 getLayerImpl(layer).mRenderState.mLayerColor.b = color.b; 440 getLayerImpl(layer).mRenderState.mLayerColor.a = color.a; 441 return Error::NONE; 442 } 443 444 Error FakeComposerClient::setLayerCompositionType(Display /*display*/, Layer /*layer*/, 445 int32_t /*type*/) { 446 ALOGV("setLayerCompositionType"); 447 return Error::NONE; 448 } 449 450 Error FakeComposerClient::setLayerDataspace(Display /*display*/, Layer /*layer*/, 451 int32_t /*dataspace*/) { 452 ALOGV("setLayerDataspace"); 453 return Error::NONE; 454 } 455 456 Error FakeComposerClient::setLayerDisplayFrame(Display /*display*/, Layer layer, 457 const hwc_rect_t& frame) { 458 ALOGV("setLayerDisplayFrame (%d, %d, %d, %d)", frame.left, frame.top, frame.right, 459 frame.bottom); 460 getLayerImpl(layer).mRenderState.mDisplayFrame = frame; 461 return Error::NONE; 462 } 463 464 Error FakeComposerClient::setLayerPlaneAlpha(Display /*display*/, Layer layer, float alpha) { 465 ALOGV("setLayerPlaneAlpha"); 466 getLayerImpl(layer).mRenderState.mPlaneAlpha = alpha; 467 return Error::NONE; 468 } 469 470 Error FakeComposerClient::setLayerSidebandStream(Display /*display*/, Layer /*layer*/, 471 buffer_handle_t /*stream*/) { 472 ALOGV("setLayerSidebandStream"); 473 return Error::NONE; 474 } 475 476 Error FakeComposerClient::setLayerSourceCrop(Display /*display*/, Layer layer, 477 const hwc_frect_t& crop) { 478 ALOGV("setLayerSourceCrop"); 479 getLayerImpl(layer).mRenderState.mSourceCrop = crop; 480 return Error::NONE; 481 } 482 483 Error FakeComposerClient::setLayerTransform(Display /*display*/, Layer layer, int32_t transform) { 484 ALOGV("setLayerTransform"); 485 getLayerImpl(layer).mRenderState.mTransform = static_cast<hwc_transform_t>(transform); 486 return Error::NONE; 487 } 488 489 Error FakeComposerClient::setLayerVisibleRegion(Display /*display*/, Layer layer, 490 const std::vector<hwc_rect_t>& visible) { 491 ALOGV("setLayerVisibleRegion"); 492 getLayerImpl(layer).mRenderState.mVisibleRegion = visible; 493 return Error::NONE; 494 } 495 496 Error FakeComposerClient::setLayerZOrder(Display /*display*/, Layer layer, uint32_t z) { 497 ALOGV("setLayerZOrder"); 498 getLayerImpl(layer).mZ = z; 499 return Error::NONE; 500 } 501 502 ////////////////////////////////////////////////////////////////// 503 504 void FakeComposerClient::requestVSync(uint64_t vsyncTime) { 505 if (mEventCallback) { 506 uint64_t timestamp = vsyncTime; 507 ALOGV("Vsync"); 508 if (timestamp == 0) { 509 struct timespec ts; 510 clock_gettime(CLOCK_MONOTONIC, &ts); 511 timestamp = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; 512 } 513 if (mSurfaceComposer != nullptr) { 514 mSurfaceComposer->injectVSync(timestamp); 515 } else { 516 mEventCallback->onVsync(PRIMARY_DISPLAY, timestamp); 517 } 518 } 519 } 520 521 void FakeComposerClient::runVSyncAfter(std::chrono::nanoseconds wait) { 522 mDelayedEventGenerator->wakeAfter(wait); 523 } 524 525 LayerImpl& FakeComposerClient::getLayerImpl(Layer handle) { 526 // TODO Change these to an internal state check that can be 527 // invoked from the gtest? GTest macros do not seem all that safe 528 // when used outside the test class 529 EXPECT_GE(handle, static_cast<Layer>(0)); 530 EXPECT_LT(handle, mLayers.size()); 531 return *(mLayers[handle]); 532 } 533 534 int FakeComposerClient::getFrameCount() const { 535 return mFrames.size(); 536 } 537 538 static std::vector<RenderState> extractRenderState( 539 const std::vector<std::unique_ptr<FrameRect>>& internalRects) { 540 std::vector<RenderState> result; 541 result.reserve(internalRects.size()); 542 for (const std::unique_ptr<FrameRect>& rect : internalRects) { 543 result.push_back(rect->renderState); 544 } 545 return result; 546 } 547 548 std::vector<RenderState> FakeComposerClient::getFrameRects(int frame) const { 549 Mutex::Autolock _l(mStateMutex); 550 return extractRenderState(mFrames[frame]->rectangles); 551 } 552 553 std::vector<RenderState> FakeComposerClient::getLatestFrame() const { 554 Mutex::Autolock _l(mStateMutex); 555 return extractRenderState(mFrames[mFrames.size() - 1]->rectangles); 556 } 557 558 void FakeComposerClient::runVSyncAndWait(std::chrono::nanoseconds maxWait) { 559 int currentFrame = 0; 560 { 561 Mutex::Autolock _l(mStateMutex); // I hope this is ok... 562 currentFrame = static_cast<int>(mFrames.size()); 563 requestVSync(); 564 } 565 waitUntilFrame(currentFrame + 1, maxWait); 566 } 567 568 void FakeComposerClient::waitUntilFrame(int targetFrame, std::chrono::nanoseconds maxWait) const { 569 Mutex::Autolock _l(mStateMutex); 570 while (mFrames.size() < static_cast<size_t>(targetFrame)) { 571 android::status_t result = mFramesAvailable.waitRelative(mStateMutex, maxWait.count()); 572 if (result == android::TIMED_OUT) { 573 ALOGE("Waiting for frame %d (at frame %zu now) timed out after %lld ns", targetFrame, 574 mFrames.size(), maxWait.count()); 575 return; 576 } 577 } 578 } 579 580 void FakeComposerClient::clearFrames() { 581 Mutex::Autolock _l(mStateMutex); 582 mFrames.clear(); 583 for (const std::unique_ptr<LayerImpl>& layer : mLayers) { 584 if (layer->mValid) { 585 layer->mRenderState.mSwapCount = 0; 586 } 587 } 588 } 589 590 void FakeComposerClient::onSurfaceFlingerStart() { 591 mSurfaceComposer = nullptr; 592 do { 593 mSurfaceComposer = new android::SurfaceComposerClient; 594 android::status_t initResult = mSurfaceComposer->initCheck(); 595 if (initResult != android::NO_ERROR) { 596 ALOGD("Init result: %d", initResult); 597 mSurfaceComposer = nullptr; 598 std::this_thread::sleep_for(10ms); 599 } 600 } while (mSurfaceComposer == nullptr); 601 ALOGD("SurfaceComposerClient created"); 602 mSurfaceComposer->enableVSyncInjections(true); 603 } 604 605 void FakeComposerClient::onSurfaceFlingerStop() { 606 mSurfaceComposer->dispose(); 607 mSurfaceComposer.clear(); 608 } 609 610 // Includes destroyed layers, stored in order of creation. 611 int FakeComposerClient::getLayerCount() const { 612 return mLayers.size(); 613 } 614 615 Layer FakeComposerClient::getLayer(size_t index) const { 616 // NOTE: If/when passing calls through to actual implementation, 617 // this might get more involving. 618 return static_cast<Layer>(index); 619 } 620