Commit 80d3f148 authored by David Edmundson's avatar David Edmundson

[wayland] Simplify output handling

Summary:
Instead of changing lifespan of kwayland objects we can just call
create() and delete() on it which affects the lifespan of the underlying
resource, but not the kwayland wrapper.

This gets rid of some duplicate syncing.

Test Plan:
Ran WAYLAND_DEBUG=1
plugged in and removed a monitor
output showed wl_output and xdg_output being handled correctly

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D27899
parent 93e8231b
......@@ -3,6 +3,7 @@
This file is part of the KDE project.
Copyright 2019 Roman Gilg <subdiff@gmail.com>
Copyright 2020 David Edmundson <davidedmundson@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -37,13 +38,18 @@ namespace KWin
AbstractWaylandOutput::AbstractWaylandOutput(QObject *parent)
: AbstractOutput(parent)
{
m_waylandOutput = waylandServer()->display()->createOutput(this);
m_waylandOutputDevice = waylandServer()->display()->createOutputDevice(this);
m_xdgOutput = waylandServer()->xdgOutputManager()->createXdgOutput(m_waylandOutput, this);
connect(m_waylandOutput, &KWayland::Server::OutputInterface::dpmsModeRequested, this,
[this] (KWayland::Server::OutputInterface::DpmsMode mode) {
updateDpms(mode);
});
}
AbstractWaylandOutput::~AbstractWaylandOutput()
{
delete m_xdgOutput.data();
delete m_waylandOutput.data();
delete m_waylandOutputDevice.data();
}
QString AbstractWaylandOutput::name() const
......@@ -81,11 +87,9 @@ void AbstractWaylandOutput::setGlobalPos(const QPoint &pos)
{
m_waylandOutputDevice->setGlobalPosition(pos);
if (isEnabled()) {
m_waylandOutput->setGlobalPosition(pos);
m_xdgOutput->setLogicalPosition(pos);
m_xdgOutput->done();
}
m_waylandOutput->setGlobalPosition(pos);
m_xdgOutput->setLogicalPosition(pos);
m_xdgOutput->done();
}
QSize AbstractWaylandOutput::modeSize() const
......@@ -107,17 +111,15 @@ void AbstractWaylandOutput::setScale(qreal scale)
{
m_waylandOutputDevice->setScaleF(scale);
if (isEnabled()) {
// this is the scale that clients will ideally use for their buffers
// this has to be an int which is fine
// this is the scale that clients will ideally use for their buffers
// this has to be an int which is fine
// I don't know whether we want to round or ceil
// or maybe even set this to 3 when we're scaling to 1.5
// don't treat this like it's chosen deliberately
m_waylandOutput->setScale(std::ceil(scale));
m_xdgOutput->setLogicalSize(pixelSize() / scale);
m_xdgOutput->done();
}
// I don't know whether we want to round or ceil
// or maybe even set this to 3 when we're scaling to 1.5
// don't treat this like it's chosen deliberately
m_waylandOutput->setScale(std::ceil(scale));
m_xdgOutput->setLogicalSize(pixelSize() / scale);
m_xdgOutput->done();
}
using DeviceInterface = KWayland::Server::OutputDeviceInterface;
......@@ -151,11 +153,9 @@ void AbstractWaylandOutput::setTransform(DeviceInterface::Transform transform)
{
m_waylandOutputDevice->setTransform(transform);
if (isEnabled()) {
m_waylandOutput->setTransform(toOutputTransform(transform));
m_xdgOutput->setLogicalSize(pixelSize() / scale());
m_xdgOutput->done();
}
m_waylandOutput->setTransform(toOutputTransform(transform));
m_xdgOutput->setLogicalSize(pixelSize() / scale());
m_xdgOutput->done();
}
inline
......@@ -223,85 +223,28 @@ void AbstractWaylandOutput::setEnabled(bool enable)
}
if (enable) {
waylandOutputDevice()->setEnabled(DeviceInterface::Enablement::Enabled);
createWaylandOutput();
m_waylandOutputDevice->setEnabled(DeviceInterface::Enablement::Enabled);
m_waylandOutput->create();
updateEnablement(true);
} else {
waylandOutputDevice()->setEnabled(DeviceInterface::Enablement::Disabled);
m_waylandOutputDevice->setEnabled(DeviceInterface::Enablement::Disabled);
m_waylandOutput->destroy();
// xdg-output is destroyed in KWayland on wl_output going away.
delete m_waylandOutput.data();
updateEnablement(false);
}
}
void AbstractWaylandOutput::setWaylandMode(const QSize &size, int refreshRate)
{
if (!isEnabled()) {
return;
}
m_waylandOutput->setCurrentMode(size, refreshRate);
m_xdgOutput->setLogicalSize(pixelSize() / scale());
m_xdgOutput->done();
}
void AbstractWaylandOutput::createXdgOutput()
{
Q_ASSERT(!m_waylandOutput.isNull());
Q_ASSERT(m_xdgOutput.isNull());
m_xdgOutput = waylandServer()->xdgOutputManager()->createXdgOutput(m_waylandOutput, m_waylandOutput);
m_xdgOutput->setLogicalSize(pixelSize() / scale());
m_xdgOutput->setLogicalPosition(globalPos());
m_xdgOutput->done();
}
void AbstractWaylandOutput::createWaylandOutput()
{
Q_ASSERT(m_waylandOutput.isNull());
m_waylandOutput = waylandServer()->display()->createOutput();
createXdgOutput();
/*
* add base wayland output data
*/
m_waylandOutput->setManufacturer(m_waylandOutputDevice->manufacturer());
m_waylandOutput->setModel(m_waylandOutputDevice->model());
m_waylandOutput->setPhysicalSize(m_waylandOutputDevice->physicalSize());
/*
* add modes
*/
for(const auto &mode: m_waylandOutputDevice->modes()) {
KWayland::Server::OutputInterface::ModeFlags flags;
if (mode.flags & DeviceInterface::ModeFlag::Current) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Current;
}
if (mode.flags & DeviceInterface::ModeFlag::Preferred) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred;
}
m_waylandOutput->addMode(mode.size, flags, mode.refreshRate);
}
m_waylandOutput->create();
/*
* set dpms
*/
m_waylandOutput->setDpmsSupported(m_supportsDpms);
// set to last known mode
m_waylandOutput->setDpmsMode(m_dpms);
connect(m_waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this,
[this] (KWayland::Server::OutputInterface::DpmsMode mode) {
updateDpms(mode);
}
);
}
void AbstractWaylandOutput::initInterfaces(const QString &model, const QString &manufacturer,
const QByteArray &uuid, const QSize &physicalSize,
const QVector<DeviceInterface::Mode> &modes)
{
Q_ASSERT(m_waylandOutputDevice.isNull());
m_waylandOutputDevice = waylandServer()->display()->createOutputDevice();
m_waylandOutputDevice->setUuid(uuid);
if (!manufacturer.isEmpty()) {
......@@ -313,14 +256,29 @@ void AbstractWaylandOutput::initInterfaces(const QString &model, const QString &
m_waylandOutputDevice->setModel(model);
m_waylandOutputDevice->setPhysicalSize(physicalSize);
m_waylandOutput->setManufacturer(m_waylandOutputDevice->manufacturer());
m_waylandOutput->setModel(m_waylandOutputDevice->model());
m_waylandOutput->setPhysicalSize(m_waylandOutputDevice->physicalSize());
int i = 0;
for (auto mode : modes) {
qCDebug(KWIN_CORE).nospace() << "Adding mode " << ++i << ": " << mode.size << " [" << mode.refreshRate << "]";
m_waylandOutputDevice->addMode(mode);
KWayland::Server::OutputInterface::ModeFlags flags;
if (mode.flags & DeviceInterface::ModeFlag::Current) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Current;
}
if (mode.flags & DeviceInterface::ModeFlag::Preferred) {
flags |= KWayland::Server::OutputInterface::ModeFlag::Preferred;
}
m_waylandOutput->addMode(mode.size, flags, mode.refreshRate);
}
m_waylandOutputDevice->create();
createWaylandOutput();
// start off enabled
m_waylandOutput->create();
m_xdgOutput->setLogicalSize(pixelSize() / scale());
m_xdgOutput->done();
}
QSize AbstractWaylandOutput::orientateSize(const QSize &size) const
......
......@@ -132,14 +132,6 @@ protected:
const QByteArray &uuid, const QSize &physicalSize,
const QVector<KWayland::Server::OutputDeviceInterface::Mode> &modes);
QPointer<KWayland::Server::XdgOutputInterface> xdgOutput() const {
return m_xdgOutput;
}
QPointer<KWayland::Server::OutputDeviceInterface> waylandOutputDevice() const {
return m_waylandOutputDevice;
}
QPoint globalPos() const;
bool internal() const {
......@@ -149,7 +141,7 @@ protected:
m_internal = set;
}
void setDpmsSupported(bool set) {
m_supportsDpms = set;
m_waylandOutput->setDpmsSupported(set);
}
virtual void updateEnablement(bool enable) {
......@@ -171,19 +163,14 @@ protected:
QSize orientateSize(const QSize &size) const;
private:
void createWaylandOutput();
void createXdgOutput();
void setTransform(KWayland::Server::OutputDeviceInterface::Transform transform);
QPointer<KWayland::Server::OutputInterface> m_waylandOutput;
QPointer<KWayland::Server::XdgOutputInterface> m_xdgOutput;
QPointer<KWayland::Server::OutputDeviceInterface> m_waylandOutputDevice;
KWayland::Server::OutputInterface *m_waylandOutput;
KWayland::Server::XdgOutputInterface *m_xdgOutput;
KWayland::Server::OutputDeviceInterface *m_waylandOutputDevice;
KWayland::Server::OutputInterface::DpmsMode m_dpms = KWayland::Server::OutputInterface::DpmsMode::On;
bool m_internal = false;
bool m_supportsDpms = false;
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment