OSDN Git Service

Added the doze power mode support
authorPallavi G <pallavi.g@intel.com>
Mon, 20 Feb 2017 09:40:18 +0000 (15:10 +0530)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Wed, 1 Mar 2017 19:16:09 +0000 (11:16 -0800)
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 <pallavi.g@intel.com>
common/display/display.cpp
common/display/display.h
common/display/displayqueue.cpp
common/display/displayqueue.h
common/display/headless.cpp
common/display/headless.h
os/android/drmhwctwo.cpp
public/hwcdefs.h
public/nativedisplay.h

index 50cfb9e..14512fb 100644 (file)
@@ -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<HwcLayer *> &source_layers) {
index 32e75a1..a356642 100644 (file)
@@ -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<HwcLayer *> &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<PageFlipEventHandler> flip_handler_;
   std::unique_ptr<DisplayQueue> display_queue_;
 };
index ab425dc..d51b1d4 100644 (file)
@@ -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<HwcLayer*>& 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<DisplayQueueItem>().swap(queue_);
   current_sync_.reset(nullptr);
   compositor_.Reset();
+  HWCThread::Exit();
 }
 
 void DisplayQueue::GetDrmObjectProperty(const char* name,
index 5c42641..fa06160 100644 (file)
@@ -52,7 +52,7 @@ class DisplayQueue : public HWCThread {
   void Exit();
 
   bool QueueUpdate(std::vector<HwcLayer*>& 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<NativeSync> 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);
index 28aabcc..4fca20d 100644 (file)
@@ -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;
 }
 
index f1489f9..3d8e223 100644 (file)
@@ -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<HwcLayer *> &source_layers) override;
 
index bc1a19d..fd2b180 100644 (file)
@@ -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<uint32_t, DrmHwcTwo::HwcLayer *> 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<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &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<HWC2::PowerMode>(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;
       }
index e499b19..fd584a5 100644 (file)
@@ -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_
index e7c08ba..4944763 100644 (file)
@@ -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<HwcLayer *> &source_layers) = 0;