diff --git a/backends/x11/CMakeLists.txt b/backends/x11/CMakeLists.txt index 1c7f72f544..c0824b09b5 100644 --- a/backends/x11/CMakeLists.txt +++ b/backends/x11/CMakeLists.txt @@ -1,5 +1,6 @@ set(X11BACKEND_SOURCES logging.cpp + egl_x11_backend.cpp scene_qpainter_x11_backend.cpp x11windowed_backend.cpp ) diff --git a/backends/x11/egl_x11_backend.cpp b/backends/x11/egl_x11_backend.cpp new file mode 100644 index 0000000000..a19fa9a62f --- /dev/null +++ b/backends/x11/egl_x11_backend.cpp @@ -0,0 +1,118 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 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 "egl_x11_backend.h" +// kwin +#include "screens.h" +#include "x11windowed_backend.h" +// kwin libs +#include + +namespace KWin +{ + +EglX11Backend::EglX11Backend(X11WindowedBackend *backend) + : EglOnXBackend(backend->connection(), backend->display(), backend->rootWindow(), backend->screenNumer(), XCB_WINDOW_NONE) + , m_backend(backend) +{ +} + +EglX11Backend::~EglX11Backend() = default; + +void EglX11Backend::cleanupSurfaces() +{ + for (auto it = m_surfaces.begin(); it != m_surfaces.end(); ++it) { + eglDestroySurface(eglDisplay(), *it); + } +} + +bool EglX11Backend::createSurfaces() +{ + for (int i = 0; i < screens()->count(); ++i) { + EGLSurface s = createSurface(m_backend->windowForScreen(i)); + if (s == EGL_NO_SURFACE) { + return false; + } + m_surfaces << s; + } + if (m_surfaces.isEmpty()) { + return false; + } + setSurface(m_surfaces.first()); + return true; +} + +void EglX11Backend::present() +{ + for (int i = 0; i < screens()->count(); ++i) { + EGLSurface s = m_surfaces.at(i); + makeContextCurrent(s); + setupViewport(i); + presentSurface(s, screens()->geometry(i), screens()->geometry(i)); + } + eglWaitGL(); + xcb_flush(m_backend->connection()); +} + +QRegion EglX11Backend::prepareRenderingFrame() +{ + startRenderTimer(); + return QRegion(); +} + +void EglX11Backend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) +{ + Q_UNUSED(renderedRegion) + Q_UNUSED(damagedRegion) +} + +bool EglX11Backend::usesOverlayWindow() const +{ + return false; +} + +bool EglX11Backend::perScreenRendering() const +{ + return true; +} + +QRegion EglX11Backend::prepareRenderingForScreen(int screenId) +{ + makeContextCurrent(m_surfaces.at(screenId)); + setupViewport(screenId); + return screens()->geometry(screenId); +} + +void EglX11Backend::setupViewport(int screenId) +{ + // TODO: ensure the viewport is set correctly each time + const QSize &overall = screens()->size(); + const QRect &v = screens()->geometry(screenId); + // TODO: are the values correct? + glViewport(-v.x(), v.height() - overall.height() - v.y(), overall.width(), overall.height()); +} + +void EglX11Backend::endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion) +{ + Q_UNUSED(damagedRegion) + const QRect &outputGeometry = screens()->geometry(screenId); + presentSurface(m_surfaces.at(screenId), renderedRegion, outputGeometry); +} + +} // namespace diff --git a/backends/x11/egl_x11_backend.h b/backends/x11/egl_x11_backend.h new file mode 100644 index 0000000000..5234801070 --- /dev/null +++ b/backends/x11/egl_x11_backend.h @@ -0,0 +1,57 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 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_EGL_X11_BACKEND_H +#define KWIN_EGL_X11_BACKEND_H +#include "eglonxbackend.h" + +namespace KWin +{ + +class X11WindowedBackend; + +/** + * @brief OpenGL Backend using Egl windowing system over an X overlay window. + **/ +class EglX11Backend : public EglOnXBackend +{ +public: + explicit EglX11Backend(X11WindowedBackend *backend); + virtual ~EglX11Backend(); + virtual QRegion prepareRenderingFrame(); + virtual void endRenderingFrame(const QRegion &damage, const QRegion &damagedRegion); + virtual bool usesOverlayWindow() const override; + bool perScreenRendering() const override; + QRegion prepareRenderingForScreen(int screenId) override; + void endRenderingFrameForScreen(int screenId, const QRegion &damage, const QRegion &damagedRegion) override; + +protected: + virtual void present(); + void cleanupSurfaces() override; + bool createSurfaces() override; + +private: + void setupViewport(int screenId); + QVector m_surfaces; + X11WindowedBackend *m_backend; +}; + +} // namespace + +#endif diff --git a/backends/x11/x11windowed_backend.cpp b/backends/x11/x11windowed_backend.cpp index 28d5b2ad8d..2db4dfec3e 100644 --- a/backends/x11/x11windowed_backend.cpp +++ b/backends/x11/x11windowed_backend.cpp @@ -22,7 +22,7 @@ along with this program. If not, see . #include "logging.h" #include "wayland_server.h" #include "xcbutils.h" -#include "eglonxbackend.h" +#include "egl_x11_backend.h" #include "screens.h" #include // KDE @@ -441,7 +441,7 @@ Screens *X11WindowedBackend::createScreens(QObject *parent) OpenGLBackend *X11WindowedBackend::createOpenGLBackend() { - return new EglOnXBackend(connection(), display(), rootWindow(), screenNumer(), window()); + return new EglX11Backend(this); } QPainterBackend *X11WindowedBackend::createQPainterBackend()