diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -347,6 +347,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/libkwineffects ${CMAKE_CURRENT_SOURCE_DIR}/effects ${CMAKE_CURRENT_SOURCE_DIR}/tabbox + ${CMAKE_CURRENT_SOURCE_DIR}/platformsupport ) add_subdirectory( libkwineffects ) @@ -410,7 +411,6 @@ unmanaged.cpp scene.cpp scene_opengl.cpp - scene_qpainter.cpp screenlockerwatcher.cpp thumbnailitem.cpp lanczosfilter.cpp @@ -625,6 +625,7 @@ install(TARGETS kwin_wayland ${INSTALL_TARGETS_DEFAULT_ARGS} ) +add_subdirectory(platformsupport) add_subdirectory(plugins) ########### install files ############### diff --git a/composite.cpp b/composite.cpp --- a/composite.cpp +++ b/composite.cpp @@ -31,7 +31,6 @@ #include "overlaywindow.h" #include "scene.h" #include "scene_opengl.h" -#include "scene_qpainter.h" #include "screens.h" #include "shadow.h" #include "useractions.h" @@ -249,10 +248,6 @@ // Do not Fall back to XRender - it causes problems when selfcheck fails during startup, but works later on break; } - case QPainterCompositing: - qCDebug(KWIN_CORE) << "Initializing QPainter compositing"; - m_scene = SceneQPainter::createScene(this); - break; default: qCDebug(KWIN_CORE) << "No compositing enabled"; m_starting = false; diff --git a/data/org_kde_kwin.categories b/data/org_kde_kwin.categories --- a/data/org_kde_kwin.categories +++ b/data/org_kde_kwin.categories @@ -17,3 +17,4 @@ kwin_xkbcommon KWin xkbcommon integration kwin_qpa_plugin KWin QtPlatformAbstraction plugin kwin_scene_xrender KWin XRender based compositor scene plugin +kwin_scene_qpainter KWin QPainter based compositor scene plugin diff --git a/platformsupport/CMakeLists.txt b/platformsupport/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/platformsupport/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(scenes) diff --git a/platformsupport/scenes/CMakeLists.txt b/platformsupport/scenes/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/platformsupport/scenes/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(qpainter) diff --git a/platformsupport/scenes/qpainter/CMakeLists.txt b/platformsupport/scenes/qpainter/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/platformsupport/scenes/qpainter/CMakeLists.txt @@ -0,0 +1,16 @@ +set(SCENE_QPAINTER_BACKEND_SRCS backend.cpp) + +include(ECMQtDeclareLoggingCategory) +ecm_qt_declare_logging_category(SCENE_QPAINTER_BACKEND_SRCS + HEADER + logging.h + IDENTIFIER + KWIN_QPAINTER + CATEGORY_NAME + kwin_scene_qpainter + DEFAULT_SEVERITY + Critical +) + +add_library(SceneQPainterBackend STATIC ${SCENE_QPAINTER_BACKEND_SRCS}) +target_link_libraries(SceneQPainterBackend Qt5::Core) diff --git a/platformsupport/scenes/qpainter/backend.h b/platformsupport/scenes/qpainter/backend.h new file mode 100644 --- /dev/null +++ b/platformsupport/scenes/qpainter/backend.h @@ -0,0 +1,108 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2013 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_BACKEND_H +#define KWIN_SCENE_QPAINTER_BACKEND_H + +class QImage; +class QRegion; +class QSize; +class QString; + +namespace KWin { +class OverlayWindow; + +class QPainterBackend +{ +public: + virtual ~QPainterBackend(); + virtual void present(int mask, const QRegion &damage) = 0; + + /** + * @brief Returns the OverlayWindow used by the backend. + * + * A backend does not have to use an OverlayWindow, this is mostly for the X world. + * In case the backend does not use an OverlayWindow it is allowed to return @c null. + * It's the task of the caller to check whether it is @c null. + * + * @return :OverlayWindow* + **/ + virtual OverlayWindow *overlayWindow(); + virtual bool usesOverlayWindow() const = 0; + virtual void prepareRenderingFrame() = 0; + /** + * @brief Shows the Overlay Window + * + * Default implementation does nothing. + */ + virtual void showOverlay(); + /** + * @brief React on screen geometry changes. + * + * Default implementation does nothing. Override if specific functionality is required. + * + * @param size The new screen size + */ + virtual void screenGeometryChanged(const QSize &size); + /** + * @brief Whether the creation of the Backend failed. + * + * The SceneQPainter should test whether the Backend got constructed correctly. If this method + * returns @c true, the SceneQPainter should not try to start the rendering. + * + * @return bool @c true if the creation of the Backend failed, @c false otherwise. + **/ + bool isFailed() const { + return m_failed; + } + + virtual QImage *buffer() = 0; + /** + * Overload for the case that there is a different buffer per screen. + * Default implementation just calls buffer. + * @param screenId The id of the screen as used in Screens + * @todo Get a better identifier for screen then a counter variable + **/ + virtual QImage *bufferForScreen(int screenId); + virtual bool needsFullRepaint() const = 0; + /** + * Whether the rendering needs to be split per screen. + * Default implementation returns @c false. + **/ + virtual bool perScreenRendering() const; + +protected: + QPainterBackend(); + /** + * @brief Sets the backend initialization to failed. + * + * This method should be called by the concrete subclass in case the initialization failed. + * The given @p reason is logged as a warning. + * + * @param reason The reason why the initialization failed. + **/ + void setFailed(const QString &reason); + +private: + bool m_failed; +}; + +} // KWin + +#endif diff --git a/plugins/platforms/fbdev/scene_qpainter_fb_backend.h b/platformsupport/scenes/qpainter/backend.cpp copy from plugins/platforms/fbdev/scene_qpainter_fb_backend.h copy to platformsupport/scenes/qpainter/backend.cpp --- a/plugins/platforms/fbdev/scene_qpainter_fb_backend.h +++ b/platformsupport/scenes/qpainter/backend.cpp @@ -2,7 +2,7 @@ KWin - the KDE window manager This file is part of the KDE project. -Copyright (C) 2015 Martin Gräßlin +Copyright (C) 2013 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 @@ -17,35 +17,52 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ -#ifndef KWIN_SCENE_QPAINTER_FB_BACKEND_H -#define KWIN_SCENE_QPAINTER_FB_BACKEND_H -#include "scene_qpainter.h" +#include "backend.h" +#include -#include +#include namespace KWin { -class FramebufferBackend; -class FramebufferQPainterBackend : public QObject, public QPainterBackend +QPainterBackend::QPainterBackend() + : m_failed(false) { - Q_OBJECT -public: - FramebufferQPainterBackend(FramebufferBackend *backend); - virtual ~FramebufferQPainterBackend(); +} - QImage *buffer() override; - bool needsFullRepaint() const override; - bool usesOverlayWindow() const override; - void prepareRenderingFrame() override; - void present(int mask, const QRegion &damage) override; +QPainterBackend::~QPainterBackend() +{ +} + +OverlayWindow* QPainterBackend::overlayWindow() +{ + return nullptr; +} -private: - QImage m_renderBuffer; - QImage m_backBuffer; - FramebufferBackend *m_backend; -}; +void QPainterBackend::showOverlay() +{ +} +void QPainterBackend::screenGeometryChanged(const QSize &size) +{ + Q_UNUSED(size) } -#endif +void QPainterBackend::setFailed(const QString &reason) +{ + qCWarning(KWIN_QPAINTER) << "Creating the QPainter backend failed: " << reason; + m_failed = true; +} + +bool QPainterBackend::perScreenRendering() const +{ + return false; +} + +QImage *QPainterBackend::bufferForScreen(int screenId) +{ + Q_UNUSED(screenId) + return buffer(); +} + +} diff --git a/plugins/platforms/drm/CMakeLists.txt b/plugins/platforms/drm/CMakeLists.txt --- a/plugins/platforms/drm/CMakeLists.txt +++ b/plugins/platforms/drm/CMakeLists.txt @@ -17,7 +17,7 @@ endif() add_library(KWinWaylandDrmBackend MODULE ${DRM_SOURCES}) -target_link_libraries(KWinWaylandDrmBackend kwin Libdrm::Libdrm) +target_link_libraries(KWinWaylandDrmBackend kwin Libdrm::Libdrm SceneQPainterBackend) if(HAVE_GBM) target_link_libraries(KWinWaylandDrmBackend gbm::gbm) diff --git a/plugins/platforms/drm/scene_qpainter_drm_backend.h b/plugins/platforms/drm/scene_qpainter_drm_backend.h --- a/plugins/platforms/drm/scene_qpainter_drm_backend.h +++ b/plugins/platforms/drm/scene_qpainter_drm_backend.h @@ -19,8 +19,9 @@ *********************************************************************/ #ifndef KWIN_SCENE_QPAINTER_DRM_BACKEND_H #define KWIN_SCENE_QPAINTER_DRM_BACKEND_H -#include "scene_qpainter.h" +#include #include +#include namespace KWin { diff --git a/plugins/platforms/fbdev/CMakeLists.txt b/plugins/platforms/fbdev/CMakeLists.txt --- a/plugins/platforms/fbdev/CMakeLists.txt +++ b/plugins/platforms/fbdev/CMakeLists.txt @@ -5,7 +5,7 @@ ) add_library(KWinWaylandFbdevBackend MODULE ${FBDEV_SOURCES}) -target_link_libraries(KWinWaylandFbdevBackend kwin) +target_link_libraries(KWinWaylandFbdevBackend kwin SceneQPainterBackend) install( TARGETS diff --git a/plugins/platforms/fbdev/scene_qpainter_fb_backend.h b/plugins/platforms/fbdev/scene_qpainter_fb_backend.h --- a/plugins/platforms/fbdev/scene_qpainter_fb_backend.h +++ b/plugins/platforms/fbdev/scene_qpainter_fb_backend.h @@ -19,9 +19,10 @@ *********************************************************************/ #ifndef KWIN_SCENE_QPAINTER_FB_BACKEND_H #define KWIN_SCENE_QPAINTER_FB_BACKEND_H -#include "scene_qpainter.h" +#include #include +#include namespace KWin { diff --git a/plugins/platforms/virtual/CMakeLists.txt b/plugins/platforms/virtual/CMakeLists.txt --- a/plugins/platforms/virtual/CMakeLists.txt +++ b/plugins/platforms/virtual/CMakeLists.txt @@ -9,7 +9,7 @@ ecm_qt_declare_logging_category(VIRTUAL_SOURCES HEADER logging.h IDENTIFIER KWIN_VIRTUAL CATEGORY_NAME kwin_platform_virtual DEFAULT_SEVERITY Critical) add_library(KWinWaylandVirtualBackend MODULE ${VIRTUAL_SOURCES}) -target_link_libraries(KWinWaylandVirtualBackend kwin) +target_link_libraries(KWinWaylandVirtualBackend kwin SceneQPainterBackend) if(HAVE_GBM) target_link_libraries(KWinWaylandVirtualBackend gbm::gbm) diff --git a/plugins/platforms/virtual/scene_qpainter_virtual_backend.h b/plugins/platforms/virtual/scene_qpainter_virtual_backend.h --- a/plugins/platforms/virtual/scene_qpainter_virtual_backend.h +++ b/plugins/platforms/virtual/scene_qpainter_virtual_backend.h @@ -20,9 +20,10 @@ #ifndef KWIN_SCENE_QPAINTER_VIRTUAL_BACKEND_H #define KWIN_SCENE_QPAINTER_VIRTUAL_BACKEND_H -#include "scene_qpainter.h" +#include #include +#include namespace KWin { diff --git a/plugins/platforms/wayland/CMakeLists.txt b/plugins/platforms/wayland/CMakeLists.txt --- a/plugins/platforms/wayland/CMakeLists.txt +++ b/plugins/platforms/wayland/CMakeLists.txt @@ -9,7 +9,7 @@ endif() add_library(KWinWaylandWaylandBackend MODULE ${WAYLAND_BACKEND_SOURCES}) -target_link_libraries(KWinWaylandWaylandBackend kwin KF5::WaylandClient) +target_link_libraries(KWinWaylandWaylandBackend kwin KF5::WaylandClient SceneQPainterBackend) if(HAVE_WAYLAND_EGL) target_link_libraries(KWinWaylandWaylandBackend Wayland::Egl) diff --git a/plugins/platforms/wayland/scene_qpainter_wayland_backend.h b/plugins/platforms/wayland/scene_qpainter_wayland_backend.h --- a/plugins/platforms/wayland/scene_qpainter_wayland_backend.h +++ b/plugins/platforms/wayland/scene_qpainter_wayland_backend.h @@ -20,9 +20,11 @@ #ifndef KWIN_SCENE_QPAINTER_WAYLAND_BACKEND_H #define KWIN_SCENE_QPAINTER_WAYLAND_BACKEND_H -#include "scene_qpainter.h" +#include #include +#include +#include namespace KWayland { diff --git a/plugins/platforms/x11/windowed/CMakeLists.txt b/plugins/platforms/x11/windowed/CMakeLists.txt --- a/plugins/platforms/x11/windowed/CMakeLists.txt +++ b/plugins/platforms/x11/windowed/CMakeLists.txt @@ -6,7 +6,7 @@ ) add_library(KWinWaylandX11Backend MODULE ${X11BACKEND_SOURCES}) -target_link_libraries(KWinWaylandX11Backend eglx11common kwin X11::XCB) +target_link_libraries(KWinWaylandX11Backend eglx11common kwin X11::XCB SceneQPainterBackend) install( TARGETS diff --git a/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.h b/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.h --- a/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.h +++ b/plugins/platforms/x11/windowed/scene_qpainter_x11_backend.h @@ -20,9 +20,13 @@ #ifndef KWIN_SCENE_QPAINTER_X11_BACKEND_H #define KWIN_SCENE_QPAINTER_X11_BACKEND_H -#include "scene_qpainter.h" +#include #include +#include +#include + +#include namespace KWin { diff --git a/plugins/scenes/CMakeLists.txt b/plugins/scenes/CMakeLists.txt --- a/plugins/scenes/CMakeLists.txt +++ b/plugins/scenes/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(qpainter) if( KWIN_BUILD_XRENDER_COMPOSITING ) add_subdirectory(xrender) endif() diff --git a/plugins/scenes/qpainter/CMakeLists.txt b/plugins/scenes/qpainter/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/plugins/scenes/qpainter/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SCENE_QPAINTER_SRCS scene_qpainter.cpp) + +add_library(KWinSceneQPainter MODULE scene_qpainter.cpp) +target_link_libraries(KWinSceneQPainter + kwin + SceneQPainterBackend +) + +install( + TARGETS + KWinSceneQPainter + DESTINATION + ${PLUGIN_INSTALL_DIR}/org.kde.kwin.scenes/ +) diff --git a/plugins/scenes/qpainter/qpainter.json b/plugins/scenes/qpainter/qpainter.json new file mode 100644 --- /dev/null +++ b/plugins/scenes/qpainter/qpainter.json @@ -0,0 +1,9 @@ +{ + "KPlugin": { + "Description": "KWin Compositor plugin rendering through QPainter", + "Id": "KWinSceneQPainter", + "Name": "SceneQPainter" + }, + "CompositingType": 4 +} + diff --git a/scene_qpainter.h b/plugins/scenes/qpainter/scene_qpainter.h rename from scene_qpainter.h rename to plugins/scenes/qpainter/scene_qpainter.h --- a/scene_qpainter.h +++ b/plugins/scenes/qpainter/scene_qpainter.h @@ -21,87 +21,13 @@ #define KWIN_SCENE_QPAINTER_H #include "scene.h" +#include #include "shadow.h" #include "decorations/decorationrenderer.h" namespace KWin { -class KWIN_EXPORT QPainterBackend -{ -public: - virtual ~QPainterBackend(); - virtual void present(int mask, const QRegion &damage) = 0; - - /** - * @brief Returns the OverlayWindow used by the backend. - * - * A backend does not have to use an OverlayWindow, this is mostly for the X world. - * In case the backend does not use an OverlayWindow it is allowed to return @c null. - * It's the task of the caller to check whether it is @c null. - * - * @return :OverlayWindow* - **/ - virtual OverlayWindow *overlayWindow(); - virtual bool usesOverlayWindow() const = 0; - virtual void prepareRenderingFrame() = 0; - /** - * @brief Shows the Overlay Window - * - * Default implementation does nothing. - */ - virtual void showOverlay(); - /** - * @brief React on screen geometry changes. - * - * Default implementation does nothing. Override if specific functionality is required. - * - * @param size The new screen size - */ - virtual void screenGeometryChanged(const QSize &size); - /** - * @brief Whether the creation of the Backend failed. - * - * The SceneQPainter should test whether the Backend got constructed correctly. If this method - * returns @c true, the SceneQPainter should not try to start the rendering. - * - * @return bool @c true if the creation of the Backend failed, @c false otherwise. - **/ - bool isFailed() const { - return m_failed; - } - - virtual QImage *buffer() = 0; - /** - * Overload for the case that there is a different buffer per screen. - * Default implementation just calls buffer. - * @param screenId The id of the screen as used in Screens - * @todo Get a better identifier for screen then a counter variable - **/ - virtual QImage *bufferForScreen(int screenId); - virtual bool needsFullRepaint() const = 0; - /** - * Whether the rendering needs to be split per screen. - * Default implementation returns @c false. - **/ - virtual bool perScreenRendering() const; - -protected: - QPainterBackend(); - /** - * @brief Sets the backend initialization to failed. - * - * This method should be called by the concrete subclass in case the initialization failed. - * The given @p reason is logged as a warning. - * - * @param reason The reason why the initialization failed. - **/ - void setFailed(const QString &reason); - -private: - bool m_failed; -}; - class KWIN_EXPORT SceneQPainter : public Scene { Q_OBJECT @@ -240,6 +166,19 @@ QImage m_images[int(DecorationPart::Count)]; }; +class KWIN_EXPORT QPainterFactory : public SceneFactory +{ + Q_OBJECT + Q_INTERFACES(KWin::SceneFactory) + Q_PLUGIN_METADATA(IID "org.kde.kwin.Scene" FILE "qpainter.json") + +public: + explicit QPainterFactory(QObject *parent = nullptr); + ~QPainterFactory() override; + + Scene *create(QObject *parent = nullptr) const override; +}; + inline bool SceneQPainter::usesOverlayWindow() const { diff --git a/scene_qpainter.cpp b/plugins/scenes/qpainter/scene_qpainter.cpp rename from scene_qpainter.cpp rename to plugins/scenes/qpainter/scene_qpainter.cpp --- a/scene_qpainter.cpp +++ b/plugins/scenes/qpainter/scene_qpainter.cpp @@ -41,49 +41,6 @@ namespace KWin { -//**************************************** -// QPainterBackend -//**************************************** -QPainterBackend::QPainterBackend() - : m_failed(false) -{ -} - -QPainterBackend::~QPainterBackend() -{ -} - -OverlayWindow* QPainterBackend::overlayWindow() -{ - return NULL; -} - -void QPainterBackend::showOverlay() -{ -} - -void QPainterBackend::screenGeometryChanged(const QSize &size) -{ - Q_UNUSED(size) -} - -void QPainterBackend::setFailed(const QString &reason) -{ - qCWarning(KWIN_CORE) << "Creating the XRender backend failed: " << reason; - m_failed = true; -} - -bool QPainterBackend::perScreenRendering() const -{ - return false; -} - -QImage *QPainterBackend::bufferForScreen(int screenId) -{ - Q_UNUSED(screenId) - return buffer(); -} - //**************************************** // SceneQPainter //**************************************** @@ -688,4 +645,22 @@ Renderer::reparent(deleted); } + +QPainterFactory::QPainterFactory(QObject *parent) + : SceneFactory(parent) +{ +} + +QPainterFactory::~QPainterFactory() = default; + +Scene *QPainterFactory::create(QObject *parent) const +{ + auto s = SceneQPainter::createScene(parent); + if (s && s->initFailed()) { + delete s; + s = nullptr; + } + return s; +} + } // KWin