diff --git a/plugins/platforms/wayland/egl_wayland_backend.cpp b/plugins/platforms/wayland/egl_wayland_backend.cpp index e845297c30..c0a74693aa 100644 --- a/plugins/platforms/wayland/egl_wayland_backend.cpp +++ b/plugins/platforms/wayland/egl_wayland_backend.cpp @@ -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 rects = regionToRects(output->m_damageHistory.constFirst(), output->m_waylandOutput); + QVector rects = regionToRects(output->m_damageHistory.constFirst(), waylandOutput); eglSwapBuffersWithDamageEXT(eglDisplay(), output->m_eglSurface, rects.data(), rects.count()/4); } else { diff --git a/plugins/platforms/wayland/egl_wayland_backend.h b/plugins/platforms/wayland/egl_wayland_backend.h index b14df8d7c0..f119e6c94a 100644 --- a/plugins/platforms/wayland/egl_wayland_backend.h +++ b/plugins/platforms/wayland/egl_wayland_backend.h @@ -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; diff --git a/plugins/platforms/wayland/scene_qpainter_wayland_backend.cpp b/plugins/platforms/wayland/scene_qpainter_wayland_backend.cpp index 0bca5d7d96..bc15d9231a 100644 --- a/plugins/platforms/wayland/scene_qpainter_wayland_backend.cpp +++ b/plugins/platforms/wayland/scene_qpainter_wayland_backend.cpp @@ -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(); } diff --git a/plugins/platforms/wayland/wayland_backend.cpp b/plugins/platforms/wayland/wayland_backend.cpp index 21641edb62..f3088a271e 100644 --- a/plugins/platforms/wayland/wayland_backend.cpp +++ b/plugins/platforms/wayland/wayland_backend.cpp @@ -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)); diff --git a/plugins/platforms/wayland/wayland_backend.h b/plugins/platforms/wayland/wayland_backend.h index 643896ef0c..cf5d8de125 100644 --- a/plugins/platforms/wayland/wayland_backend.h +++ b/plugins/platforms/wayland/wayland_backend.h @@ -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);