diff options
author | John Stultz <john.stultz@linaro.org> | 2019-06-26 12:54:43 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-06-26 12:54:43 -0700 |
commit | f94df791566640c6af2ebfef7acf823cfeee2770 (patch) | |
tree | 456febec556b9c21f956e3e7e69a86f9d45dc9b2 | |
parent | 77621aa9cbc5b5b5ddad60b1b08f2e7ecbc8e76a (diff) | |
parent | f13a30b95ab986492e9208feb3de446b3d669cc1 (diff) | |
download | drm_hwcomposer-f94df791566640c6af2ebfef7acf823cfeee2770.tar.gz |
Merge remote-tracking branch 'aosp/upstream-master' into HEAD
am: f13a30b95a
Change-Id: I4257ad915f699c3ab75879f829223232c75ebc58
-rw-r--r-- | drmhwctwo.cpp | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp index b96eb31..9268cdc 100644 --- a/drmhwctwo.cpp +++ b/drmhwctwo.cpp @@ -399,17 +399,37 @@ HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs, } } - uint32_t idx = 0; + // Since the upper layers only look at vactive/hactive/refresh, height and + // width, it doesn't differentiate interlaced from progressive and other + // similar modes. Depending on the order of modes we return to SF, it could + // end up choosing a suboptimal configuration and dropping the preferred + // mode. To workaround this, don't offer interlaced modes to SF if there is + // at least one non-interlaced alternative and only offer a single WxH@R + // mode with at least the prefered mode from in DrmConnector::UpdateModes() + + // TODO: Remove the following block of code until AOSP handles all modes + std::vector<DrmMode> sel_modes; + + // Add the preferred mode first to be sure it's not dropped + auto mode = std::find_if(connector_->modes().begin(), + connector_->modes().end(), [&](DrmMode const &m) { + return m.id() == + connector_->get_preferred_mode_id(); + }); + if (mode != connector_->modes().end()) + sel_modes.push_back(*mode); + + // Add the active mode if different from preferred mode + if (connector_->active_mode().id() != connector_->get_preferred_mode_id()) + sel_modes.push_back(connector_->active_mode()); + + // Cycle over the modes and filter out "similar" modes, keeping only the + // first ones in the order given by DRM (from CEA ids and timings order) for (const DrmMode &mode : connector_->modes()) { - if (configs && idx >= *num_configs) - break; - // Since the upper layers only look at vactive/hactive/refresh, it doesn't - // differentiate interlaced from progressive modes. Depending on the order - // of modes we return to SF, it could end up choosing a suboptimal - // configuration. - // To workaround this, don't offer interlaced modes to SF if there is at - // least one non-interlaced alternative. - // + // TODO: Remove this when 3D Attributes are in AOSP + if (mode.flags() & DRM_MODE_FLAG_3D_MASK) + continue; + // TODO: Remove this when the Interlaced attribute is in AOSP if (mode.flags() & DRM_MODE_FLAG_INTERLACE) { auto m = std::find_if(connector_->modes().begin(), @@ -419,14 +439,36 @@ HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs, m.h_display() == mode.h_display() && m.v_display() == mode.v_display(); }); - if (m != connector_->modes().end()) - continue; - } - if (configs) { - configs[idx++] = mode.id(); - } else { - idx++; + if (m == connector_->modes().end()) + sel_modes.push_back(mode); + + continue; } + + // Search for a similar WxH@R mode in the filtered list and drop it if + // another mode with the same WxH@R has already been selected + // TODO: Remove this when AOSP handles duplicates modes + auto m = std::find_if(sel_modes.begin(), sel_modes.end(), + [&mode](DrmMode const &m) { + return m.h_display() == mode.h_display() && + m.v_display() == mode.v_display() && + m.v_refresh() == mode.v_refresh(); + }); + if (m == sel_modes.end()) + sel_modes.push_back(mode); + } + + auto num_modes = static_cast<uint32_t>(sel_modes.size()); + if (!configs) { + *num_configs = num_modes; + return HWC2::Error::None; + } + + uint32_t idx = 0; + for (const DrmMode &mode : sel_modes) { + if (idx >= *num_configs) + break; + configs[idx++] = mode.id(); } *num_configs = idx; return HWC2::Error::None; |