Get output physical size from output device

Summary:
Get the physical size directly from the always available output device
interface instead of saving an additional copy in the abstract wayland
output class.

There is some ambiguity with orientation and naming that needs to be
cleaned up when output orientation is reworked.

Test Plan: Nested Wayland, Drm, virtual backends tested.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Maniphest Tasks: T11459

Differential Revision: https://phabricator.kde.org/D23496
This commit is contained in:
Roman Gilg 2019-08-27 16:52:39 +02:00
parent dbb2cede08
commit 331f5d7da7
9 changed files with 42 additions and 56 deletions

View file

@ -59,7 +59,7 @@ QRect AbstractWaylandOutput::geometry() const
QSize AbstractWaylandOutput::physicalSize() const
{
return orientateSize(m_physicalSize);
return orientateSize(m_waylandOutputDevice->physicalSize());
}
int AbstractWaylandOutput::refreshRate() const
@ -203,7 +203,7 @@ void AbstractWaylandOutput::initWaylandOutput()
*/
m_waylandOutput->setManufacturer(m_waylandOutputDevice->manufacturer());
m_waylandOutput->setModel(m_waylandOutputDevice->model());
m_waylandOutput->setPhysicalSize(rawPhysicalSize());
m_waylandOutput->setPhysicalSize(m_waylandOutputDevice->physicalSize());
/*
* add modes
@ -236,6 +236,7 @@ void AbstractWaylandOutput::initWaylandOutput()
void AbstractWaylandOutput::initWaylandOutputDevice(const QString &model,
const QString &manufacturer,
const QByteArray &uuid,
const QSize &physicalSize,
const QVector<KWayland::Server::OutputDeviceInterface::Mode> &modes)
{
Q_ASSERT(m_waylandOutputDevice.isNull());
@ -249,7 +250,7 @@ void AbstractWaylandOutput::initWaylandOutputDevice(const QString &model,
}
m_waylandOutputDevice->setModel(model);
m_waylandOutputDevice->setPhysicalSize(m_physicalSize);
m_waylandOutputDevice->setPhysicalSize(physicalSize);
int i = 0;
for (auto mode : modes) {

View file

@ -113,6 +113,7 @@ protected:
void initWaylandOutputDevice(const QString &model,
const QString &manufacturer,
const QByteArray &uuid,
const QSize &physicalSize,
const QVector<KWayland::Server::OutputDeviceInterface::Mode> &modes);
QPointer<KWayland::Server::XdgOutputInterface> xdgOutput() const {
@ -126,13 +127,6 @@ protected:
QPoint globalPos() const;
QSize rawPhysicalSize() const {
return m_physicalSize;
}
void setRawPhysicalSize(const QSize &set) {
m_physicalSize = set;
}
void setOrientation(Qt::ScreenOrientation set) {
m_orientation = set;
}
@ -166,7 +160,6 @@ private:
KWayland::Server::OutputInterface::DpmsMode m_dpms = KWayland::Server::OutputInterface::DpmsMode::On;
QSize m_physicalSize;
Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
bool m_internal = false;
bool m_supportsDpms = false;

View file

@ -266,20 +266,6 @@ bool DrmOutput::init(drmModeConnector *connector)
);
}
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("unknown");
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;
}
setRawPhysicalSize(physicalSize);
initOutputDevice(connector);
setEnabled(true);
@ -343,7 +329,20 @@ void DrmOutput::initOutputDevice(drmModeConnector *connector)
modes << mode;
}
AbstractWaylandOutput::initWaylandOutputDevice(model, manufacturer, m_uuid, modes);
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("unknown");
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;
}
initWaylandOutputDevice(model, manufacturer, m_uuid, physicalSize, modes);
}
bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const

View file

@ -37,15 +37,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin
{
void FramebufferOutput::init(const QSize &size)
void FramebufferOutput::init(const QSize &pixelSize, const QSize &physicalSize)
{
KWayland::Server::OutputDeviceInterface::Mode mode;
mode.id = 0;
mode.size = size;
mode.size = pixelSize;
mode.flags = KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
mode.refreshRate = 60000; // TODO: get actual refresh rate of fb device?
AbstractWaylandOutput::initWaylandOutputDevice("model_TODO", "manufacturer_TODO",
"UUID_TODO", { mode });
"UUID_TODO", physicalSize, { mode });
}
FramebufferBackend::FramebufferBackend(QObject *parent)
@ -149,8 +149,7 @@ bool FramebufferBackend::handleScreenInfo()
}
auto *output = new FramebufferOutput(this);
output->init(QSize(varinfo.xres, varinfo.yres));
output->setRawPhysicalSize(QSize(varinfo.width, varinfo.height));
output->init(QSize(varinfo.xres, varinfo.yres), QSize(varinfo.width, varinfo.height));
output->setEnabled(true);
m_outputs << output;

View file

@ -37,11 +37,7 @@ public:
FramebufferOutput(QObject *parent = nullptr) : AbstractWaylandOutput(parent) {}
~FramebufferOutput() override = default;
void init(const QSize &size);
void setRawPhysicalSize(const QSize &set) {
AbstractWaylandOutput::setRawPhysicalSize(set);
}
void init(const QSize &pixelSize, const QSize &physicalSize);
};
class KWIN_EXPORT FramebufferBackend : public Platform

View file

@ -502,35 +502,35 @@ HwcomposerOutput::HwcomposerOutput(hwc_composer_device_1_t *device)
HWC_DISPLAY_NO_ATTRIBUTE
};
device->getDisplayAttributes(device, 0, configs[0], attributes, attr_values);
QSize pixel(attr_values[0], attr_values[1]);
if (pixel.isEmpty()) {
QSize pixelSize(attr_values[0], attr_values[1]);
if (pixelSize.isEmpty()) {
return;
}
QSizeF physicalSize;
if (attr_values[2] != 0 && attr_values[3] != 0) {
static const qreal factor = 25.4;
auto physicalSize = QSizeF(qreal(pixel.width() * 1000) / qreal(attr_values[2]) * factor,
qreal(pixel.height() * 1000) / qreal(attr_values[3]) * factor);
setRawPhysicalSize(physicalSize.toSize());
physicalSize = QSizeF(qreal(pixelSize.width() * 1000) / qreal(attr_values[2]) * factor,
qreal(pixelSize.height() * 1000) / qreal(attr_values[3]) * factor);
} else {
// couldn't read physical size, assume 96 dpi
setRawPhysicalSize(pixel / 3.8);
physicalSize = pixelSize / 3.8;
}
OutputDeviceInterface::Mode mode;
mode.id = 0;
mode.size = pixel;
mode.size = pixelSize;
mode.flags = OutputDeviceInterface::ModeFlag::Current | OutputDeviceInterface::ModeFlag::Preferred;
mode.refreshRate = (attr_values[4] == 0) ? 60000 : 10E11/attr_values[4];
initWaylandOutputDevice(QString(), QString(), QByteArray(), {mode});
initWaylandOutputDevice(QString(), QString(), QByteArray(), physicalSize.toSize(), {mode});
setInternal(true);
setEnabled(true);
setDpmsSupported(true);
const auto outputGroup = kwinApp()->config()->group("HWComposerOutputs").group("0");
setScale(outputGroup.readEntry("Scale", 1));
setWaylandMode(pixel, mode.refreshRate);
setWaylandMode(pixelSize, mode.refreshRate);
}
HwcomposerOutput::~HwcomposerOutput()

View file

@ -40,7 +40,7 @@ void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
mode.flags = KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
mode.refreshRate = 60000; // TODO
AbstractWaylandOutput::initWaylandOutputDevice("model_TODO", "manufacturer_TODO",
"UUID_TODO", { mode });
"UUID_TODO", pixelSize, { mode });
setEnabled(true);
setGeometry(QRect(logicalPosition, pixelSize));
setScale(1.);
@ -49,7 +49,6 @@ void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
void VirtualOutput::setGeometry(const QRect &geo)
{
// TODO: set mode to have updated pixelSize
setRawPhysicalSize(geo.size());
setGlobalPos(geo.topLeft());
}

View file

@ -62,8 +62,7 @@ void WaylandOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
mode.flags = KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
mode.refreshRate = 60000; // TODO: can we get refresh rate data from Wayland host?
AbstractWaylandOutput::initWaylandOutputDevice("model_TODO", "manufacturer_TODO",
"UUID_TODO", { mode });
setRawPhysicalSize(pixelSize);
"UUID_TODO", pixelSize, { mode });
setEnabled(true);
setGeometry(logicalPosition, pixelSize);
setScale(backend()->initialOutputScale());
@ -72,7 +71,8 @@ void WaylandOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
void WaylandOutput::setGeometry(const QPoint &logicalPosition, const QSize &pixelSize)
{
// TODO: set mode to have updated pixelSize
setRawPhysicalSize(pixelSize);
Q_UNUSED(pixelSize)
setGlobalPos(logicalPosition);
}

View file

@ -54,8 +54,12 @@ void X11WindowedOutput::init(const QPoint &logicalPosition, const QSize &pixelSi
mode.size = pixelSize;
mode.flags = KWayland::Server::OutputDeviceInterface::ModeFlag::Current;
mode.refreshRate = 60000; // TODO: get refresh rate via randr
// Physicial size must be adjusted, such that QPA calculates correct sizes of
// internal elements.
const QSize physicalSize = pixelSize / 96.0 * 25.4 / scale();
AbstractWaylandOutput::initWaylandOutputDevice("model_TODO", "manufacturer_TODO",
"UUID_TODO", { mode });
"UUID_TODO", physicalSize, { mode });
setEnabled(true);
setGeometry(logicalPosition, pixelSize);
@ -137,11 +141,6 @@ void X11WindowedOutput::initXInputForWindow()
void X11WindowedOutput::setGeometry(const QPoint &logicalPosition, const QSize &pixelSize)
{
// TODO: set mode to have updated pixelSize
// Physicial size must be adjusted, such that QPA calculates correct sizes of
// internal elements.
setRawPhysicalSize(pixelSize / 96.0 * 25.4 / scale());
setGlobalPos(logicalPosition);
}