Add modelines to OutputInterfaces in DrmBackend

Each available mode on the connector is added to the
KWayland::Server::OutputInterface for the DrmOutput.

The logic to calculate the refreshRate is highly inspired from Weston's
implementation in compositor-drm.c.
This commit is contained in:
Martin Gräßlin 2015-04-28 08:16:07 +02:00
parent dc19c0ed02
commit b50d6d487b
2 changed files with 46 additions and 1 deletions

View file

@ -640,10 +640,54 @@ void DrmOutput::init(drmModeConnector *connector)
} }
m_waylandOutput->setPhysicalSize(physicalSize); m_waylandOutput->setPhysicalSize(physicalSize);
m_waylandOutput->addMode(size()); // read in mode information
for (int i = 0; i < connector->count_modes; ++i) {
auto *m = &connector->modes[i];
KWayland::Server::OutputInterface::ModeFlags flags;
if (isCurrentMode(m)) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Current;
}
if (m->type & DRM_MODE_TYPE_PREFERRED) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred;
}
// Calculate higher precision (mHz) refresh rate
// logic based on Weston, see compositor-drm.c
quint64 refreshRate = (m->clock * 1000000LL / m->htotal + m->vtotal / 2) / m->vtotal;
if (m->flags & DRM_MODE_FLAG_INTERLACE) {
refreshRate *= 2;
}
if (m->flags & DRM_MODE_FLAG_DBLSCAN) {
refreshRate /= 2;
}
if (m->vscan > 1) {
refreshRate /= m->vscan;
}
m_waylandOutput->addMode(QSize(m->hdisplay, m->vdisplay), flags, refreshRate);
}
m_waylandOutput->create(); m_waylandOutput->create();
} }
bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const
{
return mode->clock == m_mode.clock
&& mode->hdisplay == m_mode.hdisplay
&& mode->hsync_start == m_mode.hsync_start
&& mode->hsync_end == m_mode.hsync_end
&& mode->htotal == m_mode.htotal
&& mode->hskew == m_mode.hskew
&& mode->vdisplay == m_mode.vdisplay
&& mode->vsync_start == m_mode.vsync_start
&& mode->vsync_end == m_mode.vsync_end
&& mode->vtotal == m_mode.vtotal
&& mode->vscan == m_mode.vscan
&& mode->vrefresh == m_mode.vrefresh
&& mode->flags == m_mode.flags
&& mode->type == m_mode.type
&& qstrcmp(mode->name, m_mode.name) == 0;
}
void DrmOutput::blank() void DrmOutput::blank()
{ {
if (!m_blackBuffer) { if (!m_blackBuffer) {

View file

@ -135,6 +135,7 @@ private:
void cleanupBlackBuffer(); void cleanupBlackBuffer();
bool setMode(DrmBuffer *buffer); bool setMode(DrmBuffer *buffer);
void initEdid(drmModeConnector *connector); void initEdid(drmModeConnector *connector);
bool isCurrentMode(const drmModeModeInfo *mode) const;
DrmBackend *m_backend; DrmBackend *m_backend;
QPoint m_globalPos; QPoint m_globalPos;