OSDN Git Service

Postpone initial hot plug registration till Present call.
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 3 Sep 2017 09:26:28 +0000 (02:26 -0700)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Mon, 4 Sep 2017 01:43:38 +0000 (18:43 -0700)
Seems like on Android O, we need to wait for registering hot
plug events till the initial Present else these notifications
are getting ignored. Also, add more logs.

Jira: None.
Test: Two displays are recognized during boot up and show the
      right content.

Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
wsi/drm/drmdisplay.cpp
wsi/drm/drmdisplay.h
wsi/drm/drmdisplaymanager.cpp
wsi/drm/drmdisplaymanager.h
wsi/physicaldisplay.cpp
wsi/physicaldisplay.h

index 7c44df0..6dbe5f2 100644 (file)
 
 #include "displayqueue.h"
 #include "displayplanemanager.h"
+#include "drmdisplaymanager.h"
 
 namespace hwcomposer {
 
 static const int32_t kUmPerInch = 25400;
 
-DrmDisplay::DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id)
-    : PhysicalDisplay(gpu_fd, pipe_id), crtc_id_(crtc_id), connector_(0) {
+DrmDisplay::DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id,
+                       DrmDisplayManager *manager)
+    : PhysicalDisplay(gpu_fd, pipe_id),
+      crtc_id_(crtc_id),
+      connector_(0),
+      manager_(manager) {
   memset(&current_mode_, 0, sizeof(current_mode_));
 }
 
@@ -62,7 +67,8 @@ bool DrmDisplay::InitializeDisplay() {
 }
 
 bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info,
-                                const drmModeConnector *connector) {
+                                const drmModeConnector *connector,
+                                uint32_t config) {
   IHOTPLUGEVENTTRACE("DrmDisplay::Connect recieved.");
   // TODO(kalyan): Add support for multi monitor case.
   if (connector_ && connector->connector_id == connector_) {
@@ -80,6 +86,7 @@ bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info,
   mmWidth_ = connector->mmWidth;
   mmHeight_ = connector->mmHeight;
   SetDisplayAttribute(mode_info);
+  config_ = config;
 
   ScopedDrmObjectPropertyPtr connector_props(drmModeObjectGetProperties(
       gpu_fd_, connector_, DRM_MODE_OBJECT_CONNECTOR));
@@ -171,10 +178,16 @@ bool DrmDisplay::GetDisplayConfigs(uint32_t *num_configs, uint32_t *configs) {
   if (!configs) {
     display_lock_.lock();
     *num_configs = modes_.size();
+    IHOTPLUGEVENTTRACE(
+        "GetDisplayConfigs: Total Configs: %d pipe: %d display: %p",
+        *num_configs, pipe_, this);
     display_lock_.unlock();
     return true;
   }
 
+  IHOTPLUGEVENTTRACE(
+      "GetDisplayConfigs: Populating Configs: %d pipe: %d display: %p",
+      *num_configs, pipe_, this);
   uint32_t size = *num_configs;
   for (uint32_t i = 0; i < size; i++)
     configs[i] = i;
@@ -607,6 +620,10 @@ bool DrmDisplay::PopulatePlanes(
   return true;
 }
 
+void DrmDisplay::NotifyClientsOfDisplayChangeStatus() {
+  manager_->NotifyClientsOfDisplayChangeStatus();
+}
+
 bool DrmDisplay::TestCommit(
     const std::vector<OverlayPlane> &commit_planes) const {
   ScopedDrmAtomicReqPtr pset(drmModeAtomicAlloc());
index a625fa5..04eb308 100644 (file)
@@ -27,6 +27,7 @@
 #include "physicaldisplay.h"
 
 namespace hwcomposer {
+class DrmDisplayManager;
 class DisplayPlaneState;
 class DisplayQueue;
 class NativeBufferHandler;
@@ -35,7 +36,8 @@ struct HwcLayer;
 
 class DrmDisplay : public PhysicalDisplay {
  public:
-  DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
+  DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id,
+             DrmDisplayManager *manager);
   ~DrmDisplay() override;
 
   bool GetDisplayAttribute(uint32_t config, HWCDisplayAttribute attribute,
@@ -61,7 +63,7 @@ class DrmDisplay : public PhysicalDisplay {
   }
 
   bool ConnectDisplay(const drmModeModeInfo &mode_info,
-                      const drmModeConnector *connector);
+                      const drmModeConnector *connector, uint32_t config);
 
   void SetDrmModeInfo(const std::vector<drmModeModeInfo> &mode_info);
   void SetDisplayAttribute(const drmModeModeInfo &mode_info);
@@ -74,6 +76,8 @@ class DrmDisplay : public PhysicalDisplay {
       std::unique_ptr<DisplayPlane> &cursor_plane,
       std::vector<std::unique_ptr<DisplayPlane>> &overlay_planes) override;
 
+  void NotifyClientsOfDisplayChangeStatus() override;
+
  private:
   void ShutDownPipe();
   void GetDrmObjectPropertyValue(const char *name,
@@ -114,6 +118,7 @@ class DrmDisplay : public PhysicalDisplay {
   drmModeModeInfo current_mode_;
   std::vector<drmModeModeInfo> modes_;
   SpinLock display_lock_;
+  DrmDisplayManager *manager_;
 };
 
 }  // namespace hwcomposer
index 8c31b09..de046f5 100644 (file)
@@ -85,7 +85,8 @@ bool DrmDisplayManager::Initialize() {
       return false;
     }
 
-    std::unique_ptr<DrmDisplay> display(new DrmDisplay(fd_, i, c->crtc_id));
+    std::unique_ptr<DrmDisplay> display(
+        new DrmDisplay(fd_, i, c->crtc_id, this));
     if (!display->Initialize(buffer_handler_.get())) {
       ETRACE("Failed to Initialize Display %d", c->crtc_id);
       return false;
@@ -242,13 +243,12 @@ bool DrmDisplayManager::UpdateDisplayState() {
           // At initilaization  preferred mode is set!
           if (!display->IsConnected() &&
               encoder->crtc_id == display->CrtcId() &&
-              display->ConnectDisplay(mode.at(preferred_mode),
-                                      connector.get())) {
+              display->ConnectDisplay(mode.at(preferred_mode), connector.get(),
+                                      preferred_mode)) {
             IHOTPLUGEVENTTRACE("Connected %d with crtc: %d \n",
                                encoder->crtc_id, display->CrtcId());
             // Set the modes supported for each display
             display->SetDrmModeInfo(mode);
-            display->NotifyClientOfConnectedState();
             break;
           }
         }
@@ -263,12 +263,11 @@ bool DrmDisplayManager::UpdateDisplayState() {
         for (auto &display : displays_) {
           if (!display->IsConnected() &&
               (encoder->possible_crtcs & (1 << display->Pipe())) &&
-              display->ConnectDisplay(mode.at(preferred_mode),
-                                      connector.get())) {
+              display->ConnectDisplay(mode.at(preferred_mode), connector.get(),
+                                      preferred_mode)) {
             IHOTPLUGEVENTTRACE("connected pipe:%d \n", display->Pipe());
             // Set the modes supported for each display
             display->SetDrmModeInfo(mode);
-            display->NotifyClientOfConnectedState();
             break;
           }
         }
@@ -279,7 +278,6 @@ bool DrmDisplayManager::UpdateDisplayState() {
   for (auto &display : displays_) {
     if (!display->IsConnected()) {
       display->DisConnect();
-      display->NotifyClientOfDisConnectedState();
     } else {
       connected_displays_.emplace_back(display.get());
     }
@@ -297,9 +295,24 @@ bool DrmDisplayManager::UpdateDisplayState() {
   }
 
   spin_lock_.unlock();
+
+  NotifyClientsOfDisplayChangeStatus();
   return true;
 }
 
+void DrmDisplayManager::NotifyClientsOfDisplayChangeStatus() {
+  spin_lock_.lock();
+  for (auto &display : displays_) {
+    if (!display->IsConnected()) {
+      display->NotifyClientOfDisConnectedState();
+    } else {
+      display->NotifyClientOfConnectedState();
+    }
+  }
+
+  spin_lock_.unlock();
+}
+
 NativeDisplay *DrmDisplayManager::GetDisplay(uint32_t display_id) {
   CTRACE();
   spin_lock_.lock();
index ff075df..eb3ac85 100644 (file)
@@ -58,6 +58,8 @@ class DrmDisplayManager : public HWCThread, public DisplayManager {
   void RegisterHotPlugEventCallback(
       std::shared_ptr<DisplayHotPlugEventCallback> callback) override;
 
+  void NotifyClientsOfDisplayChangeStatus();
+
  protected:
   void HandleWait() override;
   void HandleRoutine() override;
index 4fdfd2a..37e4d36 100644 (file)
@@ -56,6 +56,9 @@ void PhysicalDisplay::MarkForDisconnect() {
   IHOTPLUGEVENTTRACE("PhysicalDisplay::MarkForDisconnect recieved.");
   display_state_ |= kDisconnectionInProgress;
   display_state_ |= kRefreshClonedDisplays;
+  if (pipe_ == 0 && !(display_state_ & kInitialized))
+    display_state_ |= kHandlePendingHotPlugNotifications;
+
   modeset_lock_.unlock();
 }
 
@@ -138,6 +141,9 @@ int PhysicalDisplay::GetDisplayPipe() {
 
 bool PhysicalDisplay::SetActiveConfig(uint32_t config) {
   // update the activeConfig
+  IHOTPLUGEVENTTRACE(
+      "SetActiveConfig: New config to be used %d pipe: %p display: %p", config,
+      pipe_, this);
   config_ = config;
   display_queue_->DisplayConfigurationChanged();
   display_state_ |= kNeedsModeset;
@@ -148,7 +154,10 @@ bool PhysicalDisplay::SetActiveConfig(uint32_t config) {
 bool PhysicalDisplay::GetActiveConfig(uint32_t *config) {
   if (!config)
     return false;
-
+  IHOTPLUGEVENTTRACE(
+      "GetActiveConfig: Current config being used Config: %d pipe: %d display: "
+      "%p",
+      config_, pipe_, this);
   *config = config_;
   return true;
 }
@@ -222,8 +231,18 @@ bool PhysicalDisplay::Present(std::vector<HwcLayer *> &source_layers,
   if (display_state_ & kRefreshClonedDisplays) {
     RefreshClones();
   }
+
+  bool handle_hoplug_notifications = false;
+  if (display_state_ & kHandlePendingHotPlugNotifications) {
+    display_state_ &= ~kHandlePendingHotPlugNotifications;
+    handle_hoplug_notifications = true;
+  }
   modeset_lock_.unlock();
 
+  if (handle_hoplug_notifications) {
+    NotifyClientsOfDisplayChangeStatus();
+  }
+
   bool cloned = !clones_.empty();
   bool success =
       display_queue_->QueueUpdate(source_layers, retire_fence, false);
@@ -287,8 +306,7 @@ void PhysicalDisplay::RegisterHotPlugCallback(
   hotplug_callback_ = callback;
   bool connected = display_state_ & kConnected;
   modeset_lock_.unlock();
-
-  if (hotplug_callback_) {
+  if (hotplug_callback_ && pipe_ == 0) {
     if (connected) {
       hotplug_callback_->Callback(hot_plug_display_id_, true);
     } else {
index 011c3a3..c1a56e2 100644 (file)
@@ -158,6 +158,8 @@ class PhysicalDisplay : public NativeDisplay, public DisplayPlaneHandler {
   */
   virtual bool InitializeDisplay() = 0;
 
+  virtual void NotifyClientsOfDisplayChangeStatus() = 0;
+
   /**
   * API for informing the display that it might be disconnected in near
   * future.
@@ -190,7 +192,8 @@ class PhysicalDisplay : public NativeDisplay, public DisplayPlaneHandler {
     kUpdateDisplay = 1 << 4,
     kDisconnectionInProgress = 1 << 5,
     kInitialized = 1 << 6,  // Display Queue is initialized.
-    kRefreshClonedDisplays = 1 << 7
+    kRefreshClonedDisplays = 1 << 7,
+    kHandlePendingHotPlugNotifications = 1 << 8
   };
 
   uint32_t pipe_;