From: Pallavi G Date: Mon, 20 Feb 2017 09:40:18 +0000 (+0530) Subject: Added the doze power mode support X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4704f1d95f1f777c00ee312e8a1276fcfc23c694;p=android-x86%2Fexternal-IA-Hardware-Composer.git Added the doze power mode support Added the suport for the doze and doze suspend power modes. For more details about doze and doze suspend refer the below link https://developer.android.com/training/monitoring-device-state/doze-standby.html Jira: IAHWC-21 Test: Not able to test the exact doze path device not entering into the idle mode Signed-off-by: Pallavi G --- diff --git a/common/display/display.cpp b/common/display/display.cpp index 50cfb9e..14512fb 100644 --- a/common/display/display.cpp +++ b/common/display/display.cpp @@ -184,8 +184,10 @@ bool Display::GetActiveConfig(uint32_t *config) { return true; } -bool Display::SetDpmsMode(uint32_t dpms_mode) { - return display_queue_->SetDpmsMode(dpms_mode); +bool Display::SetPowerMode(uint32_t power_mode) { + uint32_t power_mode_ = power_mode; + + return display_queue_->SetPowerMode(power_mode); } bool Display::Present(std::vector &source_layers) { diff --git a/common/display/display.h b/common/display/display.h index 32e75a1..a356642 100644 --- a/common/display/display.h +++ b/common/display/display.h @@ -67,6 +67,10 @@ class Display : public NativeDisplay { return refresh_; } + uint32_t PowerMode() const override { + return power_mode_; + } + bool GetDisplayAttribute(uint32_t config, HWCDisplayAttribute attribute, int32_t *value) override; @@ -75,7 +79,7 @@ class Display : public NativeDisplay { bool SetActiveConfig(uint32_t config) override; bool GetActiveConfig(uint32_t *config) override; - bool SetDpmsMode(uint32_t dpms_mode) override; + bool SetPowerMode(uint32_t power_mode) override; bool Present(std::vector &source_layers) override; @@ -117,6 +121,7 @@ class Display : public NativeDisplay { float refresh_; bool is_connected_; bool is_powered_off_; + uint32_t power_mode_; std::unique_ptr flip_handler_; std::unique_ptr display_queue_; }; diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index ab425dc..d51b1d4 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -106,7 +106,7 @@ bool DisplayQueue::Initialize(uint32_t width, uint32_t height, uint32_t pipe, void DisplayQueue::Exit() { IHOTPLUGEVENTTRACE("DisplayQueue::Exit recieved."); - HWCThread::Exit(); + HandleExit(); } bool DisplayQueue::GetFence(drmModeAtomicReqPtr property_set, @@ -159,27 +159,29 @@ bool DisplayQueue::ApplyPendingModeset(drmModeAtomicReqPtr property_set) { return true; } -bool DisplayQueue::SetDpmsMode(uint32_t dpms_mode) { +bool DisplayQueue::SetPowerMode(uint32_t power_mode) { ScopedSpinLock lock(spin_lock_); - if (dpms_mode_ == dpms_mode) + + if ((power_mode == kOff) || (power_mode == kDoze)) { + dpms_mode_ = DRM_MODE_DPMS_OFF; + Flush(); + HWCThread::ConditionalSuspend(); + drmModeConnectorSetProperty(gpu_fd_, connector_, dpms_prop_, dpms_mode_); return true; + } - dpms_mode_ = dpms_mode; - if (dpms_mode_ == DRM_MODE_DPMS_OFF) { - Exit(); + if (power_mode == kDozeSuspend) { + Flush(); + HWCThread::ConditionalSuspend(); return true; } - if (dpms_mode_ == DRM_MODE_DPMS_ON) { + if (power_mode == kOn) { + dpms_mode_ = DRM_MODE_DPMS_ON; needs_modeset_ = true; - if (!InitWorker()) { - ETRACE("Failed to initalize thread for DisplayQueue. %s", PRINTERROR()); - return false; - } + drmModeConnectorSetProperty(gpu_fd_, connector_, dpms_prop_, dpms_mode_); } - drmModeConnectorSetProperty(gpu_fd_, connector_, dpms_prop_, dpms_mode); - return true; } @@ -225,8 +227,19 @@ bool DisplayQueue::QueueUpdate(std::vector& source_layers) { return true; } +void DisplayQueue::GetNextQueueItem(DisplayQueueItem& item) { + display_queue_.lock(); + DisplayQueueItem& queue_item = queue_.front(); + item.layers_.swap(queue_item.layers_); + item.layers_rects_.swap(queue_item.layers_rects_); + item.sync_object_.reset(queue_item.sync_object_.release()); + queue_.pop(); + display_queue_.unlock(); +} + void DisplayQueue::HandleUpdateRequest(DisplayQueueItem& queue_item) { CTRACE(); + ScopedSpinLock lock(spin_lock_); // Reset any DisplayQueue Manager and Compositor state. if (!display_plane_manager_->BeginFrameUpdate(&queue_item.layers_)) { @@ -324,18 +337,27 @@ void DisplayQueue::HandleRoutine() { ConditionalSuspend(); return; } + display_queue_.unlock(); - DisplayQueueItem& queue_item = queue_.front(); DisplayQueueItem item; - item.layers_.swap(queue_item.layers_); - item.layers_rects_.swap(queue_item.layers_rects_); - item.sync_object_.reset(queue_item.sync_object_.release()); - queue_.pop(); - display_queue_.unlock(); + GetNextQueueItem(item); HandleUpdateRequest(item); } +void DisplayQueue::Flush() { + display_queue_.lock(); + + while (queue_.size()) { + DisplayQueueItem item; + + GetNextQueueItem(item); + HandleUpdateRequest(item); + } + + display_queue_.unlock(); +} + void DisplayQueue::HandleExit() { ScopedSpinLocks lock(spin_lock_, display_queue_); ScopedDrmAtomicReqPtr pset(drmModeAtomicAlloc()); @@ -344,6 +366,8 @@ void DisplayQueue::HandleExit() { return; } + Flush(); + bool active = false; int ret = drmModeAtomicAddProperty(pset.get(), crtc_id_, active_prop_, active) < 0; @@ -361,6 +385,7 @@ void DisplayQueue::HandleExit() { std::queue().swap(queue_); current_sync_.reset(nullptr); compositor_.Reset(); + HWCThread::Exit(); } void DisplayQueue::GetDrmObjectProperty(const char* name, diff --git a/common/display/displayqueue.h b/common/display/displayqueue.h index 5c42641..fa06160 100644 --- a/common/display/displayqueue.h +++ b/common/display/displayqueue.h @@ -52,7 +52,7 @@ class DisplayQueue : public HWCThread { void Exit(); bool QueueUpdate(std::vector& source_layers); - bool SetDpmsMode(uint32_t dpms_mode); + bool SetPowerMode(uint32_t power_mode); protected: void HandleRoutine() override; @@ -65,6 +65,8 @@ class DisplayQueue : public HWCThread { std::unique_ptr sync_object_; }; + void GetNextQueueItem(DisplayQueueItem& item); + void Flush(); void HandleUpdateRequest(DisplayQueueItem& queue_item); bool ApplyPendingModeset(drmModeAtomicReqPtr property_set); bool GetFence(drmModeAtomicReqPtr property_set, uint64_t* out_fence); diff --git a/common/display/headless.cpp b/common/display/headless.cpp index 28aabcc..4fca20d 100644 --- a/common/display/headless.cpp +++ b/common/display/headless.cpp @@ -113,7 +113,7 @@ bool Headless::GetActiveConfig(uint32_t *config) { return true; } -bool Headless::SetDpmsMode(uint32_t /*dpms_mode*/) { +bool Headless::SetPowerMode(uint32_t /*power_mode*/) { return true; } diff --git a/common/display/headless.h b/common/display/headless.h index f1489f9..3d8e223 100644 --- a/common/display/headless.h +++ b/common/display/headless.h @@ -53,6 +53,10 @@ class Headless : public NativeDisplay { return 0; } + uint32_t PowerMode() const override { + return 0; + } + bool GetDisplayAttribute(uint32_t config, HWCDisplayAttribute attribute, int32_t *value) override; @@ -61,7 +65,7 @@ class Headless : public NativeDisplay { bool SetActiveConfig(uint32_t config) override; bool GetActiveConfig(uint32_t *config) override; - bool SetDpmsMode(uint32_t dpms_mode) override; + bool SetPowerMode(uint32_t power_mode) override; bool Present(std::vector &source_layers) override; diff --git a/os/android/drmhwctwo.cpp b/os/android/drmhwctwo.cpp index bc1a19d..fd2b180 100644 --- a/os/android/drmhwctwo.cpp +++ b/os/android/drmhwctwo.cpp @@ -355,7 +355,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) { HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) { supported(__func__); - *support = 0; + *support = true; return HWC2::Error::None; } @@ -396,6 +396,14 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { uint32_t client_z_order = 0; *retire_fence = -1; std::map z_map; + + // if the power mode is doze suspend then its the hint that the drawing + // into the display has suspended and remain in the low power state and + // continue displaying the current state and stop applying display + // update from the client + if (display_->PowerMode() == HWC2_POWER_MODE_DOZE_SUSPEND) + return HWC2::Error::None; + for (std::pair &l : layers_) { switch (l.second.validated_type()) { case HWC2::Composition::Device: @@ -495,21 +503,27 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer, HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) { supported(__func__); - uint64_t dpms_value = 0; + uint32_t power_mode = 0; auto mode = static_cast(mode_in); switch (mode) { case HWC2::PowerMode::Off: - dpms_value = DRM_MODE_DPMS_OFF; + power_mode = HWC2_POWER_MODE_OFF; + break; + case HWC2::PowerMode::Doze: + power_mode = HWC2_POWER_MODE_DOZE; + break; + case HWC2::PowerMode::DozeSuspend: + power_mode = HWC2_POWER_MODE_DOZE_SUSPEND; break; case HWC2::PowerMode::On: - dpms_value = DRM_MODE_DPMS_ON; + power_mode = HWC2_POWER_MODE_ON; break; default: ALOGI("Power mode %d is unsupported\n", mode); - return HWC2::Error::Unsupported; + return HWC2::Error::BadParameter; }; - display_->SetDpmsMode(dpms_value); + display_->SetPowerMode(power_mode); return HWC2::Error::None; } @@ -544,7 +558,10 @@ HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, #ifdef DISABLE_OVERLAY_USAGE layer.set_validated_type(HWC2::Composition::Client); #else - layer.set_validated_type(layer.sf_type()); + if (display_->PowerMode() == HWC2_POWER_MODE_DOZE_SUSPEND) + layer.set_validated_type(HWC2::Composition::Client); + else + layer.set_validated_type(layer.sf_type()); #endif break; } diff --git a/public/hwcdefs.h b/public/hwcdefs.h index e499b19..fd584a5 100644 --- a/public/hwcdefs.h +++ b/public/hwcdefs.h @@ -63,5 +63,14 @@ enum class DisplayType : int32_t { kHeadless = 3 }; +enum DisplayPowerMode { + kOff = 0, // Display is off + kDoze = 1, // Display is off and used by the app during any inactivity + // when the device is on battery + kOn = 2, // Display is on + kDozeSuspend = 3 // Dispaly in low power mode and stop applying + // updates from the client +}; + } // namespace hwcomposer #endif // PUBLIC_HWCDEFS_H_ diff --git a/public/nativedisplay.h b/public/nativedisplay.h index e7c08ba..4944763 100644 --- a/public/nativedisplay.h +++ b/public/nativedisplay.h @@ -57,6 +57,8 @@ class NativeDisplay { virtual int32_t GetRefreshRate() const = 0; + virtual uint32_t PowerMode() const = 0; + virtual bool GetDisplayAttribute(uint32_t config, HWCDisplayAttribute attribute, int32_t *value) = 0; @@ -66,7 +68,7 @@ class NativeDisplay { virtual bool SetActiveConfig(uint32_t config) = 0; virtual bool GetActiveConfig(uint32_t *config) = 0; - virtual bool SetDpmsMode(uint32_t dpms_mode) = 0; + virtual bool SetPowerMode(uint32_t power_mode) = 0; virtual bool Present(std::vector &source_layers) = 0;