backends/drm: support common display modes

BUG: 448398
master
Xaver Hugl 2 years ago
parent 08ad2c8ed3
commit 9ed87a4e23

@ -34,7 +34,7 @@ set(DRM_SOURCES
add_library(KWinWaylandDrmBackend MODULE ${DRM_SOURCES})
set_target_properties(KWinWaylandDrmBackend PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.waylandbackends/")
target_link_libraries(KWinWaylandDrmBackend kwin Libdrm::Libdrm gbm::gbm)
target_link_libraries(KWinWaylandDrmBackend kwin Libdrm::Libdrm gbm::gbm PkgConfig::Libxcvt)
install(
TARGETS

@ -21,6 +21,7 @@
#include <cerrno>
#include <cstring>
#include <libxcvt/libxcvt.h>
namespace KWin
{
@ -345,6 +346,7 @@ bool DrmConnector::updateProperties()
if (m_modes.isEmpty()) {
return false;
} else {
generateCommonModes();
if (!m_pipeline->pending.mode) {
m_pipeline->pending.mode = m_modes.constFirst();
m_pipeline->applyPendingChanges();
@ -392,6 +394,73 @@ DrmConnector::LinkStatus DrmConnector::linkStatus() const
return LinkStatus::Good;
}
static const QVector<QSize> s_commonModes = {
/* 4:3 (1.33) */
QSize(1600, 1200),
QSize(1280, 1024), /* 5:4 (1.25) */
QSize(1024, 768),
/* 16:10 (1.6) */
QSize(2560, 1600),
QSize(1920, 1200),
QSize(1280, 800),
/* 16:9 (1.77) */
QSize(5120, 2880),
QSize(3840, 2160),
QSize(3200, 1800),
QSize(2880, 1620),
QSize(2560, 1440),
QSize(1920, 1080),
QSize(1600, 900),
QSize(1368, 768),
QSize(1280, 720),
};
void DrmConnector::generateCommonModes()
{
uint32_t maxBandwidthEstimation = 0;
QSize maxSize;
for (const auto &mode : qAsConst(m_modes)) {
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) {
uint32_t bandwidthEstimation = size.width() * size.height() * 60000;
const auto it = std::find_if(m_modes.constBegin(), m_modes.constEnd(), [size](const auto &mode) {
return mode->size() == size;
});
if (it == m_modes.constEnd() && size.width() <= maxSize.width() && size.height() <= maxSize.height() && bandwidthEstimation < maxBandwidthEstimation) {
generateMode(size, 60000);
}
}
}
void DrmConnector::generateMode(const QSize &size, uint32_t refreshRate)
{
auto modeInfo = libxcvt_gen_mode_info(size.width(), size.height(), refreshRate, false, false);
drmModeModeInfo mode;
mode.vdisplay = modeInfo->vdisplay;
mode.hdisplay = modeInfo->hdisplay;
mode.clock = modeInfo->dot_clock;
mode.hsync_start = modeInfo->hsync_start;
mode.hsync_end = modeInfo->hsync_end;
mode.htotal = modeInfo->htotal;
mode.vsync_start = modeInfo->vsync_start;
mode.vsync_end = modeInfo->vsync_end;
mode.vtotal = modeInfo->vtotal;
mode.vrefresh = modeInfo->vrefresh;
mode.flags = modeInfo->mode_flags;
mode.type = DRM_MODE_TYPE_USERDEF;
sprintf(mode.name, "%dx%d@%d", size.width(), size.height(), mode.vrefresh);
m_modes << QSharedPointer<DrmConnectorMode>::create(this, mode);
free(modeInfo);
}
QDebug &operator<<(QDebug &s, const KWin::DrmConnector *obj)
{
QDebugStateSaver saver(s);

@ -105,6 +105,9 @@ public:
LinkStatus linkStatus() const;
private:
void generateCommonModes();
void generateMode(const QSize &size, uint32_t refreshRate);
QScopedPointer<DrmPipeline> m_pipeline;
DrmScopedPointer<drmModeConnector> m_conn;
Edid m_edid;

Loading…
Cancel
Save