backends/drm: fix common mode generation

There were overflows in the bandwidth estimation calculation. To simplify things,
also only generate common modes if the display doesn't advertise them on its own
already.
This commit is contained in:
Xaver Hugl 2022-10-30 23:08:37 +01:00 committed by Vlad Zahorodnii
parent f649363a4e
commit 3f3d41f259
2 changed files with 9 additions and 16 deletions

View file

@ -319,7 +319,9 @@ bool DrmConnector::updateProperties()
} }
m_modes.clear(); m_modes.clear();
m_modes.append(m_driverModes); m_modes.append(m_driverModes);
m_modes.append(generateCommonModes()); if (m_driverModes.size() == 1) {
m_modes.append(generateCommonModes(m_driverModes.front().get()));
}
if (m_pipeline->mode()) { if (m_pipeline->mode()) {
if (const auto mode = findMode(*m_pipeline->mode()->nativeMode())) { if (const auto mode = findMode(*m_pipeline->mode()->nativeMode())) {
m_pipeline->setMode(mode); m_pipeline->setMode(mode);
@ -393,23 +395,14 @@ static const QVector<QSize> s_commonModes = {
QSize(1280, 720), QSize(1280, 720),
}; };
QList<std::shared_ptr<DrmConnectorMode>> DrmConnector::generateCommonModes() QList<std::shared_ptr<DrmConnectorMode>> DrmConnector::generateCommonModes(DrmConnectorMode *baseMode)
{ {
QList<std::shared_ptr<DrmConnectorMode>> ret; QList<std::shared_ptr<DrmConnectorMode>> ret;
uint32_t maxBandwidthEstimation = 0; const QSize maxSize = baseMode->size();
QSize maxSize; const uint64_t maxBandwidthEstimation = maxSize.width() * maxSize.height() * uint64_t(baseMode->refreshRate());
for (const auto &mode : qAsConst(m_driverModes)) {
if (mode->size().width() > maxSize.width() || mode->size().height() > maxSize.height()) {
maxSize = mode->size();
maxBandwidthEstimation = std::max(maxBandwidthEstimation, static_cast<uint32_t>(mode->size().width() * mode->size().height() * mode->refreshRate()));
}
}
for (const auto &size : s_commonModes) { for (const auto &size : s_commonModes) {
uint32_t bandwidthEstimation = size.width() * size.height() * 60000; const uint64_t bandwidthEstimation = size.width() * size.height() * 60000ull;
const auto it = std::find_if(m_driverModes.constBegin(), m_driverModes.constEnd(), [size](const auto &mode) { if (size.width() <= maxSize.width() && size.height() <= maxSize.height() && bandwidthEstimation <= maxBandwidthEstimation) {
return mode->size() == size;
});
if (it == m_driverModes.constEnd() && size.width() <= maxSize.width() && size.height() <= maxSize.height() && bandwidthEstimation < maxBandwidthEstimation) {
ret << generateMode(size, 60); ret << generateMode(size, 60);
} }
} }

View file

@ -114,7 +114,7 @@ public:
static DrmContentType kwinToDrmContentType(ContentType type); static DrmContentType kwinToDrmContentType(ContentType type);
private: private:
QList<std::shared_ptr<DrmConnectorMode>> generateCommonModes(); QList<std::shared_ptr<DrmConnectorMode>> generateCommonModes(DrmConnectorMode *baseMode);
std::shared_ptr<DrmConnectorMode> generateMode(const QSize &size, float refreshRate); std::shared_ptr<DrmConnectorMode> generateMode(const QSize &size, float refreshRate);
std::unique_ptr<DrmPipeline> m_pipeline; std::unique_ptr<DrmPipeline> m_pipeline;