diff --git a/CMakeLists.txt b/CMakeLists.txt index 802da3fd93..3b406b925a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,6 +439,7 @@ if(HAVE_WAYLAND) backends/fbdev/fb_backend.cpp backends/fbdev/scene_qpainter_fb_backend.cpp backends/fbdev/screens_fb.cpp + backends/wayland/scene_qpainter_wayland_backend.cpp backends/wayland/screens_wayland.cpp backends/x11/screens_x11windowed.cpp virtual_terminal.cpp diff --git a/backends/wayland/scene_qpainter_wayland_backend.cpp b/backends/wayland/scene_qpainter_wayland_backend.cpp new file mode 100644 index 0000000000..3041a6c958 --- /dev/null +++ b/backends/wayland/scene_qpainter_wayland_backend.cpp @@ -0,0 +1,135 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2013, 2015 Martin Gräßlin + +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 +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "scene_qpainter_wayland_backend.h" +#include "composite.h" +#include "wayland_backend.h" +#include +#include +#include +// Qt +#include + +namespace KWin +{ + +WaylandQPainterBackend::WaylandQPainterBackend(Wayland::WaylandBackend *b) + : QPainterBackend() + , m_backend(b) + , m_needsFullRepaint(true) + , m_backBuffer(QImage(QSize(), QImage::Format_RGB32)) + , m_buffer() +{ + connect(b->shmPool(), SIGNAL(poolResized()), SLOT(remapBuffer())); + connect(b, &Wayland::WaylandBackend::shellSurfaceSizeChanged, + this, &WaylandQPainterBackend::screenGeometryChanged); + connect(b->surface(), &KWayland::Client::Surface::frameRendered, + Compositor::self(), &Compositor::bufferSwapComplete); +} + +WaylandQPainterBackend::~WaylandQPainterBackend() +{ + if (m_buffer) { + m_buffer.toStrongRef()->setUsed(false); + } +} + +bool WaylandQPainterBackend::usesOverlayWindow() const +{ + return false; +} + +void WaylandQPainterBackend::present(int mask, const QRegion &damage) +{ + Q_UNUSED(mask) + if (m_backBuffer.isNull()) { + return; + } + Compositor::self()->aboutToSwapBuffers(); + m_needsFullRepaint = false; + auto s = m_backend->surface(); + s->attachBuffer(m_buffer); + s->damage(damage); + s->commit(); +} + +void WaylandQPainterBackend::screenGeometryChanged(const QSize &size) +{ + Q_UNUSED(size) + if (!m_buffer) { + return; + } + m_buffer.toStrongRef()->setUsed(false); + m_buffer.clear(); +} + +QImage *WaylandQPainterBackend::buffer() +{ + return &m_backBuffer; +} + +void WaylandQPainterBackend::prepareRenderingFrame() +{ + if (m_buffer) { + auto b = m_buffer.toStrongRef(); + if (b->isReleased()) { + // we can re-use this buffer + b->setReleased(false); + return; + } else { + // buffer is still in use, get a new one + b->setUsed(false); + } + } + m_buffer.clear(); + const QSize size(m_backend->shellSurfaceSize()); + m_buffer = m_backend->shmPool()->getBuffer(size, size.width() * 4); + if (!m_buffer) { + qCDebug(KWIN_CORE) << "Did not get a new Buffer from Shm Pool"; + m_backBuffer = QImage(); + return; + } + auto b = m_buffer.toStrongRef(); + b->setUsed(true); + m_backBuffer = QImage(b->address(), size.width(), size.height(), QImage::Format_RGB32); + m_backBuffer.fill(Qt::transparent); + m_needsFullRepaint = true; + qCDebug(KWIN_CORE) << "Created a new back buffer"; +} + +void WaylandQPainterBackend::remapBuffer() +{ + if (!m_buffer) { + return; + } + auto b = m_buffer.toStrongRef(); + if (!b->isUsed()){ + return; + } + const QSize size = m_backBuffer.size(); + m_backBuffer = QImage(b->address(), size.width(), size.height(), QImage::Format_RGB32); + qCDebug(KWIN_CORE) << "Remapped our back buffer"; +} + +bool WaylandQPainterBackend::needsFullRepaint() const +{ + return m_needsFullRepaint; +} + +} diff --git a/backends/wayland/scene_qpainter_wayland_backend.h b/backends/wayland/scene_qpainter_wayland_backend.h new file mode 100644 index 0000000000..ed444e7052 --- /dev/null +++ b/backends/wayland/scene_qpainter_wayland_backend.h @@ -0,0 +1,66 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2013, 2015 Martin Gräßlin + +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 +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef KWIN_SCENE_QPAINTER_WAYLAND_BACKEND_H +#define KWIN_SCENE_QPAINTER_WAYLAND_BACKEND_H + +#include "scene_qpainter.h" + +#include + +namespace KWayland +{ +namespace Client +{ +class Buffer; +} +} + +namespace KWin +{ +namespace Wayland +{ +class WaylandBackend; +} + +class WaylandQPainterBackend : public QObject, public QPainterBackend +{ + Q_OBJECT +public: + explicit WaylandQPainterBackend(Wayland::WaylandBackend *b); + virtual ~WaylandQPainterBackend(); + + virtual void present(int mask, const QRegion& damage) override; + virtual bool usesOverlayWindow() const override; + virtual void screenGeometryChanged(const QSize &size) override; + virtual QImage *buffer() override; + virtual void prepareRenderingFrame() override; + virtual bool needsFullRepaint() const override; +private Q_SLOTS: + void remapBuffer(); +private: + Wayland::WaylandBackend *m_backend; + bool m_needsFullRepaint; + QImage m_backBuffer; + QWeakPointer m_buffer; +}; + +} + +#endif diff --git a/backends/wayland/wayland_backend.cpp b/backends/wayland/wayland_backend.cpp index 93311d545b..9e83f0eda2 100644 --- a/backends/wayland/wayland_backend.cpp +++ b/backends/wayland/wayland_backend.cpp @@ -22,7 +22,7 @@ along with this program. If not, see . // KWin #include "cursor.h" #include "main.h" -#include "scene_qpainter.h" +#include "scene_qpainter_wayland_backend.h" #include "screens_wayland.h" #include "utils.h" #include "wayland_server.h" diff --git a/scene_qpainter.cpp b/scene_qpainter.cpp index f9e01e08e0..6be9330807 100644 --- a/scene_qpainter.cpp +++ b/scene_qpainter.cpp @@ -28,12 +28,8 @@ along with this program. If not, see . #include "screens.h" #include "toplevel.h" #if HAVE_WAYLAND -#include "backends/wayland/wayland_backend.h" #include "wayland_server.h" #include "backends/x11/x11windowed_backend.h" -#include -#include -#include #include #include #endif @@ -96,112 +92,6 @@ QImage *QPainterBackend::bufferForScreen(int screenId) } #if HAVE_WAYLAND -//**************************************** -// WaylandQPainterBackend -//**************************************** - -WaylandQPainterBackend::WaylandQPainterBackend(Wayland::WaylandBackend *b) - : QPainterBackend() - , m_backend(b) - , m_needsFullRepaint(true) - , m_backBuffer(QImage(QSize(), QImage::Format_RGB32)) - , m_buffer() -{ - connect(b->shmPool(), SIGNAL(poolResized()), SLOT(remapBuffer())); - connect(b, &Wayland::WaylandBackend::shellSurfaceSizeChanged, - this, &WaylandQPainterBackend::screenGeometryChanged); - connect(b->surface(), &KWayland::Client::Surface::frameRendered, - Compositor::self(), &Compositor::bufferSwapComplete); -} - -WaylandQPainterBackend::~WaylandQPainterBackend() -{ - if (m_buffer) { - m_buffer.toStrongRef()->setUsed(false); - } -} - -bool WaylandQPainterBackend::usesOverlayWindow() const -{ - return false; -} - -void WaylandQPainterBackend::present(int mask, const QRegion &damage) -{ - Q_UNUSED(mask) - if (m_backBuffer.isNull()) { - return; - } - Compositor::self()->aboutToSwapBuffers(); - m_needsFullRepaint = false; - auto s = m_backend->surface(); - s->attachBuffer(m_buffer); - s->damage(damage); - s->commit(); -} - -void WaylandQPainterBackend::screenGeometryChanged(const QSize &size) -{ - Q_UNUSED(size) - if (!m_buffer) { - return; - } - m_buffer.toStrongRef()->setUsed(false); - m_buffer.clear(); -} - -QImage *WaylandQPainterBackend::buffer() -{ - return &m_backBuffer; -} - -void WaylandQPainterBackend::prepareRenderingFrame() -{ - if (m_buffer) { - auto b = m_buffer.toStrongRef(); - if (b->isReleased()) { - // we can re-use this buffer - b->setReleased(false); - return; - } else { - // buffer is still in use, get a new one - b->setUsed(false); - } - } - m_buffer.clear(); - const QSize size(m_backend->shellSurfaceSize()); - m_buffer = m_backend->shmPool()->getBuffer(size, size.width() * 4); - if (!m_buffer) { - qCDebug(KWIN_CORE) << "Did not get a new Buffer from Shm Pool"; - m_backBuffer = QImage(); - return; - } - auto b = m_buffer.toStrongRef(); - b->setUsed(true); - m_backBuffer = QImage(b->address(), size.width(), size.height(), QImage::Format_RGB32); - m_backBuffer.fill(Qt::transparent); - m_needsFullRepaint = true; - qCDebug(KWIN_CORE) << "Created a new back buffer"; -} - -void WaylandQPainterBackend::remapBuffer() -{ - if (!m_buffer) { - return; - } - auto b = m_buffer.toStrongRef(); - if (!b->isUsed()){ - return; - } - const QSize size = m_backBuffer.size(); - m_backBuffer = QImage(b->address(), size.width(), size.height(), QImage::Format_RGB32); - qCDebug(KWIN_CORE) << "Remapped our back buffer"; -} - -bool WaylandQPainterBackend::needsFullRepaint() const -{ - return m_needsFullRepaint; -} //**************************************** // X11WindowedBackend diff --git a/scene_qpainter.h b/scene_qpainter.h index 2908907842..ff5988ebea 100644 --- a/scene_qpainter.h +++ b/scene_qpainter.h @@ -24,15 +24,6 @@ along with this program. If not, see . #include "shadow.h" #include "decorations/decorationrenderer.h" -#if HAVE_WAYLAND -namespace KWayland -{ -namespace Client -{ -class Buffer; -} -} -#endif namespace KWin { @@ -40,10 +31,6 @@ namespace Xcb { class Shm; } -namespace Wayland -{ -class WaylandBackend; -} class X11WindowedBackend; class QPainterBackend @@ -123,28 +110,6 @@ private: }; #if HAVE_WAYLAND -class WaylandQPainterBackend : public QObject, public QPainterBackend -{ - Q_OBJECT -public: - explicit WaylandQPainterBackend(Wayland::WaylandBackend *b); - virtual ~WaylandQPainterBackend(); - - virtual void present(int mask, const QRegion& damage) override; - virtual bool usesOverlayWindow() const override; - virtual void screenGeometryChanged(const QSize &size) override; - virtual QImage *buffer() override; - virtual void prepareRenderingFrame() override; - virtual bool needsFullRepaint() const override; -private Q_SLOTS: - void remapBuffer(); -private: - Wayland::WaylandBackend *m_backend; - bool m_needsFullRepaint; - QImage m_backBuffer; - QWeakPointer m_buffer; -}; - class X11WindowedQPainterBackend : public QObject, public QPainterBackend { Q_OBJECT