diff options
author | Corey Tabaka | 2017-08-22 13:59:15 -0500 |
---|---|---|
committer | Corey Tabaka | 2017-09-11 16:41:31 -0500 |
commit | 7024b8f8925de0888c6c9d2fa929980c50dbc072 (patch) | |
tree | 565a9cccd3716da8de08ae695a2792f7a377dd5e | |
parent | f7e10c82b04e0f6a2a445609144612ac2f47c8a8 (diff) | |
download | frameworks-native-7024b8f8925de0888c6c9d2fa929980c50dbc072.tar.gz frameworks-native-7024b8f8925de0888c6c9d2fa929980c50dbc072.tar.xz frameworks-native-7024b8f8925de0888c6c9d2fa929980c50dbc072.zip |
Keep standalone devices in VrFlinger mode.
Avoid unnecessary tear-down and bring up of HWC client in standalone
devices. This saves time during screen-on because standalone devices
only use VrFlinger mode.
Remove dead code that used to check the panel driver for missed frames.
No drivers expose the sysfs node that provided this function anymore.
Test: Manual testing. Observe stable DON/DOFF behavior.
Bug: 65248224
Change-Id: Id9ebb76982621848d97792496a09b6da8c4e5928
-rw-r--r-- | libs/vr/libvrflinger/hardware_composer.cpp | 110 | ||||
-rw-r--r-- | libs/vr/libvrflinger/hardware_composer.h | 7 |
2 files changed, 40 insertions, 77 deletions
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp index c19fb249d..0bf1d2b5a 100644 --- a/libs/vr/libvrflinger/hardware_composer.cpp +++ b/libs/vr/libvrflinger/hardware_composer.cpp | |||
@@ -44,9 +44,8 @@ namespace { | |||
44 | const char kBacklightBrightnessSysFile[] = | 44 | const char kBacklightBrightnessSysFile[] = |
45 | "/sys/class/leds/lcd-backlight/brightness"; | 45 | "/sys/class/leds/lcd-backlight/brightness"; |
46 | 46 | ||
47 | const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp"; | ||
48 | |||
49 | const char kDvrPerformanceProperty[] = "sys.dvr.performance"; | 47 | const char kDvrPerformanceProperty[] = "sys.dvr.performance"; |
48 | const char kDvrStandaloneProperty[] = "ro.boot.vr"; | ||
50 | 49 | ||
51 | const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns"; | 50 | const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns"; |
52 | 51 | ||
@@ -101,6 +100,8 @@ bool HardwareComposer::Initialize( | |||
101 | return false; | 100 | return false; |
102 | } | 101 | } |
103 | 102 | ||
103 | is_standalone_device_ = property_get_bool(kDvrStandaloneProperty, false); | ||
104 | |||
104 | request_display_callback_ = request_display_callback; | 105 | request_display_callback_ = request_display_callback; |
105 | 106 | ||
106 | HWC::Error error = HWC::Error::None; | 107 | HWC::Error error = HWC::Error::None; |
@@ -198,10 +199,17 @@ void HardwareComposer::UpdatePostThreadState(PostThreadStateType state, | |||
198 | } | 199 | } |
199 | 200 | ||
200 | void HardwareComposer::OnPostThreadResumed() { | 201 | void HardwareComposer::OnPostThreadResumed() { |
201 | composer_.reset(new Hwc2::Composer(false)); | 202 | // Phones create a new composer client on resume and destroy it on pause. |
202 | composer_callback_ = new ComposerCallback; | 203 | // Standalones only create the composer client once and then use SetPowerMode |
203 | composer_->registerCallback(composer_callback_); | 204 | // to control the screen on pause/resume. |
204 | Layer::SetComposer(composer_.get()); | 205 | if (!is_standalone_device_ || !composer_) { |
206 | composer_.reset(new Hwc2::Composer(false)); | ||
207 | composer_callback_ = new ComposerCallback; | ||
208 | composer_->registerCallback(composer_callback_); | ||
209 | Layer::SetComposer(composer_.get()); | ||
210 | } else { | ||
211 | SetPowerMode(true); | ||
212 | } | ||
205 | 213 | ||
206 | EnableVsync(true); | 214 | EnableVsync(true); |
207 | 215 | ||
@@ -224,9 +232,13 @@ void HardwareComposer::OnPostThreadPaused() { | |||
224 | EnableVsync(false); | 232 | EnableVsync(false); |
225 | } | 233 | } |
226 | 234 | ||
227 | composer_callback_ = nullptr; | 235 | if (!is_standalone_device_) { |
228 | composer_.reset(nullptr); | 236 | composer_callback_ = nullptr; |
229 | Layer::SetComposer(nullptr); | 237 | composer_.reset(nullptr); |
238 | Layer::SetComposer(nullptr); | ||
239 | } else { | ||
240 | SetPowerMode(false); | ||
241 | } | ||
230 | 242 | ||
231 | // Trigger target-specific performance mode change. | 243 | // Trigger target-specific performance mode change. |
232 | property_set(kDvrPerformanceProperty, "idle"); | 244 | property_set(kDvrPerformanceProperty, "idle"); |
@@ -256,6 +268,12 @@ HWC::Error HardwareComposer::EnableVsync(bool enabled) { | |||
256 | : HWC2_VSYNC_DISABLE)); | 268 | : HWC2_VSYNC_DISABLE)); |
257 | } | 269 | } |
258 | 270 | ||
271 | HWC::Error HardwareComposer::SetPowerMode(bool active) { | ||
272 | HWC::PowerMode power_mode = active ? HWC::PowerMode::On : HWC::PowerMode::Off; | ||
273 | return composer_->setPowerMode( | ||
274 | HWC_DISPLAY_PRIMARY, power_mode.cast<Hwc2::IComposerClient::PowerMode>()); | ||
275 | } | ||
276 | |||
259 | HWC::Error HardwareComposer::Present(hwc2_display_t display) { | 277 | HWC::Error HardwareComposer::Present(hwc2_display_t display) { |
260 | int32_t present_fence; | 278 | int32_t present_fence; |
261 | HWC::Error error = composer_->presentDisplay(display, &present_fence); | 279 | HWC::Error error = composer_->presentDisplay(display, &present_fence); |
@@ -459,7 +477,7 @@ void HardwareComposer::SetDisplaySurfaces( | |||
459 | pending_surfaces_ = std::move(surfaces); | 477 | pending_surfaces_ = std::move(surfaces); |
460 | } | 478 | } |
461 | 479 | ||
462 | if (request_display_callback_) | 480 | if (request_display_callback_ && (!is_standalone_device_ || !composer_)) |
463 | request_display_callback_(!display_idle); | 481 | request_display_callback_(!display_idle); |
464 | 482 | ||
465 | // Set idle state based on whether there are any surfaces to handle. | 483 | // Set idle state based on whether there are any surfaces to handle. |
@@ -569,48 +587,6 @@ int HardwareComposer::PostThreadPollInterruptible( | |||
569 | } | 587 | } |
570 | } | 588 | } |
571 | 589 | ||
572 | // Reads the value of the display driver wait_pingpong state. Returns 0 or 1 | ||
573 | // (the value of the state) on success or a negative error otherwise. | ||
574 | // TODO(eieio): This is pretty driver specific, this should be moved to a | ||
575 | // separate class eventually. | ||
576 | int HardwareComposer::ReadWaitPPState() { | ||
577 | // Gracefully handle when the kernel does not support this feature. | ||
578 | if (!primary_display_wait_pp_fd_) | ||
579 | return 0; | ||
580 | |||
581 | const int wait_pp_fd = primary_display_wait_pp_fd_.Get(); | ||
582 | int ret, error; | ||
583 | |||
584 | ret = lseek(wait_pp_fd, 0, SEEK_SET); | ||
585 | if (ret < 0) { | ||
586 | error = errno; | ||
587 | ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s", | ||
588 | strerror(error)); | ||
589 | return -error; | ||
590 | } | ||
591 | |||
592 | char data = -1; | ||
593 | ret = read(wait_pp_fd, &data, sizeof(data)); | ||
594 | if (ret < 0) { | ||
595 | error = errno; | ||
596 | ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s", | ||
597 | strerror(error)); | ||
598 | return -error; | ||
599 | } | ||
600 | |||
601 | switch (data) { | ||
602 | case '0': | ||
603 | return 0; | ||
604 | case '1': | ||
605 | return 1; | ||
606 | default: | ||
607 | ALOGE( | ||
608 | "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d", | ||
609 | data); | ||
610 | return -EINVAL; | ||
611 | } | ||
612 | } | ||
613 | |||
614 | // Waits for the next vsync and returns the timestamp of the vsync event. If | 590 | // Waits for the next vsync and returns the timestamp of the vsync event. If |
615 | // vsync already passed since the last call, returns the latest vsync timestamp | 591 | // vsync already passed since the last call, returns the latest vsync timestamp |
616 | // instead of blocking. | 592 | // instead of blocking. |
@@ -640,8 +616,8 @@ int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) { | |||
640 | return -error; | 616 | return -error; |
641 | } | 617 | } |
642 | 618 | ||
643 | return PostThreadPollInterruptible( | 619 | return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN, |
644 | vsync_sleep_timer_fd_, POLLIN, /*timeout_ms*/ -1); | 620 | /*timeout_ms*/ -1); |
645 | } | 621 | } |
646 | 622 | ||
647 | void HardwareComposer::PostThread() { | 623 | void HardwareComposer::PostThread() { |
@@ -664,15 +640,6 @@ void HardwareComposer::PostThread() { | |||
664 | strerror(errno)); | 640 | strerror(errno)); |
665 | #endif // ENABLE_BACKLIGHT_BRIGHTNESS | 641 | #endif // ENABLE_BACKLIGHT_BRIGHTNESS |
666 | 642 | ||
667 | // Open the wait pingpong status node for the primary display. | ||
668 | // TODO(eieio): Move this into a platform-specific class. | ||
669 | primary_display_wait_pp_fd_ = | ||
670 | LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY); | ||
671 | ALOGW_IF( | ||
672 | !primary_display_wait_pp_fd_, | ||
673 | "HardwareComposer: Failed to open wait_pp node for primary display: %s", | ||
674 | strerror(errno)); | ||
675 | |||
676 | // Create a timerfd based on CLOCK_MONOTINIC. | 643 | // Create a timerfd based on CLOCK_MONOTINIC. |
677 | vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0)); | 644 | vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0)); |
678 | LOG_ALWAYS_FATAL_IF( | 645 | LOG_ALWAYS_FATAL_IF( |
@@ -895,15 +862,12 @@ void HardwareComposer::SetBacklightBrightness(int brightness) { | |||
895 | 862 | ||
896 | HardwareComposer::ComposerCallback::ComposerCallback() { | 863 | HardwareComposer::ComposerCallback::ComposerCallback() { |
897 | vsync_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); | 864 | vsync_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); |
898 | LOG_ALWAYS_FATAL_IF( | 865 | LOG_ALWAYS_FATAL_IF(!vsync_event_fd_, "Failed to create vsync event fd : %s", |
899 | !vsync_event_fd_, | 866 | strerror(errno)); |
900 | "Failed to create vsync event fd : %s", | ||
901 | strerror(errno)); | ||
902 | } | 867 | } |
903 | 868 | ||
904 | Return<void> HardwareComposer::ComposerCallback::onHotplug( | 869 | Return<void> HardwareComposer::ComposerCallback::onHotplug( |
905 | Hwc2::Display /*display*/, | 870 | Hwc2::Display /*display*/, IComposerCallback::Connection /*conn*/) { |
906 | IComposerCallback::Connection /*conn*/) { | ||
907 | return Void(); | 871 | return Void(); |
908 | } | 872 | } |
909 | 873 | ||
@@ -912,8 +876,8 @@ Return<void> HardwareComposer::ComposerCallback::onRefresh( | |||
912 | return hardware::Void(); | 876 | return hardware::Void(); |
913 | } | 877 | } |
914 | 878 | ||
915 | Return<void> HardwareComposer::ComposerCallback::onVsync( | 879 | Return<void> HardwareComposer::ComposerCallback::onVsync(Hwc2::Display display, |
916 | Hwc2::Display display, int64_t timestamp) { | 880 | int64_t timestamp) { |
917 | if (display == HWC_DISPLAY_PRIMARY) { | 881 | if (display == HWC_DISPLAY_PRIMARY) { |
918 | std::lock_guard<std::mutex> lock(vsync_mutex_); | 882 | std::lock_guard<std::mutex> lock(vsync_mutex_); |
919 | vsync_time_ = timestamp; | 883 | vsync_time_ = timestamp; |
@@ -923,8 +887,8 @@ Return<void> HardwareComposer::ComposerCallback::onVsync( | |||
923 | return Void(); | 887 | return Void(); |
924 | } | 888 | } |
925 | 889 | ||
926 | const pdx::LocalHandle& | 890 | const pdx::LocalHandle& HardwareComposer::ComposerCallback::GetVsyncEventFd() |
927 | HardwareComposer::ComposerCallback::GetVsyncEventFd() const { | 891 | const { |
928 | return vsync_event_fd_; | 892 | return vsync_event_fd_; |
929 | } | 893 | } |
930 | 894 | ||
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h index 550e6877f..793c3e887 100644 --- a/libs/vr/libvrflinger/hardware_composer.h +++ b/libs/vr/libvrflinger/hardware_composer.h | |||
@@ -336,6 +336,7 @@ class HardwareComposer { | |||
336 | HWCDisplayMetrics* out_metrics) const; | 336 | HWCDisplayMetrics* out_metrics) const; |
337 | 337 | ||
338 | HWC::Error EnableVsync(bool enabled); | 338 | HWC::Error EnableVsync(bool enabled); |
339 | HWC::Error SetPowerMode(bool active); | ||
339 | 340 | ||
340 | class ComposerCallback : public Hwc2::IComposerCallback { | 341 | class ComposerCallback : public Hwc2::IComposerCallback { |
341 | public: | 342 | public: |
@@ -394,7 +395,7 @@ class HardwareComposer { | |||
394 | int WaitForVSync(int64_t* timestamp); | 395 | int WaitForVSync(int64_t* timestamp); |
395 | int SleepUntil(int64_t wakeup_timestamp); | 396 | int SleepUntil(int64_t wakeup_timestamp); |
396 | 397 | ||
397 | bool IsFramePendingInDriver() { return ReadWaitPPState() == 1; } | 398 | bool IsFramePendingInDriver() { return false; } |
398 | 399 | ||
399 | // Reconfigures the layer stack if the display surfaces changed since the last | 400 | // Reconfigures the layer stack if the display surfaces changed since the last |
400 | // frame. Called only from the post thread. | 401 | // frame. Called only from the post thread. |
@@ -413,6 +414,7 @@ class HardwareComposer { | |||
413 | void UpdateConfigBuffer(); | 414 | void UpdateConfigBuffer(); |
414 | 415 | ||
415 | bool initialized_; | 416 | bool initialized_; |
417 | bool is_standalone_device_; | ||
416 | 418 | ||
417 | std::unique_ptr<Hwc2::Composer> composer_; | 419 | std::unique_ptr<Hwc2::Composer> composer_; |
418 | sp<ComposerCallback> composer_callback_; | 420 | sp<ComposerCallback> composer_callback_; |
@@ -455,9 +457,6 @@ class HardwareComposer { | |||
455 | // Backlight LED brightness sysfs node. | 457 | // Backlight LED brightness sysfs node. |
456 | pdx::LocalHandle backlight_brightness_fd_; | 458 | pdx::LocalHandle backlight_brightness_fd_; |
457 | 459 | ||
458 | // Primary display wait_pingpong state sysfs node. | ||
459 | pdx::LocalHandle primary_display_wait_pp_fd_; | ||
460 | |||
461 | // VSync sleep timerfd. | 460 | // VSync sleep timerfd. |
462 | pdx::LocalHandle vsync_sleep_timer_fd_; | 461 | pdx::LocalHandle vsync_sleep_timer_fd_; |
463 | 462 | ||