hardware_composer.cpp revision 4b78832d7fc3cdd13a20587dfee96d1505916213
1#include "hardware_composer.h" 2 3#include <log/log.h> 4#include <cutils/properties.h> 5#include <cutils/sched_policy.h> 6#include <fcntl.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 <unistd.h> 15#include <utils/Trace.h> 16 17#include <algorithm> 18#include <functional> 19#include <map> 20 21#include <dvr/performance_client_api.h> 22#include <private/dvr/clock_ns.h> 23#include <private/dvr/display_types.h> 24#include <private/dvr/pose_client_internal.h> 25#include <private/dvr/sync_util.h> 26 27#include "debug_hud_data.h" 28#include "screenshot_service.h" 29 30using android::pdx::LocalHandle; 31 32namespace android { 33namespace dvr { 34 35namespace { 36 37// If the number of pending fences goes over this count at the point when we 38// are about to submit a new frame to HWC, we will drop the frame. This should 39// be a signal that the display driver has begun queuing frames. Note that with 40// smart displays (with RAM), the fence is signaled earlier than the next vsync, 41// at the point when the DMA to the display completes. Currently we use a smart 42// display and the EDS timing coincides with zero pending fences, so this is 0. 43constexpr int kAllowedPendingFenceCount = 0; 44 45// If we think we're going to miss vsync by more than this amount, skip the 46// frame. 47constexpr int64_t kFrameSkipThresholdNs = 4000000; // 4ms 48 49// Counter PostLayers() deficiency by requiring apps to produce a frame at least 50// 2.5ms before vsync. See b/28881672. 51constexpr int64_t kFrameTimeEstimateMin = 2500000; // 2.5ms 52 53constexpr size_t kDefaultDisplayConfigCount = 32; 54 55constexpr float kMetersPerInch = 0.0254f; 56 57const char kBacklightBrightnessSysFile[] = 58 "/sys/class/leds/lcd-backlight/brightness"; 59 60const char kPrimaryDisplayVSyncEventFile[] = 61 "/sys/class/graphics/fb0/vsync_event"; 62 63const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp"; 64 65const char kDvrPerformanceProperty[] = "sys.dvr.performance"; 66 67const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns"; 68 69// Returns our best guess for the time the compositor will spend rendering the 70// next frame. 71int64_t GuessFrameTime(int compositor_visible_layer_count) { 72 // The cost of asynchronous EDS and lens warp is currently measured at 2.5ms 73 // for one layer and 7ms for two layers, but guess a higher frame time to 74 // account for CPU overhead. This guess is only used before we've measured the 75 // actual time to render a frame for the current compositor configuration. 76 switch (compositor_visible_layer_count) { 77 case 0: 78 return 500000; // .5ms 79 case 1: 80 return 5000000; // 5ms 81 default: 82 return 10500000; // 10.5ms 83 } 84} 85 86// Get time offset from a vsync to when the pose for that vsync should be 87// predicted out to. For example, if scanout gets halfway through the frame 88// at the halfway point between vsyncs, then this could be half the period. 89// With global shutter displays, this should be changed to the offset to when 90// illumination begins. Low persistence adds a frame of latency, so we predict 91// to the center of the next frame. 92inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) { 93 return (vsync_period_ns * 150) / 100; 94} 95 96} // anonymous namespace 97 98HardwareComposer::HardwareComposer() 99 : HardwareComposer(nullptr) { 100} 101 102HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl) 103 : initialized_(false), 104 hwc2_hidl_(hwc2_hidl), 105 display_transform_(HWC_TRANSFORM_NONE), 106 active_surfaces_updated_(false), 107 active_layer_count_(0), 108 gpu_layer_(nullptr), 109 post_thread_enabled_(false), 110 post_thread_running_(false), 111 post_thread_quit_requested_(false), 112 post_thread_interrupt_event_fd_(-1), 113 backlight_brightness_fd_(-1), 114 primary_display_vsync_event_fd_(-1), 115 primary_display_wait_pp_fd_(-1), 116 vsync_sleep_timer_fd_(-1), 117 last_vsync_timestamp_(0), 118 vsync_count_(0), 119 frame_skip_count_(0), 120 pose_client_(nullptr) { 121 std::transform(layer_storage_.begin(), layer_storage_.end(), layers_.begin(), 122 [](auto& layer) { return &layer; }); 123 124 callbacks_ = new ComposerCallback; 125} 126 127HardwareComposer::~HardwareComposer(void) { 128 std::unique_lock<std::mutex> lock(post_thread_mutex_); 129 if (post_thread_.joinable()) { 130 post_thread_quit_requested_ = true; 131 post_thread_cond_var_.notify_all(); 132 post_thread_.join(); 133 } 134} 135 136bool HardwareComposer::Initialize() { 137 if (initialized_) { 138 ALOGE("HardwareComposer::Initialize: already initialized."); 139 return false; 140 } 141 142 int32_t ret = HWC2_ERROR_NONE; 143 144 Hwc2::Config config; 145 ret = (int32_t)hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config); 146 147 if (ret != HWC2_ERROR_NONE) { 148 ALOGE("HardwareComposer: Failed to get current display config : %d", 149 config); 150 return false; 151 } 152 153 ret = 154 GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_); 155 156 if (ret != HWC2_ERROR_NONE) { 157 ALOGE( 158 "HardwareComposer: Failed to get display attributes for current " 159 "configuration : %d", 160 ret); 161 return false; 162 } 163 164 ALOGI( 165 "HardwareComposer: primary display attributes: width=%d height=%d " 166 "vsync_period_ns=%d DPI=%dx%d", 167 native_display_metrics_.width, native_display_metrics_.height, 168 native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x, 169 native_display_metrics_.dpi.y); 170 171 // Set the display metrics but never use rotation to avoid the long latency of 172 // rotation processing in hwc. 173 display_transform_ = HWC_TRANSFORM_NONE; 174 display_metrics_ = native_display_metrics_; 175 176 post_thread_interrupt_event_fd_.Reset( 177 eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 178 LOG_ALWAYS_FATAL_IF( 179 !post_thread_interrupt_event_fd_, 180 "HardwareComposer: Failed to create interrupt event fd : %s", 181 strerror(errno)); 182 183 post_thread_ = std::thread(&HardwareComposer::PostThread, this); 184 185 initialized_ = true; 186 187 return initialized_; 188} 189 190void HardwareComposer::Enable() { 191 std::lock_guard<std::mutex> lock(post_thread_mutex_); 192 post_thread_enabled_ = true; 193 post_thread_cond_var_.notify_all(); 194} 195 196void HardwareComposer::Disable() { 197 std::unique_lock<std::mutex> lock(post_thread_mutex_); 198 post_thread_enabled_ = false; 199 if (post_thread_running_) { 200 // Write to the interrupt fd to get fast interrupt of the post thread 201 int error = eventfd_write(post_thread_interrupt_event_fd_.Get(), 1); 202 ALOGW_IF(error, 203 "HardwareComposer::Disable: could not write post " 204 "thread interrupt event fd : %s", 205 strerror(errno)); 206 207 post_thread_cond_var_.wait(lock, [this] { return !post_thread_running_; }); 208 209 // Read the interrupt fd to clear its state 210 uint64_t interrupt_count= 0; 211 error = eventfd_read(post_thread_interrupt_event_fd_.Get(), 212 &interrupt_count); 213 ALOGW_IF(error, 214 "HardwareComposer::Disable: could not read post " 215 "thread interrupt event fd : %s", 216 strerror(errno)); 217 } 218} 219 220bool HardwareComposer::PostThreadHasWork() { 221 return !display_surfaces_.empty() || 222 (active_surfaces_updated_ && !active_surfaces_.empty()); 223} 224 225void HardwareComposer::OnPostThreadResumed() { 226 constexpr int format = HAL_PIXEL_FORMAT_RGBA_8888; 227 constexpr int usage = 228 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER; 229 230 framebuffer_target_ = std::make_shared<IonBuffer>( 231 native_display_metrics_.width, native_display_metrics_.height, format, 232 usage); 233 234 // Associate each Layer instance with a hardware composer layer. 235 for (auto layer : layers_) { 236 layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_); 237 } 238 239 // Connect to pose service. 240 pose_client_ = dvrPoseCreate(); 241 ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client"); 242 243 EnableVsync(true); 244 245 // TODO(skiazyk): We need to do something about accessing this directly, 246 // supposedly there is a backlight service on the way. 247 // TODO(steventhomas): When we change the backlight setting, will surface 248 // flinger (or something else) set it back to its original value once we give 249 // control of the display back to surface flinger? 250 SetBacklightBrightness(255); 251 252 // Initialize the GPU compositor. 253 LOG_ALWAYS_FATAL_IF(!compositor_.Initialize(GetHmdDisplayMetrics()), 254 "Failed to initialize the compositor"); 255 256 // Trigger target-specific performance mode change. 257 property_set(kDvrPerformanceProperty, "performance"); 258} 259 260void HardwareComposer::OnPostThreadPaused() { 261 retire_fence_fds_.clear(); 262 gpu_layer_ = nullptr; 263 264 // We have to destroy the layers to fully clear hwc device state before 265 // handing off back to surface flinger 266 for (size_t i = 0; i < kMaxHardwareLayers; ++i) { 267 layers_[i]->Reset(); 268 } 269 270 active_layer_count_ = 0; 271 272 framebuffer_target_.reset(); 273 274 display_surfaces_.clear(); 275 compositor_surfaces_.clear(); 276 277 // Since we're clearing display_surfaces_ we'll need an update. 278 active_surfaces_updated_ = true; 279 280 if (pose_client_) { 281 dvrPoseDestroy(pose_client_); 282 pose_client_ = nullptr; 283 } 284 285 EnableVsync(false); 286 287 frame_time_history_.ResetWithSeed(GuessFrameTime(0)); 288 frame_time_backlog_.clear(); 289 290 compositor_.Shutdown(); 291 292 // Trigger target-specific performance mode change. 293 property_set(kDvrPerformanceProperty, "idle"); 294} 295 296DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const { 297 vec2i screen_size(display_metrics_.width, display_metrics_.height); 298 DisplayOrientation orientation = 299 (display_metrics_.width > display_metrics_.height 300 ? DisplayOrientation::kLandscape 301 : DisplayOrientation::kPortrait); 302 float dpi_x = static_cast<float>(display_metrics_.dpi.x) / 1000.0f; 303 float dpi_y = static_cast<float>(display_metrics_.dpi.y) / 1000.0f; 304 float meters_per_pixel_x = kMetersPerInch / dpi_x; 305 float meters_per_pixel_y = kMetersPerInch / dpi_y; 306 vec2 meters_per_pixel(meters_per_pixel_x, meters_per_pixel_y); 307 double frame_duration_s = 308 static_cast<double>(display_metrics_.vsync_period_ns) / 1000000000.0; 309 // TODO(hendrikw): Hard coding to 3mm. The Pixel is actually 4mm, but it 310 // seems that their tray to lens distance is wrong too, which 311 // offsets this, at least for the pixel. 312 float border_size = 0.003f; 313 return DisplayMetrics(screen_size, meters_per_pixel, border_size, 314 static_cast<float>(frame_duration_s), orientation); 315} 316 317int32_t HardwareComposer::Validate(hwc2_display_t display) { 318 uint32_t num_types; 319 uint32_t num_requests; 320 int32_t error = 321 (int32_t)hwc2_hidl_->validateDisplay(display, &num_types, &num_requests); 322 323 if (error == HWC2_ERROR_HAS_CHANGES) { 324 // TODO(skiazyk): We might need to inspect the requested changes first, but 325 // so far it seems like we shouldn't ever hit a bad state. 326 // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_, 327 // display); 328 error = (int32_t)hwc2_hidl_->acceptDisplayChanges(display); 329 } 330 331 return error; 332} 333 334int32_t HardwareComposer::EnableVsync(bool enabled) { 335 return (int32_t)hwc2_hidl_->setVsyncEnabled( 336 HWC_DISPLAY_PRIMARY, 337 (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE 338 : HWC2_VSYNC_DISABLE)); 339} 340 341int32_t HardwareComposer::Present(hwc2_display_t display) { 342 int32_t present_fence; 343 int32_t error = (int32_t)hwc2_hidl_->presentDisplay(display, &present_fence); 344 345 // According to the documentation, this fence is signaled at the time of 346 // vsync/DMA for physical displays. 347 if (error == HWC2_ERROR_NONE) { 348 ATRACE_INT("HardwareComposer: VsyncFence", present_fence); 349 retire_fence_fds_.emplace_back(present_fence); 350 } else { 351 ATRACE_INT("HardwareComposer: PresentResult", error); 352 } 353 354 return error; 355} 356 357int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display, 358 hwc2_config_t config, 359 hwc2_attribute_t attribute, 360 int32_t* out_value) const { 361 return (int32_t)hwc2_hidl_->getDisplayAttribute( 362 display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value); 363} 364 365int32_t HardwareComposer::GetDisplayMetrics( 366 hwc2_display_t display, hwc2_config_t config, 367 HWCDisplayMetrics* out_metrics) const { 368 int32_t ret = HWC2_ERROR_NONE; 369 370 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH, 371 &out_metrics->width); 372 if (ret != HWC2_ERROR_NONE) { 373 ALOGE("HardwareComposer: Failed to get display width"); 374 return ret; 375 } 376 377 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT, 378 &out_metrics->height); 379 if (ret != HWC2_ERROR_NONE) { 380 ALOGE("HardwareComposer: Failed to get display height"); 381 return ret; 382 } 383 384 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD, 385 &out_metrics->vsync_period_ns); 386 if (ret != HWC2_ERROR_NONE) { 387 ALOGE("HardwareComposer: Failed to get display height"); 388 return ret; 389 } 390 391 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X, 392 &out_metrics->dpi.x); 393 if (ret != HWC2_ERROR_NONE) { 394 ALOGE("HardwareComposer: Failed to get display DPI X"); 395 return ret; 396 } 397 398 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y, 399 &out_metrics->dpi.y); 400 if (ret != HWC2_ERROR_NONE) { 401 ALOGE("HardwareComposer: Failed to get display DPI Y"); 402 return ret; 403 } 404 405 return HWC2_ERROR_NONE; 406} 407 408void HardwareComposer::Dump(char* buffer, uint32_t* out_size) { 409 std::string debug_str = hwc2_hidl_->dumpDebugInfo(); 410 ALOGI("%s", debug_str.c_str()); 411 412 if (buffer == nullptr) { 413 *out_size = debug_str.size(); 414 } else { 415 std::copy(debug_str.begin(), debug_str.begin() + *out_size, buffer); 416 } 417} 418 419// TODO(skiazyk): Figure out what to do with `is_geometry_changed`. There does 420// not seem to be any equivalent in the HWC2 API, but that doesn't mean its not 421// there. 422void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) { 423 ATRACE_NAME("HardwareComposer::PostLayers"); 424 425 // Setup the hardware composer layers with current buffers. 426 for (size_t i = 0; i < active_layer_count_; i++) { 427 layers_[i]->Prepare(); 428 } 429 430 // Now that we have taken in a frame from the application, we have a chance 431 // to drop the frame before passing the frame along to HWC. 432 // If the display driver has become backed up, we detect it here and then 433 // react by skipping this frame to catch up latency. 434 while (!retire_fence_fds_.empty() && 435 (!retire_fence_fds_.front() || 436 sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) { 437 // There are only 2 fences in here, no performance problem to shift the 438 // array of ints. 439 retire_fence_fds_.erase(retire_fence_fds_.begin()); 440 } 441 442 const bool is_frame_pending = IsFramePendingInDriver(); 443 const bool is_fence_pending = 444 retire_fence_fds_.size() > kAllowedPendingFenceCount; 445 446 if (is_fence_pending || is_frame_pending) { 447 ATRACE_INT("frame_skip_count", ++frame_skip_count_); 448 449 ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame"); 450 ALOGW_IF(is_fence_pending, 451 "Warning: dropping a frame to catch up with HWC (pending = %zd)", 452 retire_fence_fds_.size()); 453 454 for (size_t i = 0; i < active_layer_count_; i++) { 455 layers_[i]->Drop(); 456 } 457 return; 458 } else { 459 // Make the transition more obvious in systrace when the frame skip happens 460 // above. 461 ATRACE_INT("frame_skip_count", 0); 462 } 463 464#if TRACE 465 for (size_t i = 0; i < active_layer_count_; i++) 466 ALOGI("HardwareComposer::PostLayers: dl[%zu] ctype=0x%08x", i, 467 layers_[i]->GetCompositionType()); 468#endif 469 470 int32_t ret = HWC2_ERROR_NONE; 471 472 std::vector<Hwc2::IComposerClient::Rect> full_region(1); 473 full_region[0].left = 0; 474 full_region[0].top = 0; 475 full_region[0].right = framebuffer_target_->width(); 476 full_region[0].bottom = framebuffer_target_->height(); 477 478 ALOGE_IF(ret, "Error setting client target : %d", ret); 479 480 ret = Validate(HWC_DISPLAY_PRIMARY); 481 if (ret) { 482 ALOGE("HardwareComposer::Validate failed; ret=%d", ret); 483 return; 484 } 485 486 ret = Present(HWC_DISPLAY_PRIMARY); 487 if (ret) { 488 ALOGE("HardwareComposer::Present failed; ret=%d", ret); 489 return; 490 } 491 492 std::vector<Hwc2::Layer> out_layers; 493 std::vector<int> out_fences; 494 ret = (int32_t)hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers, 495 &out_fences); 496 uint32_t num_elements = out_layers.size(); 497 498 ALOGE_IF(ret, "HardwareComposer: GetReleaseFences failed; ret=%d", ret); 499 500 // Perform post-frame bookkeeping. Unused layers are a no-op. 501 for (size_t i = 0; i < num_elements; ++i) { 502 for (size_t j = 0; j < active_layer_count_; ++j) { 503 if (layers_[j]->GetLayerHandle() == out_layers[i]) { 504 layers_[j]->Finish(out_fences[i]); 505 } 506 } 507 } 508} 509 510void HardwareComposer::SetDisplaySurfaces( 511 std::vector<std::shared_ptr<DisplaySurface>> surfaces) { 512 ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd", 513 surfaces.size()); 514 std::unique_lock<std::mutex> lock(post_thread_mutex_); 515 active_surfaces_ = std::move(surfaces); 516 active_surfaces_updated_ = true; 517 if (post_thread_enabled_) 518 post_thread_cond_var_.notify_all(); 519} 520 521int HardwareComposer::PostThreadPollInterruptible(int event_fd, 522 int requested_events) { 523 pollfd pfd[2] = { 524 { 525 .fd = event_fd, 526 .events = static_cast<short>(requested_events), 527 .revents = 0, 528 }, 529 { 530 .fd = post_thread_interrupt_event_fd_.Get(), 531 .events = POLLPRI | POLLIN, 532 .revents = 0, 533 }, 534 }; 535 int ret, error; 536 do { 537 ret = poll(pfd, 2, -1); 538 error = errno; 539 ALOGW_IF(ret < 0, 540 "HardwareComposer::PostThreadPollInterruptible: Error during " 541 "poll(): %s (%d)", 542 strerror(error), error); 543 } while (ret < 0 && error == EINTR); 544 545 if (ret < 0) { 546 return -error; 547 } else if (pfd[0].revents != 0) { 548 return 0; 549 } else if (pfd[1].revents != 0) { 550 ALOGI("VrHwcPost thread interrupted"); 551 return kPostThreadInterrupted; 552 } else { 553 return 0; 554 } 555} 556 557// Reads the value of the display driver wait_pingpong state. Returns 0 or 1 558// (the value of the state) on success or a negative error otherwise. 559// TODO(eieio): This is pretty driver specific, this should be moved to a 560// separate class eventually. 561int HardwareComposer::ReadWaitPPState() { 562 // Gracefully handle when the kernel does not support this feature. 563 if (!primary_display_wait_pp_fd_) 564 return 0; 565 566 const int wait_pp_fd = primary_display_wait_pp_fd_.Get(); 567 int ret, error; 568 569 ret = lseek(wait_pp_fd, 0, SEEK_SET); 570 if (ret < 0) { 571 error = errno; 572 ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s", 573 strerror(error)); 574 return -error; 575 } 576 577 char data = -1; 578 ret = read(wait_pp_fd, &data, sizeof(data)); 579 if (ret < 0) { 580 error = errno; 581 ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s", 582 strerror(error)); 583 return -error; 584 } 585 586 switch (data) { 587 case '0': 588 return 0; 589 case '1': 590 return 1; 591 default: 592 ALOGE( 593 "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d", 594 data); 595 return -EINVAL; 596 } 597} 598 599// Reads the timestamp of the last vsync from the display driver. 600// TODO(eieio): This is pretty driver specific, this should be moved to a 601// separate class eventually. 602int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) { 603 const int event_fd = primary_display_vsync_event_fd_.Get(); 604 int ret, error; 605 606 // The driver returns data in the form "VSYNC=<timestamp ns>". 607 std::array<char, 32> data; 608 data.fill('\0'); 609 610 // Seek back to the beginning of the event file. 611 ret = lseek(event_fd, 0, SEEK_SET); 612 if (ret < 0) { 613 error = errno; 614 ALOGE( 615 "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: " 616 "%s", 617 strerror(error)); 618 return -error; 619 } 620 621 // Read the vsync event timestamp. 622 ret = read(event_fd, data.data(), data.size()); 623 if (ret < 0) { 624 error = errno; 625 ALOGE_IF( 626 error != EAGAIN, 627 "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: " 628 "%s", 629 strerror(error)); 630 return -error; 631 } 632 633 ret = sscanf(data.data(), "VSYNC=%" PRIu64, 634 reinterpret_cast<uint64_t*>(timestamp)); 635 if (ret < 0) { 636 error = errno; 637 ALOGE( 638 "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: " 639 "%s", 640 strerror(error)); 641 return -error; 642 } 643 644 return 0; 645} 646 647// Blocks until the next vsync event is signaled by the display driver. 648// TODO(eieio): This is pretty driver specific, this should be moved to a 649// separate class eventually. 650int HardwareComposer::BlockUntilVSync() { 651 return PostThreadPollInterruptible(primary_display_vsync_event_fd_.Get(), 652 // There will be a POLLPRI event on vsync 653 POLLPRI); 654} 655 656// Waits for the next vsync and returns the timestamp of the vsync event. If 657// vsync already passed since the last call, returns the latest vsync timestamp 658// instead of blocking. This method updates the last_vsync_timeout_ in the 659// process. 660// 661// TODO(eieio): This is pretty driver specific, this should be moved to a 662// separate class eventually. 663int HardwareComposer::WaitForVSync(int64_t* timestamp) { 664 int error; 665 666 // Get the current timestamp and decide what to do. 667 while (true) { 668 int64_t current_vsync_timestamp; 669 error = ReadVSyncTimestamp(¤t_vsync_timestamp); 670 if (error < 0 && error != -EAGAIN) 671 return error; 672 673 if (error == -EAGAIN) { 674 // Vsync was turned off, wait for the next vsync event. 675 error = BlockUntilVSync(); 676 if (error < 0 || error == kPostThreadInterrupted) 677 return error; 678 679 // Try again to get the timestamp for this new vsync interval. 680 continue; 681 } 682 683 // Check that we advanced to a later vsync interval. 684 if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) { 685 *timestamp = last_vsync_timestamp_ = current_vsync_timestamp; 686 return 0; 687 } 688 689 // See how close we are to the next expected vsync. If we're within 1ms, 690 // sleep for 1ms and try again. 691 const int64_t ns_per_frame = display_metrics_.vsync_period_ns; 692 const int64_t threshold_ns = 1000000; 693 694 const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame; 695 const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs(); 696 697 if (distance_to_vsync_est > threshold_ns) { 698 // Wait for vsync event notification. 699 error = BlockUntilVSync(); 700 if (error < 0 || error == kPostThreadInterrupted) 701 return error; 702 } else { 703 // Sleep for a short time (1 millisecond) before retrying. 704 error = SleepUntil(GetSystemClockNs() + 1000000); 705 if (error < 0 || error == kPostThreadInterrupted) 706 return error; 707 } 708 } 709} 710 711int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) { 712 const int timer_fd = vsync_sleep_timer_fd_.Get(); 713 const itimerspec wakeup_itimerspec = { 714 .it_interval = {.tv_sec = 0, .tv_nsec = 0}, 715 .it_value = NsToTimespec(wakeup_timestamp), 716 }; 717 int ret = 718 timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr); 719 int error = errno; 720 if (ret < 0) { 721 ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s", 722 strerror(error)); 723 return -error; 724 } 725 726 return PostThreadPollInterruptible(timer_fd, POLLIN); 727} 728 729void HardwareComposer::PostThread() { 730 // NOLINTNEXTLINE(runtime/int) 731 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0); 732 733 // Set the scheduler to SCHED_FIFO with high priority. 734 int error = dvrSetSchedulerClass(0, "graphics:high"); 735 LOG_ALWAYS_FATAL_IF( 736 error < 0, 737 "HardwareComposer::PostThread: Failed to set scheduler class: %s", 738 strerror(-error)); 739 error = dvrSetCpuPartition(0, "/system/performance"); 740 LOG_ALWAYS_FATAL_IF( 741 error < 0, 742 "HardwareComposer::PostThread: Failed to set cpu partition: %s", 743 strerror(-error)); 744 745#if ENABLE_BACKLIGHT_BRIGHTNESS 746 // TODO(hendrikw): This isn't required at the moment. It's possible that there 747 // is another method to access this when needed. 748 // Open the backlight brightness control sysfs node. 749 backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR); 750 ALOGW_IF(!backlight_brightness_fd_, 751 "HardwareComposer: Failed to open backlight brightness control: %s", 752 strerror(errno)); 753#endif // ENABLE_BACKLIGHT_BRIGHTNESS 754 755 // Open the vsync event node for the primary display. 756 // TODO(eieio): Move this into a platform-specific class. 757 primary_display_vsync_event_fd_ = 758 LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY); 759 ALOGE_IF(!primary_display_vsync_event_fd_, 760 "HardwareComposer: Failed to open vsync event node for primary " 761 "display: %s", 762 strerror(errno)); 763 764 // Open the wait pingpong status node for the primary display. 765 // TODO(eieio): Move this into a platform-specific class. 766 primary_display_wait_pp_fd_ = 767 LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY); 768 ALOGW_IF( 769 !primary_display_wait_pp_fd_, 770 "HardwareComposer: Failed to open wait_pp node for primary display: %s", 771 strerror(errno)); 772 773 // Create a timerfd based on CLOCK_MONOTINIC. 774 vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0)); 775 LOG_ALWAYS_FATAL_IF( 776 !vsync_sleep_timer_fd_, 777 "HardwareComposer: Failed to create vsync sleep timerfd: %s", 778 strerror(errno)); 779 780 const int64_t ns_per_frame = display_metrics_.vsync_period_ns; 781 const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame); 782 783 // TODO(jbates) Query vblank time from device, when such an API is available. 784 // This value (6.3%) was measured on A00 in low persistence mode. 785 int64_t vblank_ns = ns_per_frame * 63 / 1000; 786 int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2; 787 788 // Check property for overriding right eye offset value. 789 right_eye_photon_offset_ns = 790 property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns); 791 792 compositor_surfaces_.reserve(2); 793 794 constexpr int kFrameTimeBacklogMax = 2; 795 frame_time_backlog_.reserve(kFrameTimeBacklogMax); 796 797 // Storage for retrieving fence info. 798 FenceInfoBuffer fence_info_buffer; 799 800 bool was_running = false; 801 802 while (1) { 803 ATRACE_NAME("HardwareComposer::PostThread"); 804 805 { 806 std::unique_lock<std::mutex> lock(post_thread_mutex_); 807 while (!post_thread_enabled_ || post_thread_quit_requested_ || 808 !PostThreadHasWork()) { 809 if (was_running) { 810 const char* pause_reason = "unknown"; 811 if (!post_thread_enabled_) 812 pause_reason = "disabled"; 813 else if (post_thread_quit_requested_) 814 pause_reason = "quit requested"; 815 else if (!PostThreadHasWork()) 816 pause_reason = "no work"; 817 ALOGI("VrHwcPost thread paused. Reason: %s.", pause_reason); 818 OnPostThreadPaused(); 819 was_running = false; 820 } 821 post_thread_running_ = false; 822 post_thread_cond_var_.notify_all(); 823 if (post_thread_quit_requested_) 824 return; 825 post_thread_cond_var_.wait(lock); 826 } 827 post_thread_running_ = true; 828 } 829 830 if (!was_running) { 831 ALOGI("VrHwcPost thread resumed"); 832 OnPostThreadResumed(); 833 was_running = true; 834 } 835 836 int64_t vsync_timestamp = 0; 837 { 838 std::array<char, 128> buf; 839 snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|", 840 vsync_count_ + 1); 841 ATRACE_NAME(buf.data()); 842 843 error = WaitForVSync(&vsync_timestamp); 844 ALOGE_IF( 845 error < 0, 846 "HardwareComposer::PostThread: Failed to wait for vsync event: %s", 847 strerror(-error)); 848 // Don't bother processing this frame if a pause was requested 849 if (error == kPostThreadInterrupted) 850 continue; 851 } 852 853 ++vsync_count_; 854 855 if (pose_client_) { 856 // Signal the pose service with vsync info. 857 // Display timestamp is in the middle of scanout. 858 privateDvrPoseNotifyVsync(pose_client_, vsync_count_, 859 vsync_timestamp + photon_offset_ns, 860 ns_per_frame, right_eye_photon_offset_ns); 861 } 862 863 bool layer_config_changed = UpdateLayerConfig(); 864 865 if (!was_running || layer_config_changed) { 866 frame_time_history_.ResetWithSeed( 867 GuessFrameTime(compositor_surfaces_.size())); 868 frame_time_backlog_.clear(); 869 } else { 870 UpdateFrameTimeHistory(&frame_time_backlog_, kFrameTimeBacklogMax, 871 &fence_info_buffer, &frame_time_history_); 872 } 873 874 // Get our current best estimate at how long the next frame will take to 875 // render, based on how long previous frames took to render. Use this 876 // estimate to decide when to wake up for EDS. 877 int64_t frame_time_estimate = 878 frame_time_history_.GetSampleCount() == 0 879 ? GuessFrameTime(compositor_surfaces_.size()) 880 : frame_time_history_.GetAverage(); 881 frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin); 882 DebugHudData::data.hwc_latency = frame_time_estimate; 883 884 // Signal all of the vsync clients. Because absolute time is used for the 885 // wakeup time below, this can take a little time if necessary. 886 if (vsync_callback_) 887 vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate, 888 vsync_count_); 889 890 { 891 // Sleep until async EDS wakeup time. 892 ATRACE_NAME("sleep"); 893 894 int64_t display_time_est = vsync_timestamp + ns_per_frame; 895 int64_t now = GetSystemClockNs(); 896 int64_t frame_finish_time_est = now + frame_time_estimate; 897 int64_t sleep_time_ns = display_time_est - now - frame_time_estimate; 898 899 ATRACE_INT64("sleep_time_ns", sleep_time_ns); 900 if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) { 901 ATRACE_INT("frame_skip_count", ++frame_skip_count_); 902 ALOGE( 903 "HardwareComposer::PostThread: Missed frame schedule, drop " 904 "frame. Expected frame miss: %.1fms", 905 static_cast<double>(frame_finish_time_est - display_time_est) / 906 1000000); 907 908 // There are several reasons we might skip a frame, but one possibility 909 // is we mispredicted the frame time. Clear out the frame time history. 910 frame_time_history_.ResetWithSeed( 911 GuessFrameTime(compositor_surfaces_.size())); 912 frame_time_backlog_.clear(); 913 DebugHudData::data.hwc_frame_stats.SkipFrame(); 914 915 continue; 916 } else { 917 // Make the transition more obvious in systrace when the frame skip 918 // happens above. 919 ATRACE_INT("frame_skip_count", 0); 920 } 921 922 if (sleep_time_ns > 0) { 923 error = SleepUntil(display_time_est - frame_time_estimate); 924 ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s", 925 strerror(-error)); 926 if (error == kPostThreadInterrupted) 927 continue; 928 } 929 } 930 931 DebugHudData::data.hwc_frame_stats.AddFrame(); 932 933 int64_t frame_start_time = GetSystemClockNs(); 934 935 // Setup the output buffer for the compositor. This needs to happen before 936 // you draw with the compositor. 937 if (gpu_layer_ != nullptr) { 938 gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer()); 939 } 940 941 // Call PostLayers now before performing the GL code for the compositor to 942 // avoid missing the deadline that can cause the lower-level hwc to get 943 // permanently backed up. 944 PostLayers(layer_config_changed); 945 946 PostCompositorBuffers(); 947 948 if (gpu_layer_ != nullptr) { 949 // Note, with scanline racing, this draw is timed along with the post 950 // layers to finish just in time. 951 LocalHandle frame_fence_fd; 952 compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd); 953 if (frame_fence_fd) { 954 LOG_ALWAYS_FATAL_IF(frame_time_backlog_.size() >= kFrameTimeBacklogMax, 955 "Frame time backlog exceeds capacity"); 956 frame_time_backlog_.push_back( 957 {frame_start_time, std::move(frame_fence_fd)}); 958 } 959 } else if (!layer_config_changed) { 960 frame_time_history_.AddSample(GetSystemClockNs() - frame_start_time); 961 } 962 963 HandlePendingScreenshots(); 964 } 965} 966 967bool HardwareComposer::UpdateLayerConfig() { 968 std::vector<std::shared_ptr<DisplaySurface>> old_display_surfaces; 969 { 970 std::lock_guard<std::mutex> lock(post_thread_mutex_); 971 if (!active_surfaces_updated_) 972 return false; 973 old_display_surfaces = display_surfaces_; 974 display_surfaces_ = active_surfaces_; 975 active_surfaces_updated_ = false; 976 } 977 978 DebugHudData::data.ResetLayers(); 979 980 // Figure out whether we need to update hardware layers. If this surface 981 // change does not add or remove hardware layers we can avoid display hiccups 982 // by gracefully updating only the GPU compositor layers. 983 int old_gpu_layer_count = 0; 984 int new_gpu_layer_count = 0; 985 bool hardware_layers_need_update = false; 986 // Look for new hardware layers and count new GPU layers. 987 for (const auto& surface : display_surfaces_) { 988 if (!(surface->flags() & 989 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) 990 ++new_gpu_layer_count; 991 else if (std::find(old_display_surfaces.begin(), old_display_surfaces.end(), 992 surface) == old_display_surfaces.end()) 993 // This is a new hardware layer, we need to update. 994 hardware_layers_need_update = true; 995 } 996 // Look for deleted hardware layers or compositor layers. 997 for (const auto& surface : old_display_surfaces) { 998 if (!(surface->flags() & 999 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) 1000 ++old_gpu_layer_count; 1001 else if (std::find(display_surfaces_.begin(), display_surfaces_.end(), 1002 surface) == display_surfaces_.end()) 1003 // This is a deleted hardware layer, we need to update. 1004 hardware_layers_need_update = true; 1005 } 1006 // Check for compositor hardware layer transition. 1007 if ((!old_gpu_layer_count && new_gpu_layer_count) || 1008 (old_gpu_layer_count && !new_gpu_layer_count)) 1009 hardware_layers_need_update = true; 1010 1011 // Set the chosen layer order for all surfaces. 1012 for (size_t i = 0; i < display_surfaces_.size(); ++i) { 1013 display_surfaces_[i]->SetLayerOrder(static_cast<int>(i)); 1014 } 1015 1016 // Update compositor layers. 1017 { 1018 ATRACE_NAME("UpdateLayerConfig_GpuLayers"); 1019 compositor_.UpdateSurfaces(display_surfaces_); 1020 compositor_surfaces_.clear(); 1021 for (size_t i = 0; i < display_surfaces_.size(); ++i) { 1022 const auto& surface = display_surfaces_[i]; 1023 if (!(surface->flags() & 1024 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) { 1025 compositor_surfaces_.push_back(surface); 1026 } 1027 } 1028 } 1029 1030 if (!hardware_layers_need_update) 1031 return true; 1032 1033 // Update hardware layers. 1034 1035 ATRACE_NAME("UpdateLayerConfig_HwLayers"); 1036 1037 // Update the display layers in a non-destructive fashion. 1038 1039 // Create a map from surface id to hardware layer 1040 std::map<int, Layer*> display_surface_layers; 1041 1042 for (size_t i = 0; i < active_layer_count_; ++i) { 1043 auto layer = layers_[i]; 1044 int surface_id = layer->GetSurfaceId(); 1045 1046 auto found = 1047 std::find_if(display_surfaces_.begin(), display_surfaces_.end(), 1048 [surface_id](const auto& surface) { 1049 return surface->surface_id() == surface_id; 1050 }); 1051 1052 if (found != display_surfaces_.end()) { 1053 display_surface_layers[surface_id] = layer; 1054 } 1055 } 1056 1057 bool has_gpu_layer = std::any_of( 1058 display_surfaces_.begin(), display_surfaces_.end(), 1059 [](const auto& surface) { 1060 return !(surface->flags() & 1061 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION); 1062 }); 1063 1064 if (!has_gpu_layer) { 1065 gpu_layer_ = nullptr; 1066 } 1067 1068 auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) { 1069 int surface_id = layer->GetSurfaceId(); 1070 if (surface_id >= 0) { 1071 return display_surface_layers.count(surface_id) > 0; 1072 } else { 1073 return has_gpu_layer; 1074 } 1075 }; 1076 1077 // Compress the in-use layers to the top of the list 1078 auto part = std::partition( 1079 layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active); 1080 1081 size_t new_active_layer_count = part - layers_.begin(); 1082 1083 // Clear any unused layers 1084 for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) { 1085 layers_[i]->Reset(); 1086 } 1087 1088 active_layer_count_ = new_active_layer_count; 1089 1090 bool gpu_layer_applied = false; 1091 1092 // Create/update all of the hardware layers 1093 for (size_t i = 0; i < display_surfaces_.size(); ++i) { 1094 const auto& surface = display_surfaces_[i]; 1095 bool is_hw_surface = 1096 surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION; 1097 hwc2_blend_mode_t blending = 1098 i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE; 1099 1100 DebugHudData::data.SetLayerInfo( 1101 i, surface->width(), surface->height(), 1102 !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2)); 1103 1104 if (!is_hw_surface && gpu_layer_applied) { 1105 continue; 1106 } 1107 1108 Layer* target_layer; 1109 bool existing_layer = false; 1110 1111 if (is_hw_surface) { 1112 auto it = display_surface_layers.find(surface->surface_id()); 1113 1114 if (it != display_surface_layers.end()) { 1115 target_layer = it->second; 1116 existing_layer = true; 1117 } 1118 } else if (gpu_layer_ != nullptr) { 1119 target_layer = gpu_layer_; 1120 existing_layer = true; 1121 } 1122 1123 if (!existing_layer) { 1124 if (active_layer_count_ >= kMaxHardwareLayers) { 1125 ALOGI("HardwareComposer: More than %d hardware layers requested.", 1126 kMaxHardwareLayers); 1127 break; 1128 } else { 1129 target_layer = layers_[active_layer_count_]; 1130 ++active_layer_count_; 1131 } 1132 1133 ALOGD_IF(TRACE, 1134 "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> " 1135 "layer=%zd", 1136 surface->surface_id(), i); 1137 1138 if (is_hw_surface) { 1139 target_layer->Setup(surface, blending, display_transform_, 1140 HWC2_COMPOSITION_DEVICE, i); 1141 } else { 1142 gpu_layer_ = target_layer; 1143 target_layer->Setup(compositor_.GetBuffer(), blending, 1144 display_transform_, HWC2_COMPOSITION_DEVICE, i); 1145 } 1146 } else { 1147 ALOGD_IF(TRACE, 1148 "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d " 1149 "-> layer=%zd", 1150 surface->surface_id(), i); 1151 1152 target_layer->SetBlending(blending); 1153 target_layer->SetZOrderIndex(i); 1154 target_layer->UpdateLayerSettings(); 1155 } 1156 1157 gpu_layer_applied = !is_hw_surface; 1158 } 1159 1160 ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers", 1161 active_layer_count_); 1162 1163 return true; 1164} 1165 1166void HardwareComposer::PostCompositorBuffers() { 1167 ATRACE_NAME("PostCompositorBuffers"); 1168 for (const auto& surface : compositor_surfaces_) { 1169 compositor_.PostBuffer(surface); 1170 } 1171} 1172 1173void HardwareComposer::UpdateFrameTimeHistory( 1174 std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max, 1175 FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) { 1176 while (!backlog->empty()) { 1177 const auto& frame_time_record = backlog->front(); 1178 int64_t end_time = 0; 1179 bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(), 1180 fence_info_buffer, &end_time); 1181 if (frame_finished) { 1182 int64_t frame_duration = end_time - frame_time_record.start_time; 1183 history->AddSample(frame_duration); 1184 // Our backlog is tiny (2 elements), so erasing from the front is ok 1185 backlog->erase(backlog->begin()); 1186 } else { 1187 break; 1188 } 1189 } 1190 1191 if (backlog->size() == static_cast<size_t>(backlog_max)) { 1192 // Yikes, something must've gone wrong if our oldest frame hasn't finished 1193 // yet. Give up on waiting for it. 1194 const auto& stale_frame_time_record = backlog->front(); 1195 int64_t frame_duration = 1196 GetSystemClockNs() - stale_frame_time_record.start_time; 1197 backlog->erase(backlog->begin()); 1198 history->AddSample(frame_duration); 1199 ALOGW("Frame didn't finish after %.1fms", 1200 static_cast<double>(frame_duration) / 1000000); 1201 } 1202} 1203 1204bool HardwareComposer::CheckFrameFinished(int frame_fence_fd, 1205 FenceInfoBuffer* fence_info_buffer, 1206 int64_t* timestamp) { 1207 int result = -1; 1208 int sync_result = sync_wait(frame_fence_fd, 0); 1209 if (sync_result == 0) { 1210 result = 1211 GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp); 1212 if (result < 0) { 1213 ALOGE("Failed getting signaled timestamp from fence"); 1214 } 1215 } else if (errno != ETIME) { 1216 ALOGE("sync_wait on frame fence failed"); 1217 } 1218 return result >= 0; 1219} 1220 1221void HardwareComposer::HandlePendingScreenshots() { 1222 // Take a screenshot of the requested layer, if available. 1223 // TODO(eieio): Look into using virtual displays to composite the layer stack 1224 // into a single output buffer that can be returned to the screenshot clients. 1225 if (active_layer_count_ > 0) { 1226 if (auto screenshot_service = ScreenshotService::GetInstance()) { 1227 if (screenshot_service->IsScreenshotRequestPending()) { 1228 ATRACE_NAME("screenshot"); 1229 screenshot_service->TakeIfNeeded(layers_, compositor_); 1230 } 1231 } else { 1232 ALOGW( 1233 "HardwareComposer::HandlePendingScreenshots: Failed to get " 1234 "screenshot service!"); 1235 } 1236 } 1237} 1238 1239void HardwareComposer::SetVSyncCallback(VSyncCallback callback) { 1240 vsync_callback_ = callback; 1241} 1242 1243void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/, 1244 hwc2_display_t /*display*/) { 1245 // TODO(eieio): implement invalidate callbacks. 1246} 1247 1248void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/, 1249 hwc2_display_t /*display*/, 1250 int64_t /*timestamp*/) { 1251 ATRACE_NAME(__PRETTY_FUNCTION__); 1252 // Intentionally empty. HWC may require a callback to be set to enable vsync 1253 // signals. We bypass this callback thread by monitoring the vsync event 1254 // directly, but signals still need to be enabled. 1255} 1256 1257void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/, 1258 hwc2_display_t /*display*/, 1259 hwc2_connection_t /*connected*/) { 1260 // TODO(eieio): implement display hotplug callbacks. 1261} 1262 1263void HardwareComposer::OnHardwareComposerRefresh() { 1264 // TODO(steventhomas): Handle refresh. 1265} 1266 1267void HardwareComposer::SetBacklightBrightness(int brightness) { 1268 if (backlight_brightness_fd_) { 1269 std::array<char, 32> text; 1270 const int length = snprintf(text.data(), text.size(), "%d", brightness); 1271 write(backlight_brightness_fd_.Get(), text.data(), length); 1272 } 1273} 1274 1275Layer::Layer() 1276 : hwc2_hidl_(nullptr), 1277 surface_index_(-1), 1278 hardware_composer_layer_(0), 1279 display_metrics_(nullptr), 1280 blending_(HWC2_BLEND_MODE_NONE), 1281 transform_(HWC_TRANSFORM_NONE), 1282 composition_type_(HWC2_COMPOSITION_DEVICE), 1283 surface_rect_functions_applied_(false) {} 1284 1285void Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) { 1286 hwc2_hidl_ = hwc2_hidl; 1287 display_metrics_ = metrics; 1288} 1289 1290void Layer::Reset() { 1291 const int ret = acquired_buffer_.Release(std::move(release_fence_)); 1292 ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s", 1293 strerror(-ret)); 1294 1295 if (hwc2_hidl_ != nullptr && hardware_composer_layer_) { 1296 hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_); 1297 hardware_composer_layer_ = 0; 1298 } 1299 1300 surface_index_ = static_cast<size_t>(-1); 1301 blending_ = HWC2_BLEND_MODE_NONE; 1302 transform_ = HWC_TRANSFORM_NONE; 1303 composition_type_ = HWC2_COMPOSITION_DEVICE; 1304 direct_buffer_ = nullptr; 1305 surface_ = nullptr; 1306 acquire_fence_fd_.Close(); 1307 surface_rect_functions_applied_ = false; 1308} 1309 1310void Layer::Setup(const std::shared_ptr<DisplaySurface>& surface, 1311 hwc2_blend_mode_t blending, hwc_transform_t transform, 1312 hwc2_composition_t composition_type, size_t index) { 1313 Reset(); 1314 surface_index_ = index; 1315 surface_ = surface; 1316 blending_ = blending; 1317 transform_ = transform; 1318 composition_type_ = composition_type; 1319 CommonLayerSetup(); 1320} 1321 1322void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer, 1323 hwc2_blend_mode_t blending, hwc_transform_t transform, 1324 hwc2_composition_t composition_type, size_t z_order) { 1325 Reset(); 1326 surface_index_ = z_order; 1327 direct_buffer_ = buffer; 1328 blending_ = blending; 1329 transform_ = transform; 1330 composition_type_ = composition_type; 1331 CommonLayerSetup(); 1332} 1333 1334void Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) { 1335 direct_buffer_ = buffer; 1336} 1337 1338void Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; } 1339 1340void Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; } 1341 1342IonBuffer* Layer::GetBuffer() { 1343 if (direct_buffer_) 1344 return direct_buffer_.get(); 1345 else if (acquired_buffer_.IsAvailable()) 1346 return acquired_buffer_.buffer()->buffer(); 1347 else 1348 return nullptr; 1349} 1350 1351void Layer::UpdateLayerSettings() { 1352 if (!IsLayerSetup()) { 1353 ALOGE("HardwareComposer: Trying to update layers data on an unused layer."); 1354 return; 1355 } 1356 1357 int32_t ret = HWC2_ERROR_NONE; 1358 1359 hwc2_display_t display = HWC_DISPLAY_PRIMARY; 1360 1361 ret = (int32_t)hwc2_hidl_->setLayerCompositionType( 1362 display, hardware_composer_layer_, 1363 (Hwc2::IComposerClient::Composition)composition_type_); 1364 ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d", 1365 ret); 1366 // ret = (int32_t) hwc2_hidl_->setLayerTransform(display, 1367 // hardware_composer_layer_, 1368 // (Hwc2::IComposerClient::Transform) 1369 // transform_); 1370 // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret); 1371 1372 // ret = hwc2_funcs_->set_layer_blend_mode_fn_( 1373 // hardware_composer_device_, display, hardware_composer_layer_, 1374 // blending_); 1375 ret = (int32_t)hwc2_hidl_->setLayerBlendMode( 1376 display, hardware_composer_layer_, 1377 (Hwc2::IComposerClient::BlendMode)blending_); 1378 ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret); 1379 1380 Hwc2::IComposerClient::Rect display_frame; 1381 display_frame.left = 0; 1382 display_frame.top = 0; 1383 display_frame.right = display_metrics_->width; 1384 display_frame.bottom = display_metrics_->height; 1385 ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame( 1386 display, hardware_composer_layer_, display_frame); 1387 ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d", 1388 ret); 1389 1390 std::vector<Hwc2::IComposerClient::Rect> visible_region(1); 1391 visible_region[0] = display_frame; 1392 ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion( 1393 display, hardware_composer_layer_, visible_region); 1394 ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d", 1395 ret); 1396 1397 ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display, 1398 hardware_composer_layer_, 1.0f); 1399 ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret); 1400 1401 ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_, 1402 surface_index_); 1403 ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret); 1404} 1405 1406void Layer::CommonLayerSetup() { 1407 int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY, 1408 &hardware_composer_layer_); 1409 1410 ALOGE_IF(ret, 1411 "HardwareComposer: Failed to create layer on primary display : %d", 1412 ret); 1413 1414 UpdateLayerSettings(); 1415} 1416 1417void Layer::Prepare() { 1418 int right, bottom; 1419 sp<GraphicBuffer> handle; 1420 1421 if (surface_) { 1422 // Only update the acquired buffer when one is either available or this is 1423 // the first time through. 1424 if (surface_->IsBufferAvailable()) { 1425 // If we previously set this to a solid color layer to stall for time, 1426 // revert it to a device layer. 1427 if (acquired_buffer_.IsEmpty() && 1428 composition_type_ != HWC2_COMPOSITION_DEVICE) { 1429 composition_type_ = HWC2_COMPOSITION_DEVICE; 1430 hwc2_hidl_->setLayerCompositionType( 1431 HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 1432 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE); 1433 } 1434 1435 DebugHudData::data.AddLayerFrame(surface_index_); 1436 acquired_buffer_.Release(std::move(release_fence_)); 1437 acquired_buffer_ = surface_->AcquireCurrentBuffer(); 1438 1439 // Basic latency stopgap for when the application misses a frame: 1440 // If the application recovers on the 2nd or 3rd (etc) frame after 1441 // missing, this code will skip a frame to catch up by checking if 1442 // the next frame is also available. 1443 if (surface_->IsBufferAvailable()) { 1444 DebugHudData::data.SkipLayerFrame(surface_index_); 1445 ATRACE_NAME("DropToCatchUp"); 1446 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id()); 1447 acquired_buffer_ = surface_->AcquireCurrentBuffer(); 1448 } 1449 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id()); 1450 } else if (acquired_buffer_.IsEmpty()) { 1451 // While we are waiting for a buffer, set this to be an empty layer 1452 if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) { 1453 composition_type_ = HWC2_COMPOSITION_SOLID_COLOR; 1454 hwc2_hidl_->setLayerCompositionType( 1455 HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 1456 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR); 1457 1458 Hwc2::IComposerClient::Color layer_color = { 1459 0, 0, 0, 0, 1460 }; 1461 hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 1462 layer_color); 1463 } 1464 return; 1465 } 1466 right = acquired_buffer_.buffer()->width(); 1467 bottom = acquired_buffer_.buffer()->height(); 1468 handle = acquired_buffer_.buffer()->buffer()->buffer(); 1469 acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release()); 1470 } else { 1471 // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the 1472 // mechanism to accept distorted layers from VrCore. 1473 right = direct_buffer_->width(); 1474 bottom = direct_buffer_->height(); 1475 handle = direct_buffer_->buffer(); 1476 acquire_fence_fd_.Close(); 1477 } 1478 1479 int32_t ret = HWC2_ERROR_NONE; 1480 1481 if (composition_type_ == HWC2_COMPOSITION_DEVICE) { 1482 ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY, 1483 hardware_composer_layer_, 0, 1484 handle, 1485 acquire_fence_fd_.Get()); 1486 1487 ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret); 1488 } 1489 1490 if (!surface_rect_functions_applied_) { 1491 Hwc2::IComposerClient::FRect crop_rect = { 1492 0, 0, static_cast<float>(right), static_cast<float>(bottom), 1493 }; 1494 hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY, 1495 hardware_composer_layer_, crop_rect); 1496 1497 ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d", 1498 ret); 1499 1500// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where 1501// it must/cannot be called? 1502#ifdef QCOM_BSP 1503 hwc_rect_t damage_rect = { 1504 0, 0, right, bottom, 1505 }; 1506 hwc_region_t damage = { 1507 1, &damage_rect, 1508 }; 1509 // ret = hwc2_funcs_->set_layer_surface_damage( 1510 // hardware_composer_device_, HWC_DISPLAY_PRIMARY, 1511 // hardware_composer_layer_, damage); 1512 // uses a std::vector as the listing 1513 // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY, 1514 // hardware_composer_layer_, vector here); 1515 1516 ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d", 1517 ret); 1518#endif 1519 1520 surface_rect_functions_applied_ = true; 1521 } 1522} 1523 1524void Layer::Finish(int release_fence_fd) { 1525 release_fence_.Reset(release_fence_fd); 1526} 1527 1528void Layer::Drop() { acquire_fence_fd_.Close(); } 1529 1530} // namespace dvr 1531} // namespace android 1532