hardware_composer.cpp revision fac407407e30c70da44a7a8ae1b13bf1ef9c05b7
1#include "hardware_composer.h" 2 3#include <cutils/properties.h> 4#include <cutils/sched_policy.h> 5#include <fcntl.h> 6#include <log/log.h> 7#include <poll.h> 8#include <sync/sync.h> 9#include <sys/eventfd.h> 10#include <sys/prctl.h> 11#include <sys/resource.h> 12#include <sys/system_properties.h> 13#include <sys/timerfd.h> 14#include <time.h> 15#include <unistd.h> 16#include <utils/Trace.h> 17 18#include <algorithm> 19#include <chrono> 20#include <functional> 21#include <map> 22 23#include <dvr/dvr_display_types.h> 24#include <dvr/performance_client_api.h> 25#include <private/dvr/clock_ns.h> 26#include <private/dvr/ion_buffer.h> 27#include <private/dvr/pose_client_internal.h> 28 29using android::pdx::LocalHandle; 30using android::pdx::rpc::EmptyVariant; 31using android::pdx::rpc::IfAnyOf; 32 33using namespace std::chrono_literals; 34 35namespace android { 36namespace dvr { 37 38namespace { 39 40// If the number of pending fences goes over this count at the point when we 41// are about to submit a new frame to HWC, we will drop the frame. This should 42// be a signal that the display driver has begun queuing frames. Note that with 43// smart displays (with RAM), the fence is signaled earlier than the next vsync, 44// at the point when the DMA to the display completes. Currently we use a smart 45// display and the EDS timing coincides with zero pending fences, so this is 0. 46constexpr int kAllowedPendingFenceCount = 0; 47 48// Offset before vsync to submit frames to hardware composer. 49constexpr int64_t kFramePostOffsetNs = 4000000; // 4ms 50 51const char kBacklightBrightnessSysFile[] = 52 "/sys/class/leds/lcd-backlight/brightness"; 53 54const char kPrimaryDisplayVSyncEventFile[] = 55 "/sys/class/graphics/fb0/vsync_event"; 56 57const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp"; 58 59const char kDvrPerformanceProperty[] = "sys.dvr.performance"; 60 61const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns"; 62 63// Get time offset from a vsync to when the pose for that vsync should be 64// predicted out to. For example, if scanout gets halfway through the frame 65// at the halfway point between vsyncs, then this could be half the period. 66// With global shutter displays, this should be changed to the offset to when 67// illumination begins. Low persistence adds a frame of latency, so we predict 68// to the center of the next frame. 69inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) { 70 return (vsync_period_ns * 150) / 100; 71} 72 73// Attempts to set the scheduler class and partiton for the current thread. 74// Returns true on success or false on failure. 75bool SetThreadPolicy(const std::string& scheduler_class, 76 const std::string& partition) { 77 int error = dvrSetSchedulerClass(0, scheduler_class.c_str()); 78 if (error < 0) { 79 ALOGE( 80 "SetThreadPolicy: Failed to set scheduler class \"%s\" for " 81 "thread_id=%d: %s", 82 scheduler_class.c_str(), gettid(), strerror(-error)); 83 return false; 84 } 85 error = dvrSetCpuPartition(0, partition.c_str()); 86 if (error < 0) { 87 ALOGE( 88 "SetThreadPolicy: Failed to set cpu partiton \"%s\" for thread_id=%d: " 89 "%s", 90 partition.c_str(), gettid(), strerror(-error)); 91 return false; 92 } 93 return true; 94} 95 96} // anonymous namespace 97 98// Layer static data. 99Hwc2::Composer* Layer::hwc2_hidl_; 100const HWCDisplayMetrics* Layer::display_metrics_; 101 102// HardwareComposer static data; 103constexpr size_t HardwareComposer::kMaxHardwareLayers; 104 105HardwareComposer::HardwareComposer() 106 : HardwareComposer(nullptr, RequestDisplayCallback()) {} 107 108HardwareComposer::HardwareComposer( 109 Hwc2::Composer* hwc2_hidl, RequestDisplayCallback request_display_callback) 110 : initialized_(false), 111 hwc2_hidl_(hwc2_hidl), 112 request_display_callback_(request_display_callback), 113 callbacks_(new ComposerCallback) {} 114 115HardwareComposer::~HardwareComposer(void) { 116 UpdatePostThreadState(PostThreadState::Quit, true); 117 if (post_thread_.joinable()) 118 post_thread_.join(); 119} 120 121bool HardwareComposer::Initialize() { 122 if (initialized_) { 123 ALOGE("HardwareComposer::Initialize: already initialized."); 124 return false; 125 } 126 127 HWC::Error error = HWC::Error::None; 128 129 Hwc2::Config config; 130 error = hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config); 131 132 if (error != HWC::Error::None) { 133 ALOGE("HardwareComposer: Failed to get current display config : %d", 134 config); 135 return false; 136 } 137 138 error = 139 GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_); 140 141 if (error != HWC::Error::None) { 142 ALOGE( 143 "HardwareComposer: Failed to get display attributes for current " 144 "configuration : %d", 145 error.value); 146 return false; 147 } 148 149 ALOGI( 150 "HardwareComposer: primary display attributes: width=%d height=%d " 151 "vsync_period_ns=%d DPI=%dx%d", 152 native_display_metrics_.width, native_display_metrics_.height, 153 native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x, 154 native_display_metrics_.dpi.y); 155 156 // Set the display metrics but never use rotation to avoid the long latency of 157 // rotation processing in hwc. 158 display_transform_ = HWC_TRANSFORM_NONE; 159 display_metrics_ = native_display_metrics_; 160 161 // Pass hwc instance and metrics to setup globals for Layer. 162 Layer::InitializeGlobals(hwc2_hidl_, &native_display_metrics_); 163 164 post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 165 LOG_ALWAYS_FATAL_IF( 166 !post_thread_event_fd_, 167 "HardwareComposer: Failed to create interrupt event fd : %s", 168 strerror(errno)); 169 170 post_thread_ = std::thread(&HardwareComposer::PostThread, this); 171 172 initialized_ = true; 173 174 return initialized_; 175} 176 177void HardwareComposer::Enable() { 178 UpdatePostThreadState(PostThreadState::Suspended, false); 179} 180 181void HardwareComposer::Disable() { 182 UpdatePostThreadState(PostThreadState::Suspended, true); 183} 184 185// Update the post thread quiescent state based on idle and suspended inputs. 186void HardwareComposer::UpdatePostThreadState(PostThreadStateType state, 187 bool suspend) { 188 std::unique_lock<std::mutex> lock(post_thread_mutex_); 189 190 // Update the votes in the state variable before evaluating the effective 191 // quiescent state. Any bits set in post_thread_state_ indicate that the post 192 // thread should be suspended. 193 if (suspend) { 194 post_thread_state_ |= state; 195 } else { 196 post_thread_state_ &= ~state; 197 } 198 199 const bool quit = post_thread_state_ & PostThreadState::Quit; 200 const bool effective_suspend = post_thread_state_ != PostThreadState::Active; 201 if (quit) { 202 post_thread_quiescent_ = true; 203 eventfd_write(post_thread_event_fd_.Get(), 1); 204 post_thread_wait_.notify_one(); 205 } else if (effective_suspend && !post_thread_quiescent_) { 206 post_thread_quiescent_ = true; 207 eventfd_write(post_thread_event_fd_.Get(), 1); 208 } else if (!effective_suspend && post_thread_quiescent_) { 209 post_thread_quiescent_ = false; 210 eventfd_t value; 211 eventfd_read(post_thread_event_fd_.Get(), &value); 212 post_thread_wait_.notify_one(); 213 } 214 215 // Wait until the post thread is in the requested state. 216 post_thread_ready_.wait(lock, [this, effective_suspend] { 217 return effective_suspend != post_thread_resumed_; 218 }); 219} 220 221void HardwareComposer::OnPostThreadResumed() { 222 hwc2_hidl_->resetCommands(); 223 224 // Connect to pose service. 225 pose_client_ = dvrPoseCreate(); 226 ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client"); 227 228 // HIDL HWC seems to have an internal race condition. If we submit a frame too 229 // soon after turning on VSync we don't get any VSync signals. Give poor HWC 230 // implementations a chance to enable VSync before we continue. 231 EnableVsync(false); 232 std::this_thread::sleep_for(100ms); 233 EnableVsync(true); 234 std::this_thread::sleep_for(100ms); 235 236 // TODO(skiazyk): We need to do something about accessing this directly, 237 // supposedly there is a backlight service on the way. 238 // TODO(steventhomas): When we change the backlight setting, will surface 239 // flinger (or something else) set it back to its original value once we give 240 // control of the display back to surface flinger? 241 SetBacklightBrightness(255); 242 243 // Trigger target-specific performance mode change. 244 property_set(kDvrPerformanceProperty, "performance"); 245} 246 247void HardwareComposer::OnPostThreadPaused() { 248 retire_fence_fds_.clear(); 249 display_surfaces_.clear(); 250 251 for (size_t i = 0; i < kMaxHardwareLayers; ++i) { 252 layers_[i].Reset(); 253 } 254 active_layer_count_ = 0; 255 256 if (pose_client_) { 257 dvrPoseDestroy(pose_client_); 258 pose_client_ = nullptr; 259 } 260 261 EnableVsync(false); 262 263 hwc2_hidl_->resetCommands(); 264 265 // Trigger target-specific performance mode change. 266 property_set(kDvrPerformanceProperty, "idle"); 267} 268 269HWC::Error HardwareComposer::Validate(hwc2_display_t display) { 270 uint32_t num_types; 271 uint32_t num_requests; 272 HWC::Error error = 273 hwc2_hidl_->validateDisplay(display, &num_types, &num_requests); 274 275 if (error == HWC2_ERROR_HAS_CHANGES) { 276 // TODO(skiazyk): We might need to inspect the requested changes first, but 277 // so far it seems like we shouldn't ever hit a bad state. 278 // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_, 279 // display); 280 error = hwc2_hidl_->acceptDisplayChanges(display); 281 } 282 283 return error; 284} 285 286int32_t HardwareComposer::EnableVsync(bool enabled) { 287 return (int32_t)hwc2_hidl_->setVsyncEnabled( 288 HWC_DISPLAY_PRIMARY, 289 (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE 290 : HWC2_VSYNC_DISABLE)); 291} 292 293HWC::Error HardwareComposer::Present(hwc2_display_t display) { 294 int32_t present_fence; 295 HWC::Error error = hwc2_hidl_->presentDisplay(display, &present_fence); 296 297 // According to the documentation, this fence is signaled at the time of 298 // vsync/DMA for physical displays. 299 if (error == HWC::Error::None) { 300 ATRACE_INT("HardwareComposer: VsyncFence", present_fence); 301 retire_fence_fds_.emplace_back(present_fence); 302 } else { 303 ATRACE_INT("HardwareComposer: PresentResult", error); 304 } 305 306 return error; 307} 308 309HWC::Error HardwareComposer::GetDisplayAttribute(hwc2_display_t display, 310 hwc2_config_t config, 311 hwc2_attribute_t attribute, 312 int32_t* out_value) const { 313 return hwc2_hidl_->getDisplayAttribute( 314 display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value); 315} 316 317HWC::Error HardwareComposer::GetDisplayMetrics( 318 hwc2_display_t display, hwc2_config_t config, 319 HWCDisplayMetrics* out_metrics) const { 320 HWC::Error error; 321 322 error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH, 323 &out_metrics->width); 324 if (error != HWC::Error::None) { 325 ALOGE( 326 "HardwareComposer::GetDisplayMetrics: Failed to get display width: %s", 327 error.to_string().c_str()); 328 return error; 329 } 330 331 error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT, 332 &out_metrics->height); 333 if (error != HWC::Error::None) { 334 ALOGE( 335 "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s", 336 error.to_string().c_str()); 337 return error; 338 } 339 340 error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD, 341 &out_metrics->vsync_period_ns); 342 if (error != HWC::Error::None) { 343 ALOGE( 344 "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s", 345 error.to_string().c_str()); 346 return error; 347 } 348 349 error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X, 350 &out_metrics->dpi.x); 351 if (error != HWC::Error::None) { 352 ALOGE( 353 "HardwareComposer::GetDisplayMetrics: Failed to get display DPI X: %s", 354 error.to_string().c_str()); 355 return error; 356 } 357 358 error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y, 359 &out_metrics->dpi.y); 360 if (error != HWC::Error::None) { 361 ALOGE( 362 "HardwareComposer::GetDisplayMetrics: Failed to get display DPI Y: %s", 363 error.to_string().c_str()); 364 return error; 365 } 366 367 return HWC::Error::None; 368} 369 370std::string HardwareComposer::Dump() { return hwc2_hidl_->dumpDebugInfo(); } 371 372void HardwareComposer::PostLayers() { 373 ATRACE_NAME("HardwareComposer::PostLayers"); 374 375 // Setup the hardware composer layers with current buffers. 376 for (size_t i = 0; i < active_layer_count_; i++) { 377 layers_[i].Prepare(); 378 } 379 380 HWC::Error error = Validate(HWC_DISPLAY_PRIMARY); 381 if (error != HWC::Error::None) { 382 ALOGE("HardwareComposer::PostLayers: Validate failed: %s", 383 error.to_string().c_str()); 384 return; 385 } 386 387 // Now that we have taken in a frame from the application, we have a chance 388 // to drop the frame before passing the frame along to HWC. 389 // If the display driver has become backed up, we detect it here and then 390 // react by skipping this frame to catch up latency. 391 while (!retire_fence_fds_.empty() && 392 (!retire_fence_fds_.front() || 393 sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) { 394 // There are only 2 fences in here, no performance problem to shift the 395 // array of ints. 396 retire_fence_fds_.erase(retire_fence_fds_.begin()); 397 } 398 399 const bool is_frame_pending = IsFramePendingInDriver(); 400 const bool is_fence_pending = 401 retire_fence_fds_.size() > kAllowedPendingFenceCount; 402 403 if (is_fence_pending || is_frame_pending) { 404 ATRACE_INT("frame_skip_count", ++frame_skip_count_); 405 406 ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame"); 407 ALOGW_IF(is_fence_pending, 408 "Warning: dropping a frame to catch up with HWC (pending = %zd)", 409 retire_fence_fds_.size()); 410 411 for (size_t i = 0; i < active_layer_count_; i++) { 412 layers_[i].Drop(); 413 } 414 return; 415 } else { 416 // Make the transition more obvious in systrace when the frame skip happens 417 // above. 418 ATRACE_INT("frame_skip_count", 0); 419 } 420 421#if TRACE 422 for (size_t i = 0; i < active_layer_count_; i++) 423 ALOGI("HardwareComposer::PostLayers: layer=%zu composition=%s", i, 424 layers_[i].GetCompositionType().to_string().c_str()); 425#endif 426 427 error = Present(HWC_DISPLAY_PRIMARY); 428 if (error != HWC::Error::None) { 429 ALOGE("HardwareComposer::PostLayers: Present failed: %s", 430 error.to_string().c_str()); 431 return; 432 } 433 434 std::vector<Hwc2::Layer> out_layers; 435 std::vector<int> out_fences; 436 error = hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers, 437 &out_fences); 438 ALOGE_IF(error != HWC::Error::None, 439 "HardwareComposer::PostLayers: Failed to get release fences: %s", 440 error.to_string().c_str()); 441 442 // Perform post-frame bookkeeping. Unused layers are a no-op. 443 uint32_t num_elements = out_layers.size(); 444 for (size_t i = 0; i < num_elements; ++i) { 445 for (size_t j = 0; j < active_layer_count_; ++j) { 446 if (layers_[j].GetLayerHandle() == out_layers[i]) { 447 layers_[j].Finish(out_fences[i]); 448 } 449 } 450 } 451} 452 453void HardwareComposer::SetDisplaySurfaces( 454 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces) { 455 ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd", 456 surfaces.size()); 457 const bool display_idle = surfaces.size() == 0; 458 { 459 std::unique_lock<std::mutex> lock(post_thread_mutex_); 460 pending_surfaces_ = std::move(surfaces); 461 } 462 463 // Set idle state based on whether there are any surfaces to handle. 464 UpdatePostThreadState(PostThreadState::Idle, display_idle); 465 466 // XXX: TEMPORARY 467 // Request control of the display based on whether there are any surfaces to 468 // handle. This callback sets the post thread active state once the transition 469 // is complete in SurfaceFlinger. 470 // TODO(eieio): Unify the control signal used to move SurfaceFlinger into VR 471 // mode. Currently this is hooked up to persistent VR mode, but perhaps this 472 // makes more sense to control it from VrCore, which could in turn base its 473 // decision on persistent VR mode. 474 if (request_display_callback_) 475 request_display_callback_(!display_idle); 476} 477 478int HardwareComposer::PostThreadPollInterruptible( 479 const pdx::LocalHandle& event_fd, int requested_events) { 480 pollfd pfd[2] = { 481 { 482 .fd = event_fd.Get(), 483 .events = static_cast<short>(requested_events), 484 .revents = 0, 485 }, 486 { 487 .fd = post_thread_event_fd_.Get(), 488 .events = POLLPRI | POLLIN, 489 .revents = 0, 490 }, 491 }; 492 int ret, error; 493 do { 494 ret = poll(pfd, 2, -1); 495 error = errno; 496 ALOGW_IF(ret < 0, 497 "HardwareComposer::PostThreadPollInterruptible: Error during " 498 "poll(): %s (%d)", 499 strerror(error), error); 500 } while (ret < 0 && error == EINTR); 501 502 if (ret < 0) { 503 return -error; 504 } else if (pfd[0].revents != 0) { 505 return 0; 506 } else if (pfd[1].revents != 0) { 507 ALOGI("VrHwcPost thread interrupted"); 508 return kPostThreadInterrupted; 509 } else { 510 return 0; 511 } 512} 513 514// Reads the value of the display driver wait_pingpong state. Returns 0 or 1 515// (the value of the state) on success or a negative error otherwise. 516// TODO(eieio): This is pretty driver specific, this should be moved to a 517// separate class eventually. 518int HardwareComposer::ReadWaitPPState() { 519 // Gracefully handle when the kernel does not support this feature. 520 if (!primary_display_wait_pp_fd_) 521 return 0; 522 523 const int wait_pp_fd = primary_display_wait_pp_fd_.Get(); 524 int ret, error; 525 526 ret = lseek(wait_pp_fd, 0, SEEK_SET); 527 if (ret < 0) { 528 error = errno; 529 ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s", 530 strerror(error)); 531 return -error; 532 } 533 534 char data = -1; 535 ret = read(wait_pp_fd, &data, sizeof(data)); 536 if (ret < 0) { 537 error = errno; 538 ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s", 539 strerror(error)); 540 return -error; 541 } 542 543 switch (data) { 544 case '0': 545 return 0; 546 case '1': 547 return 1; 548 default: 549 ALOGE( 550 "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d", 551 data); 552 return -EINVAL; 553 } 554} 555 556// Reads the timestamp of the last vsync from the display driver. 557// TODO(eieio): This is pretty driver specific, this should be moved to a 558// separate class eventually. 559int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) { 560 const int event_fd = primary_display_vsync_event_fd_.Get(); 561 int ret, error; 562 563 // The driver returns data in the form "VSYNC=<timestamp ns>". 564 std::array<char, 32> data; 565 data.fill('\0'); 566 567 // Seek back to the beginning of the event file. 568 ret = lseek(event_fd, 0, SEEK_SET); 569 if (ret < 0) { 570 error = errno; 571 ALOGE( 572 "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: " 573 "%s", 574 strerror(error)); 575 return -error; 576 } 577 578 // Read the vsync event timestamp. 579 ret = read(event_fd, data.data(), data.size()); 580 if (ret < 0) { 581 error = errno; 582 ALOGE_IF( 583 error != EAGAIN, 584 "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: " 585 "%s", 586 strerror(error)); 587 return -error; 588 } 589 590 ret = sscanf(data.data(), "VSYNC=%" PRIu64, 591 reinterpret_cast<uint64_t*>(timestamp)); 592 if (ret < 0) { 593 error = errno; 594 ALOGE( 595 "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: " 596 "%s", 597 strerror(error)); 598 return -error; 599 } 600 601 return 0; 602} 603 604// Blocks until the next vsync event is signaled by the display driver. 605// TODO(eieio): This is pretty driver specific, this should be moved to a 606// separate class eventually. 607int HardwareComposer::BlockUntilVSync() { 608 // Vsync is signaled by POLLPRI on the fb vsync node. 609 return PostThreadPollInterruptible(primary_display_vsync_event_fd_, POLLPRI); 610} 611 612// Waits for the next vsync and returns the timestamp of the vsync event. If 613// vsync already passed since the last call, returns the latest vsync timestamp 614// instead of blocking. This method updates the last_vsync_timeout_ in the 615// process. 616// 617// TODO(eieio): This is pretty driver specific, this should be moved to a 618// separate class eventually. 619int HardwareComposer::WaitForVSync(int64_t* timestamp) { 620 int error; 621 622 // Get the current timestamp and decide what to do. 623 while (true) { 624 int64_t current_vsync_timestamp; 625 error = ReadVSyncTimestamp(¤t_vsync_timestamp); 626 if (error < 0 && error != -EAGAIN) 627 return error; 628 629 if (error == -EAGAIN) { 630 // Vsync was turned off, wait for the next vsync event. 631 error = BlockUntilVSync(); 632 if (error < 0 || error == kPostThreadInterrupted) 633 return error; 634 635 // Try again to get the timestamp for this new vsync interval. 636 continue; 637 } 638 639 // Check that we advanced to a later vsync interval. 640 if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) { 641 *timestamp = last_vsync_timestamp_ = current_vsync_timestamp; 642 return 0; 643 } 644 645 // See how close we are to the next expected vsync. If we're within 1ms, 646 // sleep for 1ms and try again. 647 const int64_t ns_per_frame = display_metrics_.vsync_period_ns; 648 const int64_t threshold_ns = 1000000; // 1ms 649 650 const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame; 651 const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs(); 652 653 if (distance_to_vsync_est > threshold_ns) { 654 // Wait for vsync event notification. 655 error = BlockUntilVSync(); 656 if (error < 0 || error == kPostThreadInterrupted) 657 return error; 658 } else { 659 // Sleep for a short time (1 millisecond) before retrying. 660 error = SleepUntil(GetSystemClockNs() + threshold_ns); 661 if (error < 0 || error == kPostThreadInterrupted) 662 return error; 663 } 664 } 665} 666 667int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) { 668 const int timer_fd = vsync_sleep_timer_fd_.Get(); 669 const itimerspec wakeup_itimerspec = { 670 .it_interval = {.tv_sec = 0, .tv_nsec = 0}, 671 .it_value = NsToTimespec(wakeup_timestamp), 672 }; 673 int ret = 674 timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr); 675 int error = errno; 676 if (ret < 0) { 677 ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s", 678 strerror(error)); 679 return -error; 680 } 681 682 return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN); 683} 684 685void HardwareComposer::PostThread() { 686 // NOLINTNEXTLINE(runtime/int) 687 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0); 688 689 // Set the scheduler to SCHED_FIFO with high priority. If this fails here 690 // there may have been a startup timing issue between this thread and 691 // performanced. Try again later when this thread becomes active. 692 bool thread_policy_setup = 693 SetThreadPolicy("graphics:high", "/system/performance"); 694 695#if ENABLE_BACKLIGHT_BRIGHTNESS 696 // TODO(hendrikw): This isn't required at the moment. It's possible that there 697 // is another method to access this when needed. 698 // Open the backlight brightness control sysfs node. 699 backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR); 700 ALOGW_IF(!backlight_brightness_fd_, 701 "HardwareComposer: Failed to open backlight brightness control: %s", 702 strerror(errno)); 703#endif // ENABLE_BACKLIGHT_BRIGHTNESS 704 705 // Open the vsync event node for the primary display. 706 // TODO(eieio): Move this into a platform-specific class. 707 primary_display_vsync_event_fd_ = 708 LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY); 709 ALOGE_IF(!primary_display_vsync_event_fd_, 710 "HardwareComposer: Failed to open vsync event node for primary " 711 "display: %s", 712 strerror(errno)); 713 714 // Open the wait pingpong status node for the primary display. 715 // TODO(eieio): Move this into a platform-specific class. 716 primary_display_wait_pp_fd_ = 717 LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY); 718 ALOGW_IF( 719 !primary_display_wait_pp_fd_, 720 "HardwareComposer: Failed to open wait_pp node for primary display: %s", 721 strerror(errno)); 722 723 // Create a timerfd based on CLOCK_MONOTINIC. 724 vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0)); 725 LOG_ALWAYS_FATAL_IF( 726 !vsync_sleep_timer_fd_, 727 "HardwareComposer: Failed to create vsync sleep timerfd: %s", 728 strerror(errno)); 729 730 const int64_t ns_per_frame = display_metrics_.vsync_period_ns; 731 const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame); 732 733 // TODO(jbates) Query vblank time from device, when such an API is available. 734 // This value (6.3%) was measured on A00 in low persistence mode. 735 int64_t vblank_ns = ns_per_frame * 63 / 1000; 736 int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2; 737 738 // Check property for overriding right eye offset value. 739 right_eye_photon_offset_ns = 740 property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns); 741 742 bool was_running = false; 743 744 while (1) { 745 ATRACE_NAME("HardwareComposer::PostThread"); 746 747 while (post_thread_quiescent_) { 748 std::unique_lock<std::mutex> lock(post_thread_mutex_); 749 ALOGI("HardwareComposer::PostThread: Entering quiescent state."); 750 751 // Tear down resources. 752 OnPostThreadPaused(); 753 754 was_running = false; 755 post_thread_resumed_ = false; 756 post_thread_ready_.notify_all(); 757 758 if (post_thread_state_ & PostThreadState::Quit) { 759 ALOGI("HardwareComposer::PostThread: Quitting."); 760 return; 761 } 762 763 post_thread_wait_.wait(lock, [this] { return !post_thread_quiescent_; }); 764 765 post_thread_resumed_ = true; 766 post_thread_ready_.notify_all(); 767 768 ALOGI("HardwareComposer::PostThread: Exiting quiescent state."); 769 } 770 771 if (!was_running) { 772 // Setup resources. 773 OnPostThreadResumed(); 774 was_running = true; 775 776 // Try to setup the scheduler policy if it failed during startup. Only 777 // attempt to do this on transitions from inactive to active to avoid 778 // spamming the system with RPCs and log messages. 779 if (!thread_policy_setup) { 780 thread_policy_setup = 781 SetThreadPolicy("graphics:high", "/system/performance"); 782 } 783 } 784 785 int64_t vsync_timestamp = 0; 786 { 787 std::array<char, 128> buf; 788 snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|", 789 vsync_count_ + 1); 790 ATRACE_NAME(buf.data()); 791 792 const int error = WaitForVSync(&vsync_timestamp); 793 ALOGE_IF( 794 error < 0, 795 "HardwareComposer::PostThread: Failed to wait for vsync event: %s", 796 strerror(-error)); 797 // Don't bother processing this frame if a pause was requested 798 if (error == kPostThreadInterrupted) 799 continue; 800 } 801 802 ++vsync_count_; 803 804 if (pose_client_) { 805 // Signal the pose service with vsync info. 806 // Display timestamp is in the middle of scanout. 807 privateDvrPoseNotifyVsync(pose_client_, vsync_count_, 808 vsync_timestamp + photon_offset_ns, 809 ns_per_frame, right_eye_photon_offset_ns); 810 } 811 812 const bool layer_config_changed = UpdateLayerConfig(); 813 814 // Signal all of the vsync clients. Because absolute time is used for the 815 // wakeup time below, this can take a little time if necessary. 816 if (vsync_callback_) 817 vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, 818 /*frame_time_estimate*/ 0, vsync_count_); 819 820 { 821 // Sleep until shortly before vsync. 822 ATRACE_NAME("sleep"); 823 824 const int64_t display_time_est_ns = vsync_timestamp + ns_per_frame; 825 const int64_t now_ns = GetSystemClockNs(); 826 const int64_t sleep_time_ns = 827 display_time_est_ns - now_ns - kFramePostOffsetNs; 828 const int64_t wakeup_time_ns = display_time_est_ns - kFramePostOffsetNs; 829 830 ATRACE_INT64("sleep_time_ns", sleep_time_ns); 831 if (sleep_time_ns > 0) { 832 int error = SleepUntil(wakeup_time_ns); 833 ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s", 834 strerror(-error)); 835 if (error == kPostThreadInterrupted) { 836 if (layer_config_changed) { 837 // If the layer config changed we need to validateDisplay() even if 838 // we're going to drop the frame, to flush the Composer object's 839 // internal command buffer and apply our layer changes. 840 Validate(HWC_DISPLAY_PRIMARY); 841 } 842 continue; 843 } 844 } 845 } 846 847 PostLayers(); 848 } 849} 850 851// Checks for changes in the surface stack and updates the layer config to 852// accomodate the new stack. 853bool HardwareComposer::UpdateLayerConfig() { 854 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces; 855 { 856 std::unique_lock<std::mutex> lock(post_thread_mutex_); 857 if (pending_surfaces_.empty()) 858 return false; 859 860 surfaces = std::move(pending_surfaces_); 861 } 862 863 ATRACE_NAME("UpdateLayerConfig_HwLayers"); 864 865 display_surfaces_.clear(); 866 867 Layer* target_layer; 868 size_t layer_index; 869 for (layer_index = 0; 870 layer_index < std::min(surfaces.size(), kMaxHardwareLayers); 871 layer_index++) { 872 // The bottom layer is opaque, other layers blend. 873 HWC::BlendMode blending = 874 layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage; 875 layers_[layer_index].Setup(surfaces[layer_index], blending, 876 display_transform_, HWC::Composition::Device, 877 layer_index); 878 display_surfaces_.push_back(surfaces[layer_index]); 879 } 880 881 // Clear unused layers. 882 for (size_t i = layer_index; i < kMaxHardwareLayers; i++) 883 layers_[i].Reset(); 884 885 active_layer_count_ = layer_index; 886 ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers", 887 active_layer_count_); 888 889 // Any surfaces left over could not be assigned a hardware layer and will 890 // not be displayed. 891 ALOGW_IF(surfaces.size() != display_surfaces_.size(), 892 "HardwareComposer::UpdateLayerConfig: More surfaces than layers: " 893 "pending_surfaces=%zu display_surfaces=%zu", 894 surfaces.size(), display_surfaces_.size()); 895 896 return true; 897} 898 899void HardwareComposer::SetVSyncCallback(VSyncCallback callback) { 900 vsync_callback_ = callback; 901} 902 903void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/, 904 hwc2_display_t /*display*/) { 905 // TODO(eieio): implement invalidate callbacks. 906} 907 908void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/, 909 hwc2_display_t /*display*/, 910 int64_t /*timestamp*/) { 911 ATRACE_NAME(__PRETTY_FUNCTION__); 912 // Intentionally empty. HWC may require a callback to be set to enable vsync 913 // signals. We bypass this callback thread by monitoring the vsync event 914 // directly, but signals still need to be enabled. 915} 916 917void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/, 918 hwc2_display_t /*display*/, 919 hwc2_connection_t /*connected*/) { 920 // TODO(eieio): implement display hotplug callbacks. 921} 922 923void HardwareComposer::OnHardwareComposerRefresh() { 924 // TODO(steventhomas): Handle refresh. 925} 926 927void HardwareComposer::SetBacklightBrightness(int brightness) { 928 if (backlight_brightness_fd_) { 929 std::array<char, 32> text; 930 const int length = snprintf(text.data(), text.size(), "%d", brightness); 931 write(backlight_brightness_fd_.Get(), text.data(), length); 932 } 933} 934 935void Layer::InitializeGlobals(Hwc2::Composer* hwc2_hidl, 936 const HWCDisplayMetrics* metrics) { 937 hwc2_hidl_ = hwc2_hidl; 938 display_metrics_ = metrics; 939} 940 941void Layer::Reset() { 942 if (hwc2_hidl_ != nullptr && hardware_composer_layer_) { 943 hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_); 944 hardware_composer_layer_ = 0; 945 } 946 947 z_order_ = 0; 948 blending_ = HWC::BlendMode::None; 949 transform_ = HWC::Transform::None; 950 composition_type_ = HWC::Composition::Invalid; 951 target_composition_type_ = composition_type_; 952 source_ = EmptyVariant{}; 953 acquire_fence_.Close(); 954 surface_rect_functions_applied_ = false; 955} 956 957void Layer::Setup(const std::shared_ptr<DirectDisplaySurface>& surface, 958 HWC::BlendMode blending, HWC::Transform transform, 959 HWC::Composition composition_type, size_t z_order) { 960 Reset(); 961 z_order_ = z_order; 962 blending_ = blending; 963 transform_ = transform; 964 composition_type_ = HWC::Composition::Invalid; 965 target_composition_type_ = composition_type; 966 source_ = SourceSurface{surface}; 967 CommonLayerSetup(); 968} 969 970void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer, 971 HWC::BlendMode blending, HWC::Transform transform, 972 HWC::Composition composition_type, size_t z_order) { 973 Reset(); 974 z_order_ = z_order; 975 blending_ = blending; 976 transform_ = transform; 977 composition_type_ = HWC::Composition::Invalid; 978 target_composition_type_ = composition_type; 979 source_ = SourceBuffer{buffer}; 980 CommonLayerSetup(); 981} 982 983void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) { 984 if (source_.is<SourceBuffer>()) 985 std::get<SourceBuffer>(source_) = {buffer}; 986} 987 988void Layer::SetBlending(HWC::BlendMode blending) { blending_ = blending; } 989void Layer::SetZOrder(size_t z_order) { z_order_ = z_order; } 990 991IonBuffer* Layer::GetBuffer() { 992 struct Visitor { 993 IonBuffer* operator()(SourceSurface& source) { return source.GetBuffer(); } 994 IonBuffer* operator()(SourceBuffer& source) { return source.GetBuffer(); } 995 IonBuffer* operator()(EmptyVariant) { return nullptr; } 996 }; 997 return source_.Visit(Visitor{}); 998} 999 1000void Layer::UpdateLayerSettings() { 1001 if (!IsLayerSetup()) { 1002 ALOGE( 1003 "HardwareComposer::Layer::UpdateLayerSettings: Attempt to update " 1004 "unused Layer!"); 1005 return; 1006 } 1007 1008 HWC::Error error; 1009 hwc2_display_t display = HWC_DISPLAY_PRIMARY; 1010 1011 error = hwc2_hidl_->setLayerCompositionType( 1012 display, hardware_composer_layer_, 1013 composition_type_.cast<Hwc2::IComposerClient::Composition>()); 1014 ALOGE_IF( 1015 error != HWC::Error::None, 1016 "Layer::UpdateLayerSettings: Error setting layer composition type: %s", 1017 error.to_string().c_str()); 1018 1019 error = hwc2_hidl_->setLayerBlendMode( 1020 display, hardware_composer_layer_, 1021 blending_.cast<Hwc2::IComposerClient::BlendMode>()); 1022 ALOGE_IF(error != HWC::Error::None, 1023 "Layer::UpdateLayerSettings: Error setting layer blend mode: %s", 1024 error.to_string().c_str()); 1025 1026 // TODO(eieio): Use surface attributes or some other mechanism to control 1027 // the layer display frame. 1028 error = hwc2_hidl_->setLayerDisplayFrame( 1029 display, hardware_composer_layer_, 1030 {0, 0, display_metrics_->width, display_metrics_->height}); 1031 ALOGE_IF(error != HWC::Error::None, 1032 "Layer::UpdateLayerSettings: Error setting layer display frame: %s", 1033 error.to_string().c_str()); 1034 1035 error = hwc2_hidl_->setLayerVisibleRegion( 1036 display, hardware_composer_layer_, 1037 {{0, 0, display_metrics_->width, display_metrics_->height}}); 1038 ALOGE_IF(error != HWC::Error::None, 1039 "Layer::UpdateLayerSettings: Error setting layer visible region: %s", 1040 error.to_string().c_str()); 1041 1042 error = 1043 hwc2_hidl_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f); 1044 ALOGE_IF(error != HWC::Error::None, 1045 "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s", 1046 error.to_string().c_str()); 1047 1048 error = 1049 hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_, z_order_); 1050 ALOGE_IF(error != HWC::Error::None, 1051 "Layer::UpdateLayerSettings: Error setting z_ order: %s", 1052 error.to_string().c_str()); 1053} 1054 1055void Layer::CommonLayerSetup() { 1056 HWC::Error error = 1057 hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_); 1058 ALOGE_IF( 1059 error != HWC::Error::None, 1060 "Layer::CommonLayerSetup: Failed to create layer on primary display: %s", 1061 error.to_string().c_str()); 1062 UpdateLayerSettings(); 1063} 1064 1065void Layer::Prepare() { 1066 int right, bottom; 1067 sp<GraphicBuffer> handle; 1068 1069 // Acquire the next buffer according to the type of source. 1070 IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) { 1071 std::tie(right, bottom, handle, acquire_fence_) = source.Acquire(); 1072 }); 1073 1074 // When a layer is first setup there may be some time before the first buffer 1075 // arrives. Setup the HWC layer as a solid color to stall for time until the 1076 // first buffer arrives. Once the first buffer arrives there will always be a 1077 // buffer for the frame even if it is old. 1078 if (!handle.get()) { 1079 if (composition_type_ == HWC::Composition::Invalid) { 1080 composition_type_ = HWC::Composition::SolidColor; 1081 hwc2_hidl_->setLayerCompositionType( 1082 HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 1083 composition_type_.cast<Hwc2::IComposerClient::Composition>()); 1084 Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0}; 1085 hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 1086 layer_color); 1087 } else { 1088 // The composition type is already set. Nothing else to do until a 1089 // buffer arrives. 1090 } 1091 } else { 1092 if (composition_type_ != target_composition_type_) { 1093 composition_type_ = target_composition_type_; 1094 hwc2_hidl_->setLayerCompositionType( 1095 HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 1096 composition_type_.cast<Hwc2::IComposerClient::Composition>()); 1097 } 1098 1099 HWC::Error error{HWC::Error::None}; 1100 error = hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY, 1101 hardware_composer_layer_, 0, handle, 1102 acquire_fence_.Get()); 1103 1104 ALOGE_IF(error != HWC::Error::None, 1105 "Layer::Prepare: Error setting layer buffer: %s", 1106 error.to_string().c_str()); 1107 1108 if (!surface_rect_functions_applied_) { 1109 const float float_right = right; 1110 const float float_bottom = bottom; 1111 error = hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY, 1112 hardware_composer_layer_, 1113 {0, 0, float_right, float_bottom}); 1114 1115 ALOGE_IF(error != HWC::Error::None, 1116 "Layer::Prepare: Error setting layer source crop: %s", 1117 error.to_string().c_str()); 1118 1119 surface_rect_functions_applied_ = true; 1120 } 1121 } 1122} 1123 1124void Layer::Finish(int release_fence_fd) { 1125 IfAnyOf<SourceSurface, SourceBuffer>::Call( 1126 &source_, [release_fence_fd](auto& source) { 1127 source.Finish(LocalHandle(release_fence_fd)); 1128 }); 1129} 1130 1131void Layer::Drop() { acquire_fence_.Close(); } 1132 1133} // namespace dvr 1134} // namespace android 1135