diff options
author | TreeHugger Robot | 2017-09-12 18:44:31 -0500 |
---|---|---|
committer | Android (Google) Code Review | 2017-09-12 18:44:31 -0500 |
commit | 4b58ec86456ec8d691e6b8720d1240f30a456e58 (patch) | |
tree | 4c87f4595ca55b604f03c8fb011c0c256dfc5c44 | |
parent | 9e6c95deda2649b510261fbf3afdee7fb955266b (diff) | |
parent | 7024b8f8925de0888c6c9d2fa929980c50dbc072 (diff) | |
download | frameworks-native-4b58ec86456ec8d691e6b8720d1240f30a456e58.tar.gz frameworks-native-4b58ec86456ec8d691e6b8720d1240f30a456e58.tar.xz frameworks-native-4b58ec86456ec8d691e6b8720d1240f30a456e58.zip |
Merge "Keep standalone devices in VrFlinger mode." into oc-mr1-dev
-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 | ||