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:
parent
6325749f21
commit
e96f2bff11
2 changed files with 83 additions and 62 deletions
|
@ -270,38 +270,10 @@ bool DrmOutput::init(drmModeConnector *connector)
|
|||
return false;
|
||||
}
|
||||
|
||||
setDpms(DpmsMode::On);
|
||||
if (!m_waylandOutput.isNull()) {
|
||||
delete m_waylandOutput.data();
|
||||
m_waylandOutput.clear();
|
||||
}
|
||||
m_waylandOutput = waylandServer()->display()->createOutput();
|
||||
connect(this, &DrmOutput::modeChanged, this,
|
||||
[this] {
|
||||
if (m_waylandOutput.isNull()) {
|
||||
return;
|
||||
}
|
||||
m_waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), refreshRateForMode(&m_mode));
|
||||
}
|
||||
);
|
||||
if (!m_waylandOutputDevice.isNull()) {
|
||||
delete m_waylandOutputDevice.data();
|
||||
m_waylandOutputDevice.clear();
|
||||
}
|
||||
m_waylandOutputDevice = waylandServer()->display()->createOutputDevice();
|
||||
m_waylandOutputDevice->setUuid(m_uuid);
|
||||
|
||||
if (!m_edid.eisaId.isEmpty()) {
|
||||
m_waylandOutput->setManufacturer(QString::fromLatin1(m_edid.eisaId));
|
||||
} else {
|
||||
m_waylandOutput->setManufacturer(i18n("unknown"));
|
||||
}
|
||||
m_waylandOutputDevice->setManufacturer(m_waylandOutput->manufacturer());
|
||||
|
||||
QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown"));
|
||||
QString modelName;
|
||||
m_internal = connector->connector_type == DRM_MODE_CONNECTOR_LVDS || connector->connector_type == DRM_MODE_CONNECTOR_eDP;
|
||||
|
||||
setDpms(DpmsMode::On);
|
||||
|
||||
if (m_internal) {
|
||||
connect(kwinApp(), &Application::screensCreated, this,
|
||||
[this] {
|
||||
|
@ -310,22 +282,6 @@ bool DrmOutput::init(drmModeConnector *connector)
|
|||
);
|
||||
}
|
||||
|
||||
if (!m_edid.monitorName.isEmpty()) {
|
||||
QString model = QString::fromLatin1(m_edid.monitorName);
|
||||
if (!m_edid.serialNumber.isEmpty()) {
|
||||
model.append('/');
|
||||
model.append(QString::fromLatin1(m_edid.serialNumber));
|
||||
}
|
||||
modelName = model;
|
||||
} else if (!m_edid.serialNumber.isEmpty()) {
|
||||
modelName = QString::fromLatin1(m_edid.serialNumber);
|
||||
} else {
|
||||
modelName = i18n("unknown");
|
||||
}
|
||||
|
||||
m_waylandOutput->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName);
|
||||
m_waylandOutputDevice->setModel(m_waylandOutput->model());
|
||||
|
||||
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
|
||||
|
@ -339,38 +295,42 @@ bool DrmOutput::init(drmModeConnector *connector)
|
|||
physicalSize = overwriteSize;
|
||||
}
|
||||
m_physicalSize = physicalSize;
|
||||
m_waylandOutput->setPhysicalSize(physicalSize);
|
||||
m_waylandOutputDevice->setPhysicalSize(physicalSize);
|
||||
|
||||
// read in mode information
|
||||
for (int i = 0; i < connector->count_modes; ++i) {
|
||||
initOutputDevice(connector);
|
||||
initOutput();
|
||||
|
||||
// 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
|
||||
return true;
|
||||
}
|
||||
|
||||
auto *m = &connector->modes[i];
|
||||
KWayland::Server::OutputInterface::ModeFlags flags;
|
||||
KWayland::Server::OutputDeviceInterface::ModeFlags deviceflags;
|
||||
if (isCurrentMode(m)) {
|
||||
flags |= KWayland::Server::OutputInterface::ModeFlag::Current;
|
||||
deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
|
||||
}
|
||||
if (m->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred;
|
||||
deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
const auto refreshRate = refreshRateForMode(m);
|
||||
m_waylandOutput->addMode(QSize(m->hdisplay, m->vdisplay), flags, refreshRate);
|
||||
|
||||
KWayland::Server::OutputDeviceInterface::Mode mode;
|
||||
mode.id = i;
|
||||
mode.size = QSize(m->hdisplay, m->vdisplay);
|
||||
mode.flags = deviceflags;
|
||||
mode.refreshRate = refreshRate;
|
||||
qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size;
|
||||
m_waylandOutputDevice->addMode(mode);
|
||||
void DrmOutput::initOutput()
|
||||
{
|
||||
Q_ASSERT(m_waylandOutputDevice);
|
||||
if (!m_waylandOutput.isNull()) {
|
||||
delete m_waylandOutput.data();
|
||||
m_waylandOutput.clear();
|
||||
}
|
||||
m_waylandOutput = waylandServer()->display()->createOutput();
|
||||
connect(this, &DrmOutput::modeChanged, this,
|
||||
[this] {
|
||||
if (m_waylandOutput.isNull()) {
|
||||
return;
|
||||
}
|
||||
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()) {
|
||||
|
@ -383,20 +343,79 @@ bool DrmOutput::init(drmModeConnector *connector)
|
|||
);
|
||||
}
|
||||
|
||||
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();
|
||||
qCDebug(KWIN_DRM) << "Created OutputDevice";
|
||||
m_waylandOutputDevice->create();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrmOutput::initUuid()
|
||||
void DrmOutput::initOutputDevice(drmModeConnector *connector)
|
||||
{
|
||||
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);
|
||||
if (!m_waylandOutputDevice.isNull()) {
|
||||
delete m_waylandOutputDevice.data();
|
||||
m_waylandOutputDevice.clear();
|
||||
}
|
||||
m_waylandOutputDevice = waylandServer()->display()->createOutputDevice();
|
||||
m_waylandOutputDevice->setUuid(m_uuid);
|
||||
|
||||
if (!m_edid.eisaId.isEmpty()) {
|
||||
m_waylandOutputDevice->setManufacturer(QString::fromLatin1(m_edid.eisaId));
|
||||
} else {
|
||||
m_waylandOutputDevice->setManufacturer(i18n("unknown"));
|
||||
}
|
||||
|
||||
QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown"));
|
||||
QString modelName;
|
||||
|
||||
if (!m_edid.monitorName.isEmpty()) {
|
||||
QString model = QString::fromLatin1(m_edid.monitorName);
|
||||
if (!m_edid.serialNumber.isEmpty()) {
|
||||
model.append('/');
|
||||
model.append(QString::fromLatin1(m_edid.serialNumber));
|
||||
}
|
||||
modelName = model;
|
||||
} else if (!m_edid.serialNumber.isEmpty()) {
|
||||
modelName = QString::fromLatin1(m_edid.serialNumber);
|
||||
} else {
|
||||
modelName = i18n("unknown");
|
||||
}
|
||||
|
||||
m_waylandOutputDevice->setModel(connectorName + QStringLiteral("-") + QString::number(connector->connector_type_id) + QStringLiteral("-") + modelName);
|
||||
|
||||
m_waylandOutputDevice->setPhysicalSize(m_physicalSize);
|
||||
|
||||
// read in mode information
|
||||
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
|
||||
// would simplify isCurrentMode(..) and presentAtomically(..) in case of mode set
|
||||
auto *m = &connector->modes[i];
|
||||
KWayland::Server::OutputDeviceInterface::ModeFlags deviceflags;
|
||||
if (isCurrentMode(m)) {
|
||||
deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
|
||||
}
|
||||
if (m->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
deviceflags |= KWayland::Server::OutputDeviceInterface::ModeFlag::Preferred;
|
||||
}
|
||||
|
||||
const auto refreshRate = refreshRateForMode(m);
|
||||
|
||||
KWayland::Server::OutputDeviceInterface::Mode mode;
|
||||
mode.id = i;
|
||||
mode.size = QSize(m->hdisplay, m->vdisplay);
|
||||
mode.flags = deviceflags;
|
||||
mode.refreshRate = refreshRate;
|
||||
qCDebug(KWIN_DRM) << "Adding mode: " << i << mode.size;
|
||||
m_waylandOutputDevice->addMode(mode);
|
||||
}
|
||||
m_waylandOutputDevice->create();
|
||||
}
|
||||
|
||||
bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const
|
||||
|
|
|
@ -139,11 +139,13 @@ private:
|
|||
bool setModeLegacy(DrmBuffer *buffer);
|
||||
void initEdid(drmModeConnector *connector);
|
||||
void initDpms(drmModeConnector *connector);
|
||||
void initOutputDevice(drmModeConnector *connector);
|
||||
|
||||
bool isCurrentMode(const drmModeModeInfo *mode) const;
|
||||
void initUuid();
|
||||
void setGlobalPos(const QPoint &pos);
|
||||
void setScale(qreal scale);
|
||||
|
||||
void initOutput();
|
||||
bool initPrimaryPlane();
|
||||
bool initCursorPlane();
|
||||
|
||||
|
|
Loading…
Reference in a new issue