OSDN Git Service

Get All Supported Display Modes
authorPoornima <poornima.y.n@intel.com>
Mon, 12 Jun 2017 13:05:02 +0000 (18:35 +0530)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Tue, 13 Jun 2017 08:23:05 +0000 (01:23 -0700)
Implementation of  GetDisplayConfig() and support to get all the
display modes supported.

Jira:IAHWC-34
Tests: No regression on Android and linux
Signed-off-by: N, Poornima Y <poornima.y.n@intel.com>
common/core/gpudevice.cpp
common/display/display.cpp
common/display/display.h
public/nativedisplay.h

index 69d41df..c4be9f7 100644 (file)
@@ -249,30 +249,27 @@ bool GpuDevice::DisplayManager::UpdateDisplayState() {
     // Ensure we have atleast one valid mode.
     if (connector->count_modes == 0)
       continue;
-
-    drmModeModeInfo mode;
-    memset(&mode, 0, sizeof(mode));
-    bool found_prefered_mode = false;
+    std::vector<drmModeModeInfo> mode;
+    uint32_t preferred_mode;
     for (int32_t i = 0; i < connector->count_modes; ++i) {
-      mode = connector->modes[i];
+      mode.emplace_back(connector->modes[i]);
       // There is only one preferred mode per connector.
-      if (mode.type & DRM_MODE_TYPE_PREFERRED) {
-        found_prefered_mode = true;
-        break;
+      if (mode[i].type & DRM_MODE_TYPE_PREFERRED) {
+        preferred_mode = i;
       }
     }
 
-    if (!found_prefered_mode)
-      continue;
-
     // Lets try to find crts for any connected encoder.
     if (connector->encoder_id) {
       ScopedDrmEncoderPtr encoder(
           drmModeGetEncoder(fd_, connector->encoder_id));
       if (encoder && encoder->crtc_id) {
         for (auto &display : displays_) {
+          //Set the modes supported for each display
+          display->SetDrmModeInfo(mode);
+          // At initilaization  preferred mode is set!
           if (encoder->crtc_id == display->CrtcId() &&
-              display->Connect(mode, connector.get())) {
+              display->Connect(mode.at(preferred_mode), connector.get())) {
             connected_displays_.emplace_back(display.get());
             break;
           }
@@ -289,7 +286,7 @@ bool GpuDevice::DisplayManager::UpdateDisplayState() {
         for (auto &display : displays_) {
           if (!display->IsConnected() &&
               (encoder->possible_crtcs & (1 << display->Pipe())) &&
-              display->Connect(mode, connector.get())) {
+              display->Connect(mode.at(preferred_mode), connector.get())) {
             IHOTPLUGEVENTTRACE("connected pipe:%d \n", display->Pipe());
             connected_displays_.emplace_back(display.get());
             found_encoder = true;
index 5fd61b5..7cb99e2 100644 (file)
@@ -66,23 +66,9 @@ bool Display::Connect(const drmModeModeInfo &mode_info,
 
   IHOTPLUGEVENTTRACE("Display is being connected to a new connector.");
   connector_ = connector->connector_id;
-  width_ = mode_info.hdisplay;
-  height_ = mode_info.vdisplay;
-  refresh_ =
-      (mode_info.clock * 1000.0f) / (mode_info.htotal * mode_info.vtotal);
-
-  if (mode_info.flags & DRM_MODE_FLAG_INTERLACE)
-    refresh_ *= 2;
-
-  if (mode_info.flags & DRM_MODE_FLAG_DBLSCAN)
-    refresh_ /= 2;
-
-  if (mode_info.vscan > 1)
-    refresh_ /= mode_info.vscan;
-
-  dpix_ = connector->mmWidth ? (width_ * kUmPerInch) / connector->mmWidth : -1;
-  dpiy_ =
-      connector->mmHeight ? (height_ * kUmPerInch) / connector->mmHeight : -1;
+  mmWidth_ = connector->mmWidth;
+  mmHeight_ = connector->mmHeight;
+  SetDisplayAttribute(mode_info);
 
   is_connected_ = true;
 
@@ -114,28 +100,40 @@ void Display::ShutDown() {
   connector_ = 0;
 }
 
-bool Display::GetDisplayAttribute(uint32_t /*config*/,
+bool Display::GetDisplayAttribute(uint32_t config /*config*/,
                                   HWCDisplayAttribute attribute,
                                   int32_t *value) {
-  // We always get the values from preferred mode config.
+  float refresh;
   switch (attribute) {
     case HWCDisplayAttribute::kWidth:
-      *value = width_;
+      *value = mode_[config].hdisplay;
       break;
     case HWCDisplayAttribute::kHeight:
-      *value = height_;
+      *value = mode_[config].vdisplay;
       break;
     case HWCDisplayAttribute::kRefreshRate:
+      refresh = (mode_[config].clock * 1000.0f) /
+                (mode_[config].htotal * mode_[config].vtotal);
+
+      if (mode_[config].flags & DRM_MODE_FLAG_INTERLACE)
+        refresh *= 2;
+
+      if (mode_[config].flags & DRM_MODE_FLAG_DBLSCAN)
+        refresh /= 2;
+
+      if (mode_[config].vscan > 1)
+        refresh /= mode_[config].vscan;
       // in nanoseconds
-      *value = 1e9 / refresh_;
+      *value = 1e9 / refresh;
       break;
     case HWCDisplayAttribute::kDpiX:
       // Dots per 1000 inches
-      *value = dpix_;
+      *value = mmWidth_ ? (mode_[config].hdisplay * kUmPerInch) / mmWidth_ : -1;
       break;
     case HWCDisplayAttribute::kDpiY:
       // Dots per 1000 inches
-      *value = dpiy_;
+      *value =
+          mmHeight_ ? (mode_[config].vdisplay * kUmPerInch) / mmHeight_ : -1;
       break;
     default:
       *value = -1;
@@ -146,11 +144,12 @@ bool Display::GetDisplayAttribute(uint32_t /*config*/,
 }
 
 bool Display::GetDisplayConfigs(uint32_t *num_configs, uint32_t *configs) {
-  *num_configs = 1;
+  *num_configs = mode_.size();
   if (!configs)
     return true;
 
-  configs[0] = 1;
+  for (uint32_t i = 0; i < *num_configs; i++)
+    configs[i] = i;
 
   return true;
 }
@@ -244,4 +243,29 @@ void Display::SetExplicitSyncSupport(bool disable_explicit_sync) {
   display_queue_->SetExplicitSyncSupport(disable_explicit_sync);
 }
 
+void Display::SetDrmModeInfo(
+    const std::vector<drmModeModeInfo> &mode_info) {
+  for (uint32_t i = 0; i < mode_info.size(); ++i)
+    mode_.emplace_back(mode_info[i]);
+}
+
+void Display::SetDisplayAttribute(const drmModeModeInfo &mode_info) {
+  width_ = mode_info.hdisplay;
+  height_ = mode_info.vdisplay;
+  refresh_ =
+      (mode_info.clock * 1000.0f) / (mode_info.htotal * mode_info.vtotal);
+
+  if (mode_info.flags & DRM_MODE_FLAG_INTERLACE)
+    refresh_ *= 2;
+
+  if (mode_info.flags & DRM_MODE_FLAG_DBLSCAN)
+    refresh_ /= 2;
+
+  if (mode_info.vscan > 1)
+    refresh_ /= mode_info.vscan;
+
+  dpix_ = mmWidth_ ? (width_ * kUmPerInch) / mmWidth_ : -1;
+  dpiy_ = mmHeight_ ? (height_ * kUmPerInch) / mmHeight_ : -1;
+}
+
 }  // namespace hwcomposer
index 1de92ce..b00cd78 100644 (file)
@@ -108,6 +108,9 @@ class Display : public NativeDisplay {
   void DisConnect() override;
 
   void ShutDown() override;
+  void SetDrmModeInfo(
+      const std::vector<drmModeModeInfo> &mode_info) override;
+  void SetDisplayAttribute(const drmModeModeInfo &mode_info) override;
 
  private:
   void ShutDownPipe();
@@ -119,11 +122,14 @@ class Display : public NativeDisplay {
   int32_t height_;
   int32_t dpix_;
   int32_t dpiy_;
+  uint32_t mmWidth_;
+  uint32_t mmHeight_;
   uint32_t gpu_fd_;
   uint32_t power_mode_;
   float refresh_;
   bool is_connected_;
   std::unique_ptr<DisplayQueue> display_queue_;
+  std::vector<drmModeModeInfo> mode_;
 };
 
 }  // namespace hwcomposer
index 57ab49d..134b87e 100644 (file)
@@ -149,6 +149,7 @@ class NativeDisplay {
 
   virtual void SetExplicitSyncSupport(bool /*explicit_sync_enabled*/) {
   }
+
  protected:
   virtual uint32_t CrtcId() const = 0;
   virtual bool Connect(const drmModeModeInfo &mode_info,
@@ -159,6 +160,19 @@ class NativeDisplay {
   virtual void DisConnect() = 0;
 
   virtual void ShutDown() = 0;
+  /**
+  * API to Set the suported modes of the display
+  * @param mode_info vector of drmModeModeInfo
+  */
+  virtual void SetDrmModeInfo(
+      const std::vector<drmModeModeInfo> & /*mode_info*/) {
+  }
+  /**
+  * API to Set the Display attribute based on mode set
+  * @param mode_info  drmModeModeInfo
+  */
+  virtual void SetDisplayAttribute(const drmModeModeInfo & /*mode_info*/) {
+  }
 
   friend class GpuDevice;
 };