Decouple render backend from scene

Currently, the scene owns the renderer, which puts more
responsibilities on the scene other than painting windows and it also
puts some limitations on what we can do, for example, there can be only
one scene, etc.

This change decouples the scene and the renderer so the scene is more
swappable.

Scenes are no longer implemented as plugins because opengl backend
and scene creation needs to be wrapped in opengl safety points. We
could still create the render backend and then go through the list
of scene plugins, but accessing concrete scene implementation is
much much simpler. Besides that, having scenes implemented as plugins
is not worthwhile because there are only two scenes and each contributes
very small amount of binary size. On the other hand, we still need to
take into account how many times kwin accesses the hard drive to load
plugins in order to function as expected.
This commit is contained in:
Vlad Zahorodnii 2021-11-08 12:08:06 +02:00
parent 3485eb6200
commit cff74b568b
13 changed files with 87 additions and 390 deletions

View file

@ -15,10 +15,14 @@
#include "effects.h" #include "effects.h"
#include "ftrace.h" #include "ftrace.h"
#include "internal_client.h" #include "internal_client.h"
#include "openglbackend.h"
#include "overlaywindow.h" #include "overlaywindow.h"
#include "platform.h" #include "platform.h"
#include "qpainterbackend.h"
#include "renderloop.h" #include "renderloop.h"
#include "scene.h" #include "scene.h"
#include "scenes/opengl/scene_opengl.h"
#include "scenes/qpainter/scene_qpainter.h"
#include "screens.h" #include "screens.h"
#include "shadow.h" #include "shadow.h"
#include "surfaceitem_x11.h" #include "surfaceitem_x11.h"
@ -36,7 +40,6 @@
#include <KGlobalAccel> #include <KGlobalAccel>
#include <KLocalizedString> #include <KLocalizedString>
#include <KPluginMetaData>
#include <KNotification> #include <KNotification>
#include <KSelectionOwner> #include <KSelectionOwner>
@ -157,6 +160,61 @@ Compositor::~Compositor()
s_compositor = nullptr; s_compositor = nullptr;
} }
bool Compositor::attemptOpenGLCompositing()
{
// Some broken drivers crash on glXQuery() so to prevent constant KWin crashes:
if (kwinApp()->platform()->openGLCompositingIsBroken()) {
qCWarning(KWIN_CORE) << "KWin has detected that your OpenGL library is unsafe to use";
return false;
}
kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreInit);
qScopeGuard([]() {
kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostInit);
});
QScopedPointer<OpenGLBackend> backend(kwinApp()->platform()->createOpenGLBackend());
if (!backend) {
return false;
}
if (!backend->isFailed()) {
backend->init();
}
if (backend->isFailed()) {
return false;
}
QScopedPointer<Scene> scene(SceneOpenGL::createScene(backend.data(), this));
if (!scene || scene->initFailed()) {
return false;
}
m_backend = backend.take();
m_scene = scene.take();
qCDebug(KWIN_CORE) << "OpenGL compositing has been successfully initialized";
return true;
}
bool Compositor::attemptQPainterCompositing()
{
QScopedPointer<QPainterBackend> backend(kwinApp()->platform()->createQPainterBackend());
if (!backend || backend->isFailed()) {
return false;
}
QScopedPointer<Scene> scene(SceneQPainter::createScene(backend.data(), this));
if (!scene || scene->initFailed()) {
return false;
}
m_backend = backend.take();
m_scene = scene.take();
qCDebug(KWIN_CORE) << "QPainter compositing has been successfully initialized";
return true;
}
bool Compositor::setupStart() bool Compositor::setupStart()
{ {
if (kwinApp()->isTerminating()) { if (kwinApp()->isTerminating()) {
@ -195,51 +253,25 @@ bool Compositor::setupStart()
<< "Configured compositor not supported by Platform. Falling back to defaults"; << "Configured compositor not supported by Platform. Falling back to defaults";
} }
const auto availablePlugins = KPluginMetaData::findPlugins(QStringLiteral("org.kde.kwin.scenes"));
for (const KPluginMetaData &pluginMetaData : availablePlugins) {
qCDebug(KWIN_CORE) << "Available scene plugin:" << pluginMetaData.fileName();
}
for (auto type : qAsConst(supportedCompositors)) { for (auto type : qAsConst(supportedCompositors)) {
bool stop = false;
switch (type) { switch (type) {
case OpenGLCompositing: case OpenGLCompositing:
qCDebug(KWIN_CORE) << "Attempting to load the OpenGL scene"; qCDebug(KWIN_CORE) << "Attempting to load the OpenGL scene";
stop = attemptOpenGLCompositing();
break; break;
case QPainterCompositing: case QPainterCompositing:
qCDebug(KWIN_CORE) << "Attempting to load the QPainter scene"; qCDebug(KWIN_CORE) << "Attempting to load the QPainter scene";
stop = attemptQPainterCompositing();
break; break;
case NoCompositing: case NoCompositing:
qCDebug(KWIN_CORE) << "Starting without compositing..."; qCDebug(KWIN_CORE) << "Starting without compositing...";
stop = true;
break; break;
} }
const auto pluginIt = std::find_if(availablePlugins.begin(), availablePlugins.end(),
[type] (const auto &plugin) { if (stop) {
const auto &metaData = plugin.rawData();
auto it = metaData.find(QStringLiteral("CompositingType"));
if (it != metaData.end()) {
if ((*it).toInt() == int{type}) {
return true;
}
}
return false;
});
if (pluginIt != availablePlugins.end()) {
std::unique_ptr<SceneFactory>
factory{ qobject_cast<SceneFactory*>(pluginIt->instantiate()) };
if (factory) {
m_scene = factory->create(this);
if (m_scene) {
if (!m_scene->initFailed()) {
qCDebug(KWIN_CORE) << "Instantiated compositing plugin:"
<< pluginIt->name();
break; break;
} else {
delete m_scene;
m_scene = nullptr;
}
}
}
} }
} }
@ -470,6 +502,9 @@ void Compositor::stop()
delete m_scene; delete m_scene;
m_scene = nullptr; m_scene = nullptr;
delete m_backend;
m_backend = nullptr;
m_state = State::Off; m_state = State::Off;
Q_EMIT compositingToggled(false); Q_EMIT compositingToggled(false);
} }

View file

@ -135,6 +135,9 @@ private:
void registerRenderLoop(RenderLoop *renderLoop, AbstractOutput *output); void registerRenderLoop(RenderLoop *renderLoop, AbstractOutput *output);
void unregisterRenderLoop(RenderLoop *renderLoop); void unregisterRenderLoop(RenderLoop *renderLoop);
bool attemptOpenGLCompositing();
bool attemptQPainterCompositing();
State m_state; State m_state;
CompositorSelectionOwner *m_selectionOwner; CompositorSelectionOwner *m_selectionOwner;
@ -142,6 +145,7 @@ private:
QList<xcb_atom_t> m_unusedSupportProperties; QList<xcb_atom_t> m_unusedSupportProperties;
QTimer m_unusedSupportPropertyTimer; QTimer m_unusedSupportPropertyTimer;
Scene *m_scene; Scene *m_scene;
QObject *m_backend = nullptr;
QMap<RenderLoop *, AbstractOutput *> m_renderLoops; QMap<RenderLoop *, AbstractOutput *> m_renderLoops;
}; };

View file

@ -762,13 +762,4 @@ Scene::EffectFrame::~EffectFrame()
{ {
} }
SceneFactory::SceneFactory(QObject *parent)
: QObject(parent)
{
}
SceneFactory::~SceneFactory()
{
}
} // namespace } // namespace

View file

@ -263,24 +263,6 @@ private:
int m_paintScreenCount = 0; int m_paintScreenCount = 0;
}; };
/**
* Factory class to create a Scene. Needs to be implemented by the plugins.
*/
class KWIN_EXPORT SceneFactory : public QObject
{
Q_OBJECT
public:
~SceneFactory() override;
/**
* @returns The created Scene, may be @c nullptr.
*/
virtual Scene *create(QObject *parent = nullptr) const = 0;
protected:
explicit SceneFactory(QObject *parent);
};
// The base class for windows representations in composite backends // The base class for windows representations in composite backends
class Scene::Window : public QObject class Scene::Window : public QObject
{ {
@ -422,6 +404,4 @@ Toplevel* Scene::Window::window() const
} // namespace } // namespace
Q_DECLARE_INTERFACE(KWin::SceneFactory, "org.kde.kwin.Scene")
#endif #endif

View file

@ -1,29 +1,5 @@
set(SCENE_OPENGL_SRCS target_sources(kwin PRIVATE
lanczosfilter.cpp lanczosfilter.cpp
lanczosresources.qrc
scene_opengl.cpp scene_opengl.cpp
) )
include(ECMQtDeclareLoggingCategory)
ecm_qt_declare_logging_category(
SCENE_OPENGL_SRCS HEADER
logging.h
IDENTIFIER
KWIN_OPENGL
CATEGORY_NAME
kwin_scene_opengl
DEFAULT_SEVERITY
Critical
)
qt5_add_resources(SCENE_OPENGL_SRCS resources.qrc)
add_library(KWinSceneOpenGL MODULE ${SCENE_OPENGL_SRCS})
set_target_properties(KWinSceneOpenGL PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.scenes/")
target_link_libraries(KWinSceneOpenGL kwin)
install(
TARGETS
KWinSceneOpenGL
DESTINATION
${KDE_INSTALL_PLUGINDIR}/org.kde.kwin.scenes/
)

View file

@ -1,87 +0,0 @@
{
"CompositingType": 1,
"KPlugin": {
"Description": "KWin Compositor plugin rendering through OpenGL",
"Description[ar]": "ملحقة لمؤلف كوين للتصيير عن طريق OpenGL",
"Description[az]": "OpenGL vasitəsi ilə qoşulmuş KWin birləşdirici modulunu formalaşdırmaq",
"Description[ca@valencia]": "Connector del Compositor de KWin que renderitza a través d'OpenGL",
"Description[ca]": "Connector del Compositor del KWin que renderitza a través de l'OpenGL",
"Description[da]": "KWin-compositorplugin som renderer via OpenGL",
"Description[de]": "KWin-Compositor-Modul zum Rendern mit OpenGL",
"Description[en_GB]": "KWin Compositor plugin rendering through OpenGL",
"Description[es]": "Complemento compositor de KWin renderizando mediante OpenGL",
"Description[et]": "KWini komposiitori plugin renderdamiseks OpenGL abil",
"Description[eu]": "Kwin konposatzailearen plugina OpenGL bidez errendatzen",
"Description[fi]": "OpenGL:llä hahmontava KWin-koostajaliitännäinen",
"Description[fr]": "Module du compositeur KWin effectuant le rendu avec OpenGL",
"Description[gl]": "Complemento de compositor de KWin que renderiza a través de OpenGL.",
"Description[hu]": "KWin összeállító bővítmény OpenGL leképezéssel",
"Description[ia]": "Plugin de Compositor KWin rendente transverso OpenGL",
"Description[id]": "Plugin KWin Compositor perenderan melalui OpenGL",
"Description[it]": "Estensione del compositore di KWin per la resa tramite OpenGL",
"Description[ko]": "OpenGL로 렌더링하는 KWin 컴포지터 플러그인",
"Description[lt]": "KWin kompozitoriaus priedas atvaizdavimui per OpenGL",
"Description[nl]": "KWin-compositor-plug-in rendering via OpenGL",
"Description[nn]": "KWin-samansetjartillegg som brukar OpenGL",
"Description[pl]": "Wtyczka kompozytora KWin wyświetlająca przez OpenGL",
"Description[pt]": "'Plugin' de Composição do KWin com desenho via OpenGL",
"Description[pt_BR]": "Plugin do compositor KWin renderizando pelo OpenGL",
"Description[ru]": "Отрисовка подключаемым модулем компоновщика KWin через OpenGL",
"Description[sk]": "Renderovací plugin kompozítora KWin cez OpenGL",
"Description[sl]": "Izrisovanje vstavka upravljalnika skladnje KWin preko OpenGL-ja",
"Description[sr@ijekavian]": "К‑винов прикључак слагача за рендеровање кроз опенГЛ",
"Description[sr@ijekavianlatin]": "KWinov priključak slagača za renderovanje kroz OpenGL",
"Description[sr@latin]": "KWinov priključak slagača za renderovanje kroz OpenGL",
"Description[sr]": "К‑винов прикључак слагача за рендеровање кроз опенГЛ",
"Description[sv]": "Kwin sammansättningsinsticksprogram återger via OpenGL",
"Description[tr]": "OpenGL üzerinden gerçekleme yapan KWin Dizgici eklentisi",
"Description[uk]": "Додаток засобу композиції KWin для обробки з використанням OpenGL",
"Description[vi]": "Phần cài cắm trình kết hợp KWin kết xuất thông qua OpenGL",
"Description[x-test]": "xxKWin Compositor plugin rendering through OpenGLxx",
"Description[zh_CN]": "使用 OpenGL 渲染的 KWin 显示特效混合器插件",
"Description[zh_TW]": "透過 OpenGL 繪製 KWin 合成器附加元件",
"Id": "KWinSceneOpenGL",
"Name": "SceneOpenGL",
"Name[ar]": "SceneOpenGL",
"Name[az]": "SceneOpenGL",
"Name[ca@valencia]": "SceneOpenGL",
"Name[ca]": "SceneOpenGL",
"Name[cs]": "SceneOpenGL",
"Name[da]": "SceneOpenGL",
"Name[de]": "SceneOpenGL",
"Name[en_GB]": "SceneOpenGL",
"Name[es]": "SceneOpenGL",
"Name[et]": "SceneOpenGL",
"Name[eu]": "SceneOpenGL",
"Name[fi]": "SceneOpenGL",
"Name[fr]": "SceneOpenGL",
"Name[gl]": "SceneOpenGL",
"Name[hu]": "SceneOpenGL",
"Name[ia]": "SceneOpenGL",
"Name[id]": "SceneOpenGL",
"Name[it]": "SceneOpenGL",
"Name[ko]": "SceneOpenGL",
"Name[lt]": "SceneOpenGL",
"Name[nl]": "SceneOpenGL",
"Name[nn]": "SceneOpenGL",
"Name[pa]": "ਸੀਨ-ਓਪਨ-ਜੀਐਲ",
"Name[pl]": "OpenGL sceny",
"Name[pt]": "SceneOpenGL",
"Name[pt_BR]": "SceneOpenGL",
"Name[ro]": "SceneOpenGL",
"Name[ru]": "SceneOpenGL",
"Name[sk]": "SceneOpenGL",
"Name[sl]": "SceneOpenGL",
"Name[sr@ijekavian]": "ОпенГЛ-сцена",
"Name[sr@ijekavianlatin]": "OpenGL-scena",
"Name[sr@latin]": "OpenGL-scena",
"Name[sr]": "ОпенГЛ-сцена",
"Name[sv]": "Scen OpenGL",
"Name[tr]": "SceneOpenGL",
"Name[uk]": "SceneOpenGL",
"Name[vi]": "SceneOpenGL",
"Name[x-test]": "xxSceneOpenGLxx",
"Name[zh_CN]": "SceneOpenGL",
"Name[zh_TW]": "SceneOpenGL"
}
}

View file

@ -117,9 +117,6 @@ SceneOpenGL::~SceneOpenGL()
m_lanczosFilter = nullptr; m_lanczosFilter = nullptr;
} }
SceneOpenGL::EffectFrame::cleanup(); SceneOpenGL::EffectFrame::cleanup();
// backend might be still needed for a different scene
delete m_backend;
} }
@ -198,38 +195,13 @@ void SceneOpenGL::initDebugOutput()
GL_DEBUG_SEVERITY_LOW, message.length(), message.constData()); GL_DEBUG_SEVERITY_LOW, message.length(), message.constData());
} }
SceneOpenGL *SceneOpenGL::createScene(QObject *parent) SceneOpenGL *SceneOpenGL::createScene(OpenGLBackend *backend, QObject *parent)
{ {
QScopedPointer<OpenGLBackend> backend(kwinApp()->platform()->createOpenGLBackend()); if (SceneOpenGL::supported(backend)) {
if (!backend) { return new SceneOpenGL(backend, parent);
return nullptr;
}
if (!backend->isFailed()) {
backend->init();
}
if (backend->isFailed()) {
return nullptr;
}
SceneOpenGL *scene = nullptr;
// first let's try an OpenGL 2 scene
if (SceneOpenGL::supported(backend.data())) {
scene = new SceneOpenGL(backend.take(), parent);
if (scene->initFailed()) {
delete scene;
scene = nullptr;
} else {
return scene;
}
}
if (!scene) {
if (GLPlatform::instance()->recommendedCompositor() == QPainterCompositing) {
qCCritical(KWIN_OPENGL) << "OpenGL driver recommends QPainter based compositing. Falling back to QPainter.";
qCCritical(KWIN_OPENGL) << "To overwrite the detection use the environment variable KWIN_COMPOSE";
qCCritical(KWIN_OPENGL) << "For more information see https://community.kde.org/KWin/Environment_Variables#KWIN_COMPOSE";
}
} }
return scene; return nullptr;
} }
OverlayWindow *SceneOpenGL::overlayWindow() const OverlayWindow *SceneOpenGL::overlayWindow() const
@ -1915,30 +1887,4 @@ void SceneOpenGLDecorationRenderer::resizeTexture()
} }
} }
OpenGLFactory::OpenGLFactory(QObject *parent)
: SceneFactory(parent)
{
}
OpenGLFactory::~OpenGLFactory() = default;
Scene *OpenGLFactory::create(QObject *parent) const
{
qCDebug(KWIN_OPENGL) << "Initializing OpenGL compositing";
// Some broken drivers crash on glXQuery() so to prevent constant KWin crashes:
if (kwinApp()->platform()->openGLCompositingIsBroken()) {
qCWarning(KWIN_OPENGL) << "KWin has detected that your OpenGL library is unsafe to use";
return nullptr;
}
kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreInit);
auto s = SceneOpenGL::createScene(parent);
kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostInit);
if (s && s->initFailed()) {
delete s;
return nullptr;
}
return s;
}
} // namespace } // namespace

View file

@ -61,7 +61,7 @@ public:
QMatrix4x4 projectionMatrix() const { return m_projectionMatrix; } QMatrix4x4 projectionMatrix() const { return m_projectionMatrix; }
QMatrix4x4 screenProjectionMatrix() const override { return m_screenProjectionMatrix; } QMatrix4x4 screenProjectionMatrix() const override { return m_screenProjectionMatrix; }
static SceneOpenGL *createScene(QObject *parent); static SceneOpenGL *createScene(OpenGLBackend *backend, QObject *parent);
static bool supported(OpenGLBackend *backend); static bool supported(OpenGLBackend *backend);
protected: protected:
@ -226,19 +226,6 @@ private:
QScopedPointer<GLTexture> m_texture; QScopedPointer<GLTexture> m_texture;
}; };
class KWIN_EXPORT OpenGLFactory : public SceneFactory
{
Q_OBJECT
Q_INTERFACES(KWin::SceneFactory)
Q_PLUGIN_METADATA(IID "org.kde.kwin.Scene" FILE "opengl.json")
public:
explicit OpenGLFactory(QObject *parent = nullptr);
~OpenGLFactory() override;
Scene *create(QObject *parent = nullptr) const override;
};
} // namespace } // namespace
#endif #endif

View file

@ -1,12 +1,3 @@
set(SCENE_QPAINTER_SRCS scene_qpainter.cpp) target_sources(kwin PRIVATE
scene_qpainter.cpp
add_library(KWinSceneQPainter MODULE scene_qpainter.cpp)
set_target_properties(KWinSceneQPainter PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.scenes/")
target_link_libraries(KWinSceneQPainter kwin)
install(
TARGETS
KWinSceneQPainter
DESTINATION
${KDE_INSTALL_PLUGINDIR}/org.kde.kwin.scenes/
) )

View file

@ -1,89 +0,0 @@
{
"CompositingType": 4,
"KPlugin": {
"Description": "KWin Compositor plugin rendering through QPainter",
"Description[ar]": "ملحقة لمؤلف كوين للتصيير عن طريق QPainter",
"Description[az]": "QPainter vasitəsi ilə KWin birləşdirici əlavəsini formalaşdırmaq",
"Description[ca@valencia]": "Connector del Compositor de KWin que renderitza a través de QPainter",
"Description[ca]": "Connector del Compositor del KWin que renderitza a través del QPainter",
"Description[da]": "KWin-compositorplugin som renderer igennem QPainter",
"Description[de]": "KWin-Compositor-Modul zum Rendern mit QPainter",
"Description[el]": "Αποτύπωση πρσοθέτου συνθέτη KWin μέσω QPainter",
"Description[en_GB]": "KWin Compositor plugin rendering through QPainter",
"Description[es]": "Complemento compositor de KWin renderizando mediante QPainter",
"Description[et]": "KWini komposiitori plugin renderdamiseks QPainteri abil",
"Description[eu]": "Kwin konposatzailearen plugina QPainter bidez errendatzen",
"Description[fi]": "QPainterillä hahmontava KWin-koostajaliitännäinen",
"Description[fr]": "Module du compositeur KWin effectuant le rendu avec QPainter",
"Description[gl]": "Complemento de compositor de KWin que renderiza a través de QPainter.",
"Description[hu]": "KWin összeállító bővítmény QPainter leképezéssel",
"Description[ia]": "Plugin de Compositor KWin rendente transverso QPainter",
"Description[id]": "Plugin KWin Compositor perenderan melalui QPainter",
"Description[it]": "Estensione del compositore di KWin per la resa tramite QPainter",
"Description[ko]": "QPainter로 렌더링하는 KWin 컴포지터 플러그인",
"Description[lt]": "KWin kompozitoriaus priedas atvaizdavimui per QPainter",
"Description[nl]": "KWin-compositor-plug-in rendering via QPainter",
"Description[nn]": "KWin-samansetjartillegg som brukar QPainter",
"Description[pl]": "Wtyczka kompozytora KWin wyświetlająca przez QPainter",
"Description[pt]": "'Plugin' de Composição do KWin com desenho via QPainter",
"Description[pt_BR]": "Plugin do compositor KWin renderizando pelo QPainter",
"Description[ru]": "Отрисовка подключаемым модулем компоновщика KWin через QPainter",
"Description[sk]": "Renderovací plugin kompozítora KWin cez QPainter",
"Description[sl]": "Izrisovanje vstavka upravljalnika skladnje KWin preko QPainter-ja",
"Description[sr@ijekavian]": "К‑винов прикључак слагача за рендеровање кроз QPainter",
"Description[sr@ijekavianlatin]": "KWinov priključak slagača za renderovanje kroz QPainter",
"Description[sr@latin]": "KWinov priključak slagača za renderovanje kroz QPainter",
"Description[sr]": "К‑винов прикључак слагача за рендеровање кроз QPainter",
"Description[sv]": "Kwin sammansättningsinsticksprogram återger via QPainter",
"Description[tr]": "QPainter üzerinden KWin Dizgici eklentisi oluşturma",
"Description[uk]": "Додаток засобу композиції KWin для обробки з використанням QPainter",
"Description[vi]": "Phần cài cắm trình kết hợp KWin kết xuất thông qua QPainter",
"Description[x-test]": "xxKWin Compositor plugin rendering through QPainterxx",
"Description[zh_CN]": "使用 QPainter 渲染的 KWin 显示特效混合器插件",
"Description[zh_TW]": "透過 QPainter 繪製 KWin 合成器附加元件",
"Id": "KWinSceneQPainter",
"Name": "SceneQPainter",
"Name[ar]": "SceneQPainter",
"Name[az]": "SceneQPainter",
"Name[ca@valencia]": "SceneQPainter",
"Name[ca]": "SceneQPainter",
"Name[cs]": "SceneQPainter",
"Name[da]": "SceneQPainter",
"Name[de]": "SceneQPainter",
"Name[el]": "SceneQPainter",
"Name[en_GB]": "SceneQPainter",
"Name[es]": "SceneQPainter",
"Name[et]": "SceneQPainter",
"Name[eu]": "SceneQPainter",
"Name[fi]": "SceneQPainter",
"Name[fr]": "SceneQPainter",
"Name[gl]": "SceneQPainter",
"Name[hu]": "SceneQPainter",
"Name[ia]": "SceneQPainter",
"Name[id]": "SceneQPainter",
"Name[it]": "SceneQPainter",
"Name[ko]": "SceneQPainter",
"Name[lt]": "SceneQPainter",
"Name[nl]": "SceneQPainter",
"Name[nn]": "SceneQPainter",
"Name[pa]": "ਸੀਨ-ਕਿਊ-ਪੇਂਟਰ",
"Name[pl]": "QPainter sceny",
"Name[pt]": "SceneQPainter",
"Name[pt_BR]": "SceneQPainter",
"Name[ro]": "SceneQPainter",
"Name[ru]": "SceneQPainter",
"Name[sk]": "SceneQPainter",
"Name[sl]": "SceneQPainter",
"Name[sr@ijekavian]": "QPainter-сцена",
"Name[sr@ijekavianlatin]": "QPainter-scena",
"Name[sr@latin]": "QPainter-scena",
"Name[sr]": "QPainter-сцена",
"Name[sv]": "Scen QPainter",
"Name[tr]": "SceneQPainter",
"Name[uk]": "SceneQPainter",
"Name[vi]": "SceneQPainter",
"Name[x-test]": "xxSceneQPainterxx",
"Name[zh_CN]": "SceneQPainter",
"Name[zh_TW]": "SceneQPainter"
}
}

View file

@ -38,16 +38,9 @@ namespace KWin
//**************************************** //****************************************
// SceneQPainter // SceneQPainter
//**************************************** //****************************************
SceneQPainter *SceneQPainter::createScene(QObject *parent) SceneQPainter *SceneQPainter::createScene(QPainterBackend *backend, QObject *parent)
{ {
QScopedPointer<QPainterBackend> backend(kwinApp()->platform()->createQPainterBackend()); return new SceneQPainter(backend, parent);
if (backend.isNull()) {
return nullptr;
}
if (backend->isFailed()) {
return nullptr;
}
return new SceneQPainter(backend.take(), parent);
} }
SceneQPainter::SceneQPainter(QPainterBackend *backend, QObject *parent) SceneQPainter::SceneQPainter(QPainterBackend *backend, QObject *parent)
@ -493,21 +486,4 @@ void SceneQPainterDecorationRenderer::resizeImages()
checkAndCreate(int(DecorationPart::Bottom), bottom.size()); checkAndCreate(int(DecorationPart::Bottom), bottom.size());
} }
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 } // KWin

View file

@ -43,10 +43,10 @@ public:
QImage *qpainterRenderBuffer(AbstractOutput *output) const override; QImage *qpainterRenderBuffer(AbstractOutput *output) const override;
QPainterBackend *backend() const { QPainterBackend *backend() const {
return m_backend.data(); return m_backend;
} }
static SceneQPainter *createScene(QObject *parent); static SceneQPainter *createScene(QPainterBackend *backend, QObject *parent);
protected: protected:
void paintBackground(const QRegion &region) override; void paintBackground(const QRegion &region) override;
@ -56,7 +56,7 @@ protected:
private: private:
explicit SceneQPainter(QPainterBackend *backend, QObject *parent = nullptr); explicit SceneQPainter(QPainterBackend *backend, QObject *parent = nullptr);
QScopedPointer<QPainterBackend> m_backend; QPainterBackend *m_backend;
QScopedPointer<QPainter> m_painter; QScopedPointer<QPainter> m_painter;
class Window; class Window;
}; };
@ -124,19 +124,6 @@ private:
QImage m_images[int(DecorationPart::Count)]; 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 inline
OverlayWindow* SceneQPainter::overlayWindow() const OverlayWindow* SceneQPainter::overlayWindow() const
{ {