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:
parent
dc19c0ed02
commit
b50d6d487b
2 changed files with 46 additions and 1 deletions
|
@ -640,10 +640,54 @@ void DrmOutput::init(drmModeConnector *connector)
|
|||
}
|
||||
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();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (!m_blackBuffer) {
|
||||
|
|
|
@ -135,6 +135,7 @@ private:
|
|||
void cleanupBlackBuffer();
|
||||
bool setMode(DrmBuffer *buffer);
|
||||
void initEdid(drmModeConnector *connector);
|
||||
bool isCurrentMode(const drmModeModeInfo *mode) const;
|
||||
|
||||
DrmBackend *m_backend;
|
||||
QPoint m_globalPos;
|
||||
|
|
Loading…
Reference in a new issue