1
0
Fork 0

Dedupe near-identical EDID modes by resolution and refresh rate

This commit is contained in:
Brendan Szymanski 2026-07-13 14:36:44 -04:00
parent 22ba81cf61
commit fbaba3b2b4

View file

@ -21,9 +21,11 @@
#include <drm/drm_mode.h>
#include <xf86drmMode.h>
#include <algorithm>
#include <array>
#include <cerrno>
#include <cinttypes>
#include <cmath>
#include <cstdint>
#include <sstream>
@ -265,6 +267,26 @@ std::string DrmConnector::GetName() const {
return "None";
}
namespace {
// Some EDIDs describe the same effective resolution/refresh-rate as two
// distinct raw mode entries -- e.g. a detailed-timing "preferred" mode plus a
// CEA-861 mode for the same nominal timing, differing only in blanking or in
// the DRM_MODE_TYPE_PREFERRED bit. A byte-for-byte comparison (DrmMode::
// operator==) treats these as separate modes, so both survive into the mode
// list. That leaves which mode is "preferred" ambiguous between the kernel's
// initial modeset and drm_hwcomposer's own selection, which is the suspected
// cause of a mid-boot mode switch (visible as overscan until HDMI is
// replugged) and of framework APIs like Display.getSystemPreferredDisplayMode()
// intermittently returning null (TvSettings NPE on the Resolution screen).
constexpr float kDuplicateModeRateEpsilonHz = 0.05F;
bool IsSameEffectiveMode(const DrmMode &existing, const DrmMode &candidate) {
return existing.SameSize(candidate) &&
std::abs(existing.GetVRefresh() - candidate.GetVRefresh()) <
kDuplicateModeRateEpsilonHz;
}
} // namespace
int DrmConnector::UpdateModes() {
std::string force_mode = Properties::GetForceMode();
uint32_t xres = 0, yres = 0, rate = 0;
@ -287,35 +309,43 @@ int DrmConnector::UpdateModes() {
modes_.clear();
for (int i = 0; i < connector_->count_modes; ++i) {
bool exists = false;
for (const DrmMode &mode : modes_) {
if (mode == connector_->modes[i]) {
exists = true;
break;
DrmMode m(&connector_->modes[i]);
ALOGV("Supported mode %dx%d@%fHz for display in connector %s",
m.GetRawMode().hdisplay, m.GetRawMode().vdisplay,
m.GetVRefresh(), GetName().c_str());
auto existing = std::find_if(modes_.begin(), modes_.end(),
[&m](const DrmMode &other) {
return IsSameEffectiveMode(other, m);
});
if (existing != modes_.end()) {
// Keep whichever duplicate carries the EDID's PREFERRED flag.
if ((m.GetRawMode().type & DRM_MODE_TYPE_PREFERRED) != 0 &&
(existing->GetRawMode().type & DRM_MODE_TYPE_PREFERRED) == 0) {
ALOGD("Mode %dx%d@%fHz for display in connector %s duplicated; "
"keeping the PREFERRED entry",
m.GetRawMode().hdisplay, m.GetRawMode().vdisplay,
m.GetVRefresh(), GetName().c_str());
*existing = m;
}
continue;
}
if (!exists) {
DrmMode m(&connector_->modes[i]);
ALOGV("Supported mode %dx%d@%fHz for display in connector %s",
m.GetRawMode().hdisplay, m.GetRawMode().vdisplay,
m.GetVRefresh(), GetName().c_str());
if (xres && yres) {
if (!rate && m.GetRawMode().hdisplay == xres
&& m.GetRawMode().vdisplay == yres) {
rate = m.GetVRefresh();
}
if (m.GetRawMode().hdisplay != xres
|| m.GetRawMode().vdisplay != yres
|| m.GetVRefresh() != rate) {
continue;
}
if (xres && yres) {
if (!rate && m.GetRawMode().hdisplay == xres
&& m.GetRawMode().vdisplay == yres) {
rate = m.GetVRefresh();
}
if (m.GetRawMode().hdisplay != xres
|| m.GetRawMode().vdisplay != yres
|| m.GetVRefresh() != rate) {
continue;
}
ALOGD("Add mode %dx%d@%fHz for display in connector %s",
m.GetRawMode().hdisplay, m.GetRawMode().vdisplay,
m.GetVRefresh(), GetName().c_str());
modes_.emplace_back(m);
}
ALOGD("Add mode %dx%d@%fHz for display in connector %s",
m.GetRawMode().hdisplay, m.GetRawMode().vdisplay,
m.GetVRefresh(), GetName().c_str());
modes_.emplace_back(m);
}
return 0;