platforms/wayland: Add initial HiDPI support
This can be useful for test purposes and for people who have HiDPI monitors.
This commit is contained in:
parent
6b94be8652
commit
41a5362136
5 changed files with 35 additions and 37 deletions
|
@ -50,8 +50,8 @@ EglWaylandOutput::EglWaylandOutput(WaylandOutput *output, QObject *parent)
|
|||
bool EglWaylandOutput::init(EglWaylandBackend *backend)
|
||||
{
|
||||
auto surface = m_waylandOutput->surface();
|
||||
const QSize &size = m_waylandOutput->geometry().size();
|
||||
auto overlay = wl_egl_window_create(*surface, size.width(), size.height());
|
||||
const QSize nativeSize = m_waylandOutput->geometry().size() * m_waylandOutput->scale();
|
||||
auto overlay = wl_egl_window_create(*surface, nativeSize.width(), nativeSize.height());
|
||||
if (!overlay) {
|
||||
qCCritical(KWIN_WAYLAND_BACKEND) << "Creating Wayland Egl window failed";
|
||||
return false;
|
||||
|
@ -71,19 +71,15 @@ bool EglWaylandOutput::init(EglWaylandBackend *backend)
|
|||
m_eglSurface = eglSurface;
|
||||
|
||||
connect(m_waylandOutput, &WaylandOutput::sizeChanged, this, &EglWaylandOutput::updateSize);
|
||||
connect(m_waylandOutput, &WaylandOutput::modeChanged, this, &EglWaylandOutput::updateMode);
|
||||
connect(m_waylandOutput, &WaylandOutput::modeChanged, this, &EglWaylandOutput::updateSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EglWaylandOutput::updateSize(const QSize &size)
|
||||
void EglWaylandOutput::updateSize()
|
||||
{
|
||||
wl_egl_window_resize(m_overlay, size.width(), size.height(), 0, 0);
|
||||
}
|
||||
|
||||
void EglWaylandOutput::updateMode()
|
||||
{
|
||||
updateSize(m_waylandOutput->geometry().size());
|
||||
const QSize nativeSize = m_waylandOutput->geometry().size() * m_waylandOutput->scale();
|
||||
wl_egl_window_resize(m_overlay, nativeSize.width(), nativeSize.height(), 0, 0);
|
||||
}
|
||||
|
||||
EglWaylandBackend::EglWaylandBackend(WaylandBackend *b)
|
||||
|
@ -240,9 +236,7 @@ bool EglWaylandBackend::makeContextCurrent(EglWaylandOutput *output)
|
|||
}
|
||||
|
||||
const QRect &v = output->m_waylandOutput->geometry();
|
||||
|
||||
//The output is in scaled coordinates
|
||||
const qreal scale = 1;
|
||||
const qreal scale = output->m_waylandOutput->scale();
|
||||
|
||||
const QSize overall = screens()->size();
|
||||
glViewport(-v.x() * scale, (v.height() - overall.height() + v.y()) * scale,
|
||||
|
@ -324,13 +318,15 @@ void EglWaylandBackend::aboutToStartPainting(int screenId, const QRegion &damage
|
|||
|
||||
void EglWaylandBackend::presentOnSurface(EglWaylandOutput *output, const QRegion &damage)
|
||||
{
|
||||
output->m_waylandOutput->surface()->setupFrameCallback();
|
||||
Compositor::self()->aboutToSwapBuffers();
|
||||
WaylandOutput *waylandOutput = output->m_waylandOutput;
|
||||
|
||||
Q_EMIT output->m_waylandOutput->outputChange(damage);
|
||||
waylandOutput->surface()->setupFrameCallback();
|
||||
waylandOutput->surface()->setScale(waylandOutput->scale());
|
||||
Compositor::self()->aboutToSwapBuffers();
|
||||
Q_EMIT waylandOutput->outputChange(damage);
|
||||
|
||||
if (supportsSwapBuffersWithDamage() && !output->m_damageHistory.isEmpty()) {
|
||||
QVector<EGLint> rects = regionToRects(output->m_damageHistory.constFirst(), output->m_waylandOutput);
|
||||
QVector<EGLint> rects = regionToRects(output->m_damageHistory.constFirst(), waylandOutput);
|
||||
eglSwapBuffersWithDamageEXT(eglDisplay(), output->m_eglSurface,
|
||||
rects.data(), rects.count()/4);
|
||||
} else {
|
||||
|
|
|
@ -34,8 +34,7 @@ public:
|
|||
~EglWaylandOutput() override = default;
|
||||
|
||||
bool init(EglWaylandBackend *backend);
|
||||
void updateSize(const QSize &size);
|
||||
void updateMode();
|
||||
void updateSize();
|
||||
|
||||
private:
|
||||
WaylandOutput *m_waylandOutput;
|
||||
|
|
|
@ -86,6 +86,7 @@ void WaylandQPainterOutput::present(const QRegion &damage)
|
|||
auto s = m_waylandOutput->surface();
|
||||
s->attachBuffer(m_buffer);
|
||||
s->damage(damage);
|
||||
s->setScale(m_waylandOutput->scale());
|
||||
s->commit();
|
||||
}
|
||||
|
||||
|
@ -104,9 +105,9 @@ void WaylandQPainterOutput::prepareRenderingFrame()
|
|||
}
|
||||
m_buffer.clear();
|
||||
|
||||
const QSize size(m_waylandOutput->geometry().size());
|
||||
const QSize nativeSize(m_waylandOutput->geometry().size() * m_waylandOutput->scale());
|
||||
|
||||
m_buffer = m_pool->getBuffer(size, size.width() * 4);
|
||||
m_buffer = m_pool->getBuffer(nativeSize, nativeSize.width() * 4);
|
||||
if (!m_buffer) {
|
||||
qCDebug(KWIN_WAYLAND_BACKEND) << "Did not get a new Buffer from Shm Pool";
|
||||
m_backBuffer = QImage();
|
||||
|
@ -116,7 +117,7 @@ void WaylandQPainterOutput::prepareRenderingFrame()
|
|||
auto b = m_buffer.toStrongRef();
|
||||
b->setUsed(true);
|
||||
|
||||
m_backBuffer = QImage(b->address(), size.width(), size.height(), QImage::Format_RGB32);
|
||||
m_backBuffer = QImage(b->address(), nativeSize.width(), nativeSize.height(), QImage::Format_RGB32);
|
||||
m_backBuffer.fill(Qt::transparent);
|
||||
// qCDebug(KWIN_WAYLAND_BACKEND) << "Created a new back buffer for output surface" << m_waylandOutput->surface();
|
||||
}
|
||||
|
|
|
@ -92,29 +92,30 @@ void WaylandCursor::installImage()
|
|||
{
|
||||
const QImage image = Cursors::self()->currentCursor()->image();
|
||||
if (image.isNull() || image.size().isEmpty()) {
|
||||
doInstallImage(nullptr, QSize());
|
||||
doInstallImage(nullptr, QSize(), 1);
|
||||
return;
|
||||
}
|
||||
|
||||
auto buffer = m_backend->shmPool()->createBuffer(image).toStrongRef();
|
||||
wl_buffer *imageBuffer = *buffer.data();
|
||||
doInstallImage(imageBuffer, image.size());
|
||||
doInstallImage(imageBuffer, image.size(), image.devicePixelRatio());
|
||||
}
|
||||
|
||||
void WaylandCursor::doInstallImage(wl_buffer *image, const QSize &size)
|
||||
void WaylandCursor::doInstallImage(wl_buffer *image, const QSize &size, qreal scale)
|
||||
{
|
||||
auto *pointer = m_backend->seat()->pointer();
|
||||
if (!pointer || !pointer->isValid()) {
|
||||
return;
|
||||
}
|
||||
pointer->setCursor(m_surface, image ? Cursors::self()->currentCursor()->hotspot() : QPoint());
|
||||
drawSurface(image, size);
|
||||
drawSurface(image, size, scale);
|
||||
}
|
||||
|
||||
void WaylandCursor::drawSurface(wl_buffer *image, const QSize &size)
|
||||
void WaylandCursor::drawSurface(wl_buffer *image, const QSize &size, qreal scale)
|
||||
{
|
||||
m_surface->attachBuffer(image);
|
||||
m_surface->damage(QRect(QPoint(0,0), size));
|
||||
m_surface->setScale(scale);
|
||||
m_surface->damageBuffer(QRect(QPoint(0, 0), size));
|
||||
m_surface->commit(Surface::CommitFlag::None);
|
||||
m_backend->flush();
|
||||
}
|
||||
|
@ -161,7 +162,7 @@ void WaylandSubSurfaceCursor::createSubSurface()
|
|||
m_subSurface->setMode(SubSurface::Mode::Desynchronized);
|
||||
}
|
||||
|
||||
void WaylandSubSurfaceCursor::doInstallImage(wl_buffer *image, const QSize &size)
|
||||
void WaylandSubSurfaceCursor::doInstallImage(wl_buffer *image, const QSize &size, qreal scale)
|
||||
{
|
||||
if (!image) {
|
||||
delete m_subSurface;
|
||||
|
@ -171,7 +172,7 @@ void WaylandSubSurfaceCursor::doInstallImage(wl_buffer *image, const QSize &size
|
|||
createSubSurface();
|
||||
// cursor position might have changed due to different cursor hot spot
|
||||
move(input()->pointer()->pos());
|
||||
drawSurface(image, size);
|
||||
drawSurface(image, size, scale);
|
||||
}
|
||||
|
||||
QPointF WaylandSubSurfaceCursor::absoluteToRelativePosition(const QPointF &position)
|
||||
|
@ -496,11 +497,12 @@ WaylandBackend::~WaylandBackend()
|
|||
|
||||
void WaylandBackend::init()
|
||||
{
|
||||
connect(m_registry, &Registry::compositorAnnounced, this,
|
||||
[this](quint32 name) {
|
||||
m_compositor->setup(m_registry->bindCompositor(name, 1));
|
||||
connect(m_registry, &Registry::compositorAnnounced, this, [this](quint32 name, quint32 version) {
|
||||
if (version < 4) {
|
||||
qFatal("wl_compositor version 4 or later is required");
|
||||
}
|
||||
);
|
||||
m_compositor->setup(m_registry->bindCompositor(name, version));
|
||||
});
|
||||
connect(m_registry, &Registry::subCompositorAnnounced, this,
|
||||
[this](quint32 name) {
|
||||
m_subCompositor->setup(m_registry->bindSubCompositor(name, 1));
|
||||
|
|
|
@ -79,8 +79,8 @@ public:
|
|||
|
||||
protected:
|
||||
void resetSurface();
|
||||
virtual void doInstallImage(wl_buffer *image, const QSize &size);
|
||||
void drawSurface(wl_buffer *image, const QSize &size);
|
||||
virtual void doInstallImage(wl_buffer *image, const QSize &size, qreal scale);
|
||||
void drawSurface(wl_buffer *image, const QSize &size, qreal scale);
|
||||
|
||||
KWayland::Client::Surface *surface() const {
|
||||
return m_surface;
|
||||
|
@ -108,7 +108,7 @@ public:
|
|||
|
||||
private:
|
||||
void changeOutput(WaylandOutput *output);
|
||||
void doInstallImage(wl_buffer *image, const QSize &size) override;
|
||||
void doInstallImage(wl_buffer *image, const QSize &size, qreal scale) override;
|
||||
void createSubSurface();
|
||||
|
||||
QPointF absoluteToRelativePosition(const QPointF &position);
|
||||
|
|
Loading…
Reference in a new issue