From: Poornima Date: Mon, 12 Jun 2017 13:05:02 +0000 (+0530) Subject: Get All Supported Display Modes X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=8836801aecd2ccd41d857d43fa7d3d5f26a59e08;p=android-x86%2Fexternal-IA-Hardware-Composer.git Get All Supported Display Modes 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 --- diff --git a/common/core/gpudevice.cpp b/common/core/gpudevice.cpp index 69d41df..c4be9f7 100644 --- a/common/core/gpudevice.cpp +++ b/common/core/gpudevice.cpp @@ -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 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; diff --git a/common/display/display.cpp b/common/display/display.cpp index 5fd61b5..7cb99e2 100644 --- a/common/display/display.cpp +++ b/common/display/display.cpp @@ -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 &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 diff --git a/common/display/display.h b/common/display/display.h index 1de92ce..b00cd78 100644 --- a/common/display/display.h +++ b/common/display/display.h @@ -108,6 +108,9 @@ class Display : public NativeDisplay { void DisConnect() override; void ShutDown() override; + void SetDrmModeInfo( + const std::vector &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 display_queue_; + std::vector mode_; }; } // namespace hwcomposer diff --git a/public/nativedisplay.h b/public/nativedisplay.h index 57ab49d..134b87e 100644 --- a/public/nativedisplay.h +++ b/public/nativedisplay.h @@ -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 & /*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; };