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