Split init'ing the wayland output from init

Summary:
This is a tiny refactor so that DrmOutput can have WaylandOutput
dynamically
deleted and recreated at runtime as we disable outptuts.

Reviewers: #plasma, graesslin

Reviewed By: #plasma, graesslin

Subscribers: plasma-devel, kwin, #kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D8794
This commit is contained in:
David Edmundson 2017-11-15 16:08:09 +00:00
parent 6325749f21
commit e96f2bff11
2 changed files with 83 additions and 62 deletions

View file

@ -270,7 +270,51 @@ bool DrmOutput::init(drmModeConnector *connector)
return false; return false;
} }
m_internal = connector->connector_type == DRM_MODE_CONNECTOR_LVDS || connector->connector_type == DRM_MODE_CONNECTOR_eDP;
setDpms(DpmsMode::On); setDpms(DpmsMode::On);
if (m_internal) {
connect(kwinApp(), &Application::screensCreated, this,
[this] {
connect(screens()->orientationSensor(), &OrientationSensor::orientationChanged, this, &DrmOutput::automaticRotation);
}
);
}
QSize physicalSize = !m_edid.physicalSize.isEmpty() ? m_edid.physicalSize : QSize(connector->mmWidth, connector->mmHeight);
// the size might be completely borked. E.g. Samsung SyncMaster 2494HS reports 160x90 while in truth it's 520x292
// as this information is used to calculate DPI info, it's going to result in everything being huge
const QByteArray unknown = QByteArrayLiteral("unkown");
KConfigGroup group = kwinApp()->config()->group("EdidOverwrite").group(m_edid.eisaId.isEmpty() ? unknown : m_edid.eisaId)
.group(m_edid.monitorName.isEmpty() ? unknown : m_edid.monitorName)
.group(m_edid.serialNumber.isEmpty() ? unknown : m_edid.serialNumber);
if (group.hasKey("PhysicalSize")) {
const QSize overwriteSize = group.readEntry("PhysicalSize", physicalSize);
qCWarning(KWIN_DRM) << "Overwriting monitor physical size for" << m_edid.eisaId << "/" << m_edid.monitorName << "/" << m_edid.serialNumber << " from " << physicalSize << "to " << overwriteSize;
physicalSize = overwriteSize;
}
m_physicalSize = physicalSize;
initOutputDevice(connector);
initOutput();
return true;
}
void DrmOutput::initUuid()
{
QCryptographicHash hash(QCryptographicHash::Md5);
hash.addData(QByteArray::number(m_conn->id()));
hash.addData(m_edid.eisaId);
hash.addData(m_edid.monitorName);
hash.addData(m_edid.serialNumber);
m_uuid = hash.result().toHex().left(10);
}
void DrmOutput::initOutput()
{
Q_ASSERT(m_waylandOutputDevice);
if (!m_waylandOutput.isNull()) { if (!m_waylandOutput.isNull()) {
delete m_waylandOutput.data(); delete m_waylandOutput.data();
m_waylandOutput.clear(); m_waylandOutput.clear();
@ -284,6 +328,37 @@ bool DrmOutput::init(drmModeConnector *connector)
m_waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), refreshRateForMode(&m_mode)); m_waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), refreshRateForMode(&m_mode));
} }
); );
m_waylandOutput->setManufacturer(m_waylandOutputDevice->manufacturer());
m_waylandOutput->setModel(m_waylandOutputDevice->model());
m_waylandOutput->setPhysicalSize(m_physicalSize);
// set dpms
if (!m_dpms.isNull()) {
m_waylandOutput->setDpmsSupported(true);
m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsMode));
connect(m_waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this,
[this] (KWayland::Server::OutputInterface::DpmsMode mode) {
setDpms(fromWaylandDpmsMode(mode));
}, Qt::QueuedConnection
);
}
for(const auto &mode: m_waylandOutputDevice->modes()) {
KWayland::Server::OutputInterface::ModeFlags flags;
if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Current) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Current;
}
if (mode.flags & KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred;
}
m_waylandOutput->addMode(mode.size, flags, mode.refreshRate);
}
m_waylandOutput->create();
}
void DrmOutput::initOutputDevice(drmModeConnector *connector)
{
if (!m_waylandOutputDevice.isNull()) { if (!m_waylandOutputDevice.isNull()) {
delete m_waylandOutputDevice.data(); delete m_waylandOutputDevice.data();
m_waylandOutputDevice.clear(); m_waylandOutputDevice.clear();
@ -292,23 +367,13 @@ bool DrmOutput::init(drmModeConnector *connector)
m_waylandOutputDevice->setUuid(m_uuid); m_waylandOutputDevice->setUuid(m_uuid);
if (!m_edid.eisaId.isEmpty()) { if (!m_edid.eisaId.isEmpty()) {
m_waylandOutput->setManufacturer(QString::fromLatin1(m_edid.eisaId)); m_waylandOutputDevice->setManufacturer(QString::fromLatin1(m_edid.eisaId));
} else { } else {
m_waylandOutput->setManufacturer(i18n("unknown")); m_waylandOutputDevice->setManufacturer(i18n("unknown"));
} }
m_waylandOutputDevice->setManufacturer(m_waylandOutput->manufacturer());
QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown")); QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown"));
QString modelName; QString modelName;
m_internal = connector->connector_type == DRM_MODE_CONNECTOR_LVDS || connector->connector_type == DRM_MODE_CONNECTOR_eDP;
if (m_internal) {
connect(kwinApp(), &Application::screensCreated, this,
[this] {
connect(screens()->orientationSensor(), &OrientationSensor::orientationChanged, this, &DrmOutput::automaticRotation);
}
);
}
if (!m_edid.monitorName.isEmpty()) { if (!m_edid.monitorName.isEmpty()) {
QString model = QString::fromLatin1(m_edid.monitorName); QString model = QString::fromLatin1(m_edid.monitorName);
@ -323,45 +388,24 @@ bool DrmOutput::init(drmModeConnector *connector)
modelName = i18n("unknown"); modelName = i18n("unknown");
} }
m_waylandOutput->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName); m_waylandOutputDevice->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName);
m_waylandOutputDevice->setModel(m_waylandOutput->model());
m_waylandOutputDevice->setPhysicalSize(m_physicalSize);
QSize physicalSize = !m_edid.physicalSize.isEmpty() ? m_edid.physicalSize : QSize(connector->mmWidth, connector->mmHeight);
// the size might be completely borked. E.g. Samsung SyncMaster 2494HS reports 160x90 while in truth it's 520x292
// as this information is used to calculate DPI info, it's going to result in everything being huge
const QByteArray unknown = QByteArrayLiteral("unkown");
KConfigGroup group = kwinApp()->config()->group("EdidOverwrite").group(m_edid.eisaId.isEmpty() ? unknown : m_edid.eisaId)
.group(m_edid.monitorName.isEmpty() ? unknown : m_edid.monitorName)
.group(m_edid.serialNumber.isEmpty() ? unknown : m_edid.serialNumber);
if (group.hasKey("PhysicalSize")) {
const QSize overwriteSize = group.readEntry("PhysicalSize", physicalSize);
qCWarning(KWIN_DRM) << "Overwriting monitor physical size for" << m_edid.eisaId << "/" << m_edid.monitorName << "/" << m_edid.serialNumber << " from " << physicalSize << "to " << overwriteSize;
physicalSize = overwriteSize;
}
m_physicalSize = physicalSize;
m_waylandOutput->setPhysicalSize(physicalSize);
m_waylandOutputDevice->setPhysicalSize(physicalSize);
// read in mode information // read in mode information
for (int i = 0; i < connector->count_modes; ++i) { for (int i = 0; i < connector->count_modes; ++i) {
// TODO: in AMS here we could read and store for later every mode's blob_id // TODO: in AMS here we could read and store for later every mode's blob_id
// would simplify isCurrentMode(..) and presentAtomically(..) in case of mode set // would simplify isCurrentMode(..) and presentAtomically(..) in case of mode set
auto *m = &connector->modes[i]; auto *m = &connector->modes[i];
KWayland::Server::OutputInterface::ModeFlags flags;
KWayland::Server::OutputDeviceInterface::ModeFlags deviceflags; KWayland::Server::OutputDeviceInterface::ModeFlags deviceflags;
if (isCurrentMode(m)) { if (isCurrentMode(m)) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Current;
deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current; deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
} }
if (m->type & DRM_MODE_TYPE_PREFERRED) { if (m->type & DRM_MODE_TYPE_PREFERRED) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred;
deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred; deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred;
} }
const auto refreshRate = refreshRateForMode(m); const auto refreshRate = refreshRateForMode(m);
m_waylandOutput->addMode(QSize(m->hdisplay, m->vdisplay), flags, refreshRate);
KWayland::Server::OutputDeviceInterface::Mode mode; KWayland::Server::OutputDeviceInterface::Mode mode;
mode.id = i; mode.id = i;
@ -371,32 +415,7 @@ bool DrmOutput::init(drmModeConnector *connector)
qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size; qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size;
m_waylandOutputDevice->addMode(mode); m_waylandOutputDevice->addMode(mode);
} }
// set dpms
if (!m_dpms.isNull()) {
m_waylandOutput->setDpmsSupported(true);
m_waylandOutput->setDpmsMode(toWaylandDpmsMode(m_dpmsMode));
connect(m_waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this,
[this] (KWayland::Server::OutputInterface::DpmsMode mode) {
setDpms(fromWaylandDpmsMode(mode));
}, Qt::QueuedConnection
);
}
m_waylandOutput->create();
qCDebug(KWIN_DRM) << "Created OutputDevice";
m_waylandOutputDevice->create(); m_waylandOutputDevice->create();
return true;
}
void DrmOutput::initUuid()
{
QCryptographicHash hash(QCryptographicHash::Md5);
hash.addData(QByteArray::number(m_conn->id()));
hash.addData(m_edid.eisaId);
hash.addData(m_edid.monitorName);
hash.addData(m_edid.serialNumber);
m_uuid = hash.result().toHex().left(10);
} }
bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const

View file

@ -139,11 +139,13 @@ private:
bool setModeLegacy(DrmBuffer *buffer); bool setModeLegacy(DrmBuffer *buffer);
void initEdid(drmModeConnector *connector); void initEdid(drmModeConnector *connector);
void initDpms(drmModeConnector *connector); void initDpms(drmModeConnector *connector);
void initOutputDevice(drmModeConnector *connector);
bool isCurrentMode(const drmModeModeInfo *mode) const; bool isCurrentMode(const drmModeModeInfo *mode) const;
void initUuid(); void initUuid();
void setGlobalPos(const QPoint &pos); void setGlobalPos(const QPoint &pos);
void setScale(qreal scale); void setScale(qreal scale);
void initOutput();
bool initPrimaryPlane(); bool initPrimaryPlane();
bool initCursorPlane(); bool initCursorPlane();