From f37acaff54eb83ab3e67758483f8b50e0b5493ad Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Mon, 19 Dec 2022 00:20:28 +0200 Subject: [PATCH] scene: Split base Scene class from WorkspaceScene class The main motivation behind this change is to share rendering code between windows and the cursor, specifically the Item class which requires a Scene. Note that Scene subclasses are responsible for issuing ItemRenderer::renderItem() calls. The main reason for that is the current architecture of the effects system, specifically we need to call some effects hooks before and after painting a window. --- src/CMakeLists.txt | 1 + src/deleted.cpp | 2 +- src/deleted.h | 2 +- src/internalwindow.cpp | 2 +- src/internalwindow.h | 2 +- .../screencast/windowscreencastsource.cpp | 2 +- src/scene/decorationitem.cpp | 2 +- src/scene/decorationitem.h | 2 +- src/scene/dndiconitem.cpp | 2 +- src/scene/dndiconitem.h | 2 +- src/scene/item.cpp | 8 +- src/scene/item.h | 8 +- src/scene/itemrenderer_opengl.cpp | 2 +- src/scene/itemrenderer_qpainter.cpp | 4 +- src/scene/scene.cpp | 143 ++++++++++++++++++ src/scene/scene.h | 98 ++++++++++++ src/scene/shadowitem.cpp | 2 +- src/scene/shadowitem.h | 2 +- src/scene/surfaceitem.cpp | 2 +- src/scene/surfaceitem.h | 2 +- src/scene/surfaceitem_internal.cpp | 2 +- src/scene/surfaceitem_internal.h | 2 +- src/scene/surfaceitem_wayland.cpp | 4 +- src/scene/surfaceitem_wayland.h | 4 +- src/scene/surfaceitem_x11.cpp | 2 +- src/scene/surfaceitem_x11.h | 2 +- src/scene/windowitem.cpp | 8 +- src/scene/windowitem.h | 8 +- src/scene/workspacescene.cpp | 111 +------------- src/scene/workspacescene.h | 76 +--------- src/scripting/windowthumbnailitem.cpp | 2 +- src/unmanaged.cpp | 2 +- src/unmanaged.h | 2 +- src/waylandwindow.cpp | 2 +- src/waylandwindow.h | 2 +- src/window.h | 3 +- src/x11window.cpp | 2 +- src/x11window.h | 2 +- 38 files changed, 300 insertions(+), 226 deletions(-) create mode 100644 src/scene/scene.cpp create mode 100644 src/scene/scene.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 635ff430c6..50eb28b19e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -123,6 +123,7 @@ target_sources(kwin PRIVATE scene/itemrenderer.cpp scene/itemrenderer_opengl.cpp scene/itemrenderer_qpainter.cpp + scene/scene.cpp scene/shadowitem.cpp scene/surfaceitem.cpp scene/surfaceitem_internal.cpp diff --git a/src/deleted.cpp b/src/deleted.cpp index 16a3008bc3..aa26a4a2f0 100644 --- a/src/deleted.cpp +++ b/src/deleted.cpp @@ -52,7 +52,7 @@ Deleted::~Deleted() deleteShadow(); } -WindowItem *Deleted::createItem(WorkspaceScene *scene) +WindowItem *Deleted::createItem(Scene *scene) { Q_UNREACHABLE(); } diff --git a/src/deleted.h b/src/deleted.h index 19730909f3..12d438003e 100644 --- a/src/deleted.h +++ b/src/deleted.h @@ -104,7 +104,7 @@ public: { /* nothing to do */ return geometry; } - WindowItem *createItem(WorkspaceScene *scene) override; + WindowItem *createItem(Scene *scene) override; /** * Returns whether the client was a popup. diff --git a/src/internalwindow.cpp b/src/internalwindow.cpp index ee5eb24120..1c546761ad 100644 --- a/src/internalwindow.cpp +++ b/src/internalwindow.cpp @@ -67,7 +67,7 @@ InternalWindow::~InternalWindow() { } -WindowItem *InternalWindow::createItem(WorkspaceScene *scene) +WindowItem *InternalWindow::createItem(Scene *scene) { return new WindowItemInternal(this, scene); } diff --git a/src/internalwindow.h b/src/internalwindow.h index 75ae9a1bef..a7e930a810 100644 --- a/src/internalwindow.h +++ b/src/internalwindow.h @@ -72,7 +72,7 @@ protected: void doInteractiveResizeSync(const QRectF &rect) override; void updateCaption() override; void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override; - WindowItem *createItem(WorkspaceScene *scene) override; + WindowItem *createItem(Scene *scene) override; private: void requestGeometry(const QRectF &rect); diff --git a/src/plugins/screencast/windowscreencastsource.cpp b/src/plugins/screencast/windowscreencastsource.cpp index f385374f80..b675bf0b9a 100644 --- a/src/plugins/screencast/windowscreencastsource.cpp +++ b/src/plugins/screencast/windowscreencastsource.cpp @@ -63,7 +63,7 @@ void WindowScreenCastSource::render(GLFramebuffer *target) GLFramebuffer::pushFramebuffer(target); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - Compositor::self()->scene()->renderer()->renderItem(m_window->windowItem(), WorkspaceScene::PAINT_WINDOW_TRANSFORMED, infiniteRegion(), data); + Compositor::self()->scene()->renderer()->renderItem(m_window->windowItem(), Scene::PAINT_WINDOW_TRANSFORMED, infiniteRegion(), data); GLFramebuffer::popFramebuffer(); } diff --git a/src/scene/decorationitem.cpp b/src/scene/decorationitem.cpp index 3bea5d0235..054d08be22 100644 --- a/src/scene/decorationitem.cpp +++ b/src/scene/decorationitem.cpp @@ -124,7 +124,7 @@ void DecorationRenderer::renderToPainter(QPainter *painter, const QRect &rect) client()->decoration()->paint(painter, rect); } -DecorationItem::DecorationItem(KDecoration2::Decoration *decoration, Window *window, WorkspaceScene *scene, Item *parent) +DecorationItem::DecorationItem(KDecoration2::Decoration *decoration, Window *window, Scene *scene, Item *parent) : Item(scene, parent) , m_window(window) { diff --git a/src/scene/decorationitem.h b/src/scene/decorationitem.h index 3bb09f2925..64a6fb6778 100644 --- a/src/scene/decorationitem.h +++ b/src/scene/decorationitem.h @@ -79,7 +79,7 @@ class KWIN_EXPORT DecorationItem : public Item Q_OBJECT public: - explicit DecorationItem(KDecoration2::Decoration *decoration, Window *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit DecorationItem(KDecoration2::Decoration *decoration, Window *window, Scene *scene, Item *parent = nullptr); DecorationRenderer *renderer() const; Window *window() const; diff --git a/src/scene/dndiconitem.cpp b/src/scene/dndiconitem.cpp index 5caed21f35..c2577b6f51 100644 --- a/src/scene/dndiconitem.cpp +++ b/src/scene/dndiconitem.cpp @@ -12,7 +12,7 @@ namespace KWin { -DragAndDropIconItem::DragAndDropIconItem(KWaylandServer::DragAndDropIcon *icon, WorkspaceScene *scene, Item *parent) +DragAndDropIconItem::DragAndDropIconItem(KWaylandServer::DragAndDropIcon *icon, Scene *scene, Item *parent) : Item(scene, parent) { m_surfaceItem = std::make_unique(icon->surface(), scene, this); diff --git a/src/scene/dndiconitem.h b/src/scene/dndiconitem.h index c779584f2b..d79f09e12a 100644 --- a/src/scene/dndiconitem.h +++ b/src/scene/dndiconitem.h @@ -23,7 +23,7 @@ class DragAndDropIconItem : public Item Q_OBJECT public: - explicit DragAndDropIconItem(KWaylandServer::DragAndDropIcon *icon, WorkspaceScene *scene, Item *parent = nullptr); + explicit DragAndDropIconItem(KWaylandServer::DragAndDropIcon *icon, Scene *scene, Item *parent = nullptr); ~DragAndDropIconItem() override; void frameRendered(quint32 timestamp); diff --git a/src/scene/item.cpp b/src/scene/item.cpp index f81f053353..3069856c16 100644 --- a/src/scene/item.cpp +++ b/src/scene/item.cpp @@ -7,17 +7,17 @@ #include "scene/item.h" #include "core/renderlayer.h" #include "core/renderloop.h" -#include "scene/workspacescene.h" +#include "scene/scene.h" #include "utils/common.h" namespace KWin { -Item::Item(WorkspaceScene *scene, Item *parent) +Item::Item(Scene *scene, Item *parent) : m_scene(scene) { setParentItem(parent); - connect(m_scene, &WorkspaceScene::delegateRemoved, this, &Item::removeRepaints); + connect(m_scene, &Scene::delegateRemoved, this, &Item::removeRepaints); } Item::~Item() @@ -30,7 +30,7 @@ Item::~Item() } } -WorkspaceScene *Item::scene() const +Scene *Item::scene() const { return m_scene; } diff --git a/src/scene/item.h b/src/scene/item.h index e17d96cde0..51b57bc90e 100644 --- a/src/scene/item.h +++ b/src/scene/item.h @@ -19,7 +19,7 @@ namespace KWin { class SceneDelegate; -class WorkspaceScene; +class Scene; /** * The Item class is the base class for items in the scene. @@ -29,10 +29,10 @@ class KWIN_EXPORT Item : public QObject Q_OBJECT public: - explicit Item(WorkspaceScene *scene, Item *parent = nullptr); + explicit Item(Scene *scene, Item *parent = nullptr); ~Item() override; - WorkspaceScene *scene() const; + Scene *scene() const; qreal opacity() const; void setOpacity(qreal opacity); @@ -142,7 +142,7 @@ private: void updateEffectiveVisibility(); void removeRepaints(SceneDelegate *delegate); - WorkspaceScene *m_scene; + Scene *m_scene; QPointer m_parentItem; QList m_childItems; QMatrix4x4 m_transform; diff --git a/src/scene/itemrenderer_opengl.cpp b/src/scene/itemrenderer_opengl.cpp index cbee9aaa0a..bee38d865c 100644 --- a/src/scene/itemrenderer_opengl.cpp +++ b/src/scene/itemrenderer_opengl.cpp @@ -252,7 +252,7 @@ void ItemRendererOpenGL::renderItem(Item *item, int mask, const QRegion ®ion, RenderContext renderContext{ .clip = region, - .hardwareClipping = region != infiniteRegion() && ((mask & WorkspaceScene::PAINT_WINDOW_TRANSFORMED) || (mask & WorkspaceScene::PAINT_SCREEN_TRANSFORMED)), + .hardwareClipping = region != infiniteRegion() && ((mask & Scene::PAINT_WINDOW_TRANSFORMED) || (mask & Scene::PAINT_SCREEN_TRANSFORMED)), .renderTargetScale = data.renderTargetScale().value_or(renderTargetScale()), }; diff --git a/src/scene/itemrenderer_qpainter.cpp b/src/scene/itemrenderer_qpainter.cpp index 7b13c183eb..e27fc41cf6 100644 --- a/src/scene/itemrenderer_qpainter.cpp +++ b/src/scene/itemrenderer_qpainter.cpp @@ -53,7 +53,7 @@ void ItemRendererQPainter::renderItem(Item *item, int mask, const QRegion &_regi QRegion region = _region; const QRect boundingRect = item->mapToGlobal(item->boundingRect()).toAlignedRect(); - if (!(mask & (WorkspaceScene::PAINT_WINDOW_TRANSFORMED | WorkspaceScene::PAINT_SCREEN_TRANSFORMED))) { + if (!(mask & (Scene::PAINT_WINDOW_TRANSFORMED | Scene::PAINT_SCREEN_TRANSFORMED))) { region &= boundingRect; } @@ -66,7 +66,7 @@ void ItemRendererQPainter::renderItem(Item *item, int mask, const QRegion &_regi m_painter->setClipping(true); m_painter->setOpacity(data.opacity()); - if (mask & WorkspaceScene::PAINT_WINDOW_TRANSFORMED) { + if (mask & Scene::PAINT_WINDOW_TRANSFORMED) { m_painter->translate(data.xTranslation(), data.yTranslation()); m_painter->scale(data.xScale(), data.yScale()); } diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp new file mode 100644 index 0000000000..5e9ad9e683 --- /dev/null +++ b/src/scene/scene.cpp @@ -0,0 +1,143 @@ +/* + SPDX-FileCopyrightText: 2022 Vlad Zahorodnii + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "scene/scene.h" +#include "core/output.h" +#include "core/renderlayer.h" +#include "scene/itemrenderer.h" + +namespace KWin +{ + +SceneDelegate::SceneDelegate(Scene *scene) + : m_scene(scene) +{ + m_scene->addDelegate(this); +} + +SceneDelegate::SceneDelegate(Scene *scene, Output *output) + : m_scene(scene) + , m_output(output) +{ + m_scene->addDelegate(this); +} + +SceneDelegate::~SceneDelegate() +{ + m_scene->removeDelegate(this); +} + +QRegion SceneDelegate::repaints() const +{ + return m_scene->damage().translated(-viewport().topLeft()); +} + +SurfaceItem *SceneDelegate::scanoutCandidate() const +{ + return m_scene->scanoutCandidate(); +} + +void SceneDelegate::prePaint() +{ + m_scene->prePaint(this); +} + +void SceneDelegate::postPaint() +{ + m_scene->postPaint(); +} + +void SceneDelegate::paint(RenderTarget *renderTarget, const QRegion ®ion) +{ + m_scene->paint(renderTarget, region.translated(viewport().topLeft())); +} + +Output *SceneDelegate::output() const +{ + return m_output; +} + +QRect SceneDelegate::viewport() const +{ + return m_output ? m_output->geometry() : m_scene->geometry(); +} + +Scene::Scene(std::unique_ptr &&renderer) + : m_renderer(std::move(renderer)) +{ +} + +Scene::~Scene() +{ +} + +ItemRenderer *Scene::renderer() const +{ + return m_renderer.get(); +} + +void Scene::addRepaintFull() +{ + addRepaint(geometry()); +} + +void Scene::addRepaint(int x, int y, int width, int height) +{ + addRepaint(QRegion(x, y, width, height)); +} + +void Scene::addRepaint(const QRegion ®ion) +{ + for (const auto &delegate : std::as_const(m_delegates)) { + const QRect viewport = delegate->viewport(); + QRegion dirtyRegion = region & viewport; + dirtyRegion.translate(-viewport.topLeft()); + if (!dirtyRegion.isEmpty()) { + delegate->layer()->addRepaint(dirtyRegion); + } + } +} + +QRegion Scene::damage() const +{ + return QRegion(); +} + +QRect Scene::geometry() const +{ + return m_geometry; +} + +void Scene::setGeometry(const QRect &rect) +{ + if (m_geometry != rect) { + m_geometry = rect; + addRepaintFull(); + } +} + +QList Scene::delegates() const +{ + return m_delegates; +} + +void Scene::addDelegate(SceneDelegate *delegate) +{ + m_delegates.append(delegate); +} + +void Scene::removeDelegate(SceneDelegate *delegate) +{ + m_delegates.removeOne(delegate); + Q_EMIT delegateRemoved(delegate); +} + +SurfaceItem *Scene::scanoutCandidate() const +{ + return nullptr; +} + +} // namespace KWin diff --git a/src/scene/scene.h b/src/scene/scene.h new file mode 100644 index 0000000000..6b8f52265b --- /dev/null +++ b/src/scene/scene.h @@ -0,0 +1,98 @@ +/* + SPDX-FileCopyrightText: 2022 Vlad Zahorodnii + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "core/renderlayerdelegate.h" + +#include + +#include + +namespace KWin +{ + +class ItemRenderer; +class Output; +class Scene; + +class KWIN_EXPORT SceneDelegate : public RenderLayerDelegate +{ +public: + explicit SceneDelegate(Scene *scene); + explicit SceneDelegate(Scene *scene, Output *output); + ~SceneDelegate() override; + + Output *output() const; + QRect viewport() const; + + QRegion repaints() const override; + SurfaceItem *scanoutCandidate() const override; + void prePaint() override; + void postPaint() override; + void paint(RenderTarget *renderTarget, const QRegion ®ion) override; + +private: + Scene *m_scene; + Output *m_output = nullptr; +}; + +class KWIN_EXPORT Scene : public QObject +{ + Q_OBJECT + +public: + // Flags controlling how painting is done. + enum { + // WindowItem (or at least part of it) will be painted opaque. + PAINT_WINDOW_OPAQUE = 1 << 0, + // WindowItem (or at least part of it) will be painted translucent. + PAINT_WINDOW_TRANSLUCENT = 1 << 1, + // WindowItem will be painted with transformed geometry. + PAINT_WINDOW_TRANSFORMED = 1 << 2, + // Paint only a region of the screen (can be optimized, cannot + // be used together with TRANSFORMED flags). + PAINT_SCREEN_REGION = 1 << 3, + // Whole screen will be painted with transformed geometry. + PAINT_SCREEN_TRANSFORMED = 1 << 4, + // At least one window will be painted with transformed geometry. + PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5, + // Clear whole background as the very first step, without optimizing it + PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6, + }; + + explicit Scene(std::unique_ptr &&renderer); + ~Scene() override; + + ItemRenderer *renderer() const; + + void addRepaint(const QRegion ®ion); + void addRepaint(int x, int y, int width, int height); + void addRepaintFull(); + virtual QRegion damage() const; + + QRect geometry() const; + void setGeometry(const QRect &rect); + + QList delegates() const; + void addDelegate(SceneDelegate *delegate); + void removeDelegate(SceneDelegate *delegate); + + virtual SurfaceItem *scanoutCandidate() const; + virtual void prePaint(SceneDelegate *delegate) = 0; + virtual void postPaint() = 0; + virtual void paint(RenderTarget *renderTarget, const QRegion ®ion) = 0; + +Q_SIGNALS: + void delegateRemoved(SceneDelegate *delegate); + +protected: + std::unique_ptr m_renderer; + QList m_delegates; + QRect m_geometry; +}; + +} // namespace KWin diff --git a/src/scene/shadowitem.cpp b/src/scene/shadowitem.cpp index e1d0279ffe..28dbf213df 100644 --- a/src/scene/shadowitem.cpp +++ b/src/scene/shadowitem.cpp @@ -11,7 +11,7 @@ namespace KWin { -ShadowItem::ShadowItem(Shadow *shadow, Window *window, WorkspaceScene *scene, Item *parent) +ShadowItem::ShadowItem(Shadow *shadow, Window *window, Scene *scene, Item *parent) : Item(scene, parent) , m_window(window) , m_shadow(shadow) diff --git a/src/scene/shadowitem.h b/src/scene/shadowitem.h index 51cd39daca..45eca20d99 100644 --- a/src/scene/shadowitem.h +++ b/src/scene/shadowitem.h @@ -23,7 +23,7 @@ class KWIN_EXPORT ShadowItem : public Item Q_OBJECT public: - explicit ShadowItem(Shadow *shadow, Window *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit ShadowItem(Shadow *shadow, Window *window, Scene *scene, Item *parent = nullptr); ~ShadowItem() override; Shadow *shadow() const; diff --git a/src/scene/surfaceitem.cpp b/src/scene/surfaceitem.cpp index e13049275e..deb0b99d97 100644 --- a/src/scene/surfaceitem.cpp +++ b/src/scene/surfaceitem.cpp @@ -9,7 +9,7 @@ namespace KWin { -SurfaceItem::SurfaceItem(WorkspaceScene *scene, Item *parent) +SurfaceItem::SurfaceItem(Scene *scene, Item *parent) : Item(scene, parent) { } diff --git a/src/scene/surfaceitem.h b/src/scene/surfaceitem.h index 3e458724dc..492f9a3b65 100644 --- a/src/scene/surfaceitem.h +++ b/src/scene/surfaceitem.h @@ -45,7 +45,7 @@ Q_SIGNALS: void damaged(); protected: - explicit SurfaceItem(WorkspaceScene *scene, Item *parent = nullptr); + explicit SurfaceItem(Scene *scene, Item *parent = nullptr); virtual std::unique_ptr createPixmap() = 0; void preprocess() override; diff --git a/src/scene/surfaceitem_internal.cpp b/src/scene/surfaceitem_internal.cpp index 8088536c1c..e660c971ea 100644 --- a/src/scene/surfaceitem_internal.cpp +++ b/src/scene/surfaceitem_internal.cpp @@ -15,7 +15,7 @@ namespace KWin { -SurfaceItemInternal::SurfaceItemInternal(InternalWindow *window, WorkspaceScene *scene, Item *parent) +SurfaceItemInternal::SurfaceItemInternal(InternalWindow *window, Scene *scene, Item *parent) : SurfaceItem(scene, parent) , m_window(window) { diff --git a/src/scene/surfaceitem_internal.h b/src/scene/surfaceitem_internal.h index 67626379b5..b284696b66 100644 --- a/src/scene/surfaceitem_internal.h +++ b/src/scene/surfaceitem_internal.h @@ -24,7 +24,7 @@ class KWIN_EXPORT SurfaceItemInternal : public SurfaceItem Q_OBJECT public: - explicit SurfaceItemInternal(InternalWindow *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit SurfaceItemInternal(InternalWindow *window, Scene *scene, Item *parent = nullptr); Window *window() const; diff --git a/src/scene/surfaceitem_wayland.cpp b/src/scene/surfaceitem_wayland.cpp index e8a3238de6..66d1063a28 100644 --- a/src/scene/surfaceitem_wayland.cpp +++ b/src/scene/surfaceitem_wayland.cpp @@ -15,7 +15,7 @@ namespace KWin { -SurfaceItemWayland::SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, WorkspaceScene *scene, Item *parent) +SurfaceItemWayland::SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, Scene *scene, Item *parent) : SurfaceItem(scene, parent) , m_surface(surface) { @@ -202,7 +202,7 @@ void SurfacePixmapWayland::setBuffer(KWaylandServer::ClientBuffer *buffer) } } -SurfaceItemXwayland::SurfaceItemXwayland(Window *window, WorkspaceScene *scene, Item *parent) +SurfaceItemXwayland::SurfaceItemXwayland(Window *window, Scene *scene, Item *parent) : SurfaceItemWayland(window->surface(), scene, parent) , m_window(window) { diff --git a/src/scene/surfaceitem_wayland.h b/src/scene/surfaceitem_wayland.h index 4b8845dbb2..1d279deb74 100644 --- a/src/scene/surfaceitem_wayland.h +++ b/src/scene/surfaceitem_wayland.h @@ -28,7 +28,7 @@ class KWIN_EXPORT SurfaceItemWayland : public SurfaceItem Q_OBJECT public: - explicit SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, WorkspaceScene *scene, Item *parent = nullptr); + explicit SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface, Scene *scene, Item *parent = nullptr); QVector shape() const override; QRegion opaque() const override; @@ -87,7 +87,7 @@ class KWIN_EXPORT SurfaceItemXwayland : public SurfaceItemWayland Q_OBJECT public: - explicit SurfaceItemXwayland(Window *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit SurfaceItemXwayland(Window *window, Scene *scene, Item *parent = nullptr); QVector shape() const override; diff --git a/src/scene/surfaceitem_x11.cpp b/src/scene/surfaceitem_x11.cpp index 27200cb2ff..8859f8be9c 100644 --- a/src/scene/surfaceitem_x11.cpp +++ b/src/scene/surfaceitem_x11.cpp @@ -13,7 +13,7 @@ namespace KWin { -SurfaceItemX11::SurfaceItemX11(Window *window, WorkspaceScene *scene, Item *parent) +SurfaceItemX11::SurfaceItemX11(Window *window, Scene *scene, Item *parent) : SurfaceItem(scene, parent) , m_window(window) { diff --git a/src/scene/surfaceitem_x11.h b/src/scene/surfaceitem_x11.h index 0761cd16f8..0ab3a5826c 100644 --- a/src/scene/surfaceitem_x11.h +++ b/src/scene/surfaceitem_x11.h @@ -24,7 +24,7 @@ class KWIN_EXPORT SurfaceItemX11 : public SurfaceItem Q_OBJECT public: - explicit SurfaceItemX11(Window *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit SurfaceItemX11(Window *window, Scene *scene, Item *parent = nullptr); ~SurfaceItemX11() override; Window *window() const; diff --git a/src/scene/windowitem.cpp b/src/scene/windowitem.cpp index 074e5ff0cd..b926dd1c5e 100644 --- a/src/scene/windowitem.cpp +++ b/src/scene/windowitem.cpp @@ -19,7 +19,7 @@ namespace KWin { -WindowItem::WindowItem(Window *window, WorkspaceScene *scene, Item *parent) +WindowItem::WindowItem(Window *window, Scene *scene, Item *parent) : Item(scene, parent) , m_window(window) { @@ -248,7 +248,7 @@ void WindowItem::markDamaged() Q_EMIT m_window->damaged(m_window); } -WindowItemX11::WindowItemX11(Window *window, WorkspaceScene *scene, Item *parent) +WindowItemX11::WindowItemX11(Window *window, Scene *scene, Item *parent) : WindowItem(window, scene, parent) { initialize(); @@ -275,13 +275,13 @@ void WindowItemX11::initialize() } } -WindowItemWayland::WindowItemWayland(Window *window, WorkspaceScene *scene, Item *parent) +WindowItemWayland::WindowItemWayland(Window *window, Scene *scene, Item *parent) : WindowItem(window, scene, parent) { updateSurfaceItem(new SurfaceItemWayland(window->surface(), scene, this)); } -WindowItemInternal::WindowItemInternal(InternalWindow *window, WorkspaceScene *scene, Item *parent) +WindowItemInternal::WindowItemInternal(InternalWindow *window, Scene *scene, Item *parent) : WindowItem(window, scene, parent) { updateSurfaceItem(new SurfaceItemInternal(window, scene, this)); diff --git a/src/scene/windowitem.h b/src/scene/windowitem.h index 2da77cf9fb..8e0eaaffa5 100644 --- a/src/scene/windowitem.h +++ b/src/scene/windowitem.h @@ -53,7 +53,7 @@ public: void unrefVisible(int reason); protected: - explicit WindowItem(Window *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit WindowItem(Window *window, Scene *scene, Item *parent = nullptr); void updateSurfaceItem(SurfaceItem *surfaceItem); private Q_SLOTS: @@ -92,7 +92,7 @@ class KWIN_EXPORT WindowItemX11 : public WindowItem Q_OBJECT public: - explicit WindowItemX11(Window *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit WindowItemX11(Window *window, Scene *scene, Item *parent = nullptr); private Q_SLOTS: void initialize(); @@ -106,7 +106,7 @@ class KWIN_EXPORT WindowItemWayland : public WindowItem Q_OBJECT public: - explicit WindowItemWayland(Window *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit WindowItemWayland(Window *window, Scene *scene, Item *parent = nullptr); }; /** @@ -118,7 +118,7 @@ class KWIN_EXPORT WindowItemInternal : public WindowItem Q_OBJECT public: - explicit WindowItemInternal(InternalWindow *window, WorkspaceScene *scene, Item *parent = nullptr); + explicit WindowItemInternal(InternalWindow *window, Scene *scene, Item *parent = nullptr); }; } // namespace KWin diff --git a/src/scene/workspacescene.cpp b/src/scene/workspacescene.cpp index 680c0cc566..804b58e289 100644 --- a/src/scene/workspacescene.cpp +++ b/src/scene/workspacescene.cpp @@ -79,65 +79,12 @@ namespace KWin { -SceneDelegate::SceneDelegate(WorkspaceScene *scene) - : m_scene(scene) -{ - m_scene->addDelegate(this); -} - -SceneDelegate::SceneDelegate(WorkspaceScene *scene, Output *output) - : m_scene(scene) - , m_output(output) -{ - m_scene->addDelegate(this); -} - -SceneDelegate::~SceneDelegate() -{ - m_scene->removeDelegate(this); -} - -QRegion SceneDelegate::repaints() const -{ - return m_scene->damage().translated(-viewport().topLeft()); -} - -SurfaceItem *SceneDelegate::scanoutCandidate() const -{ - return m_scene->scanoutCandidate(); -} - -void SceneDelegate::prePaint() -{ - m_scene->prePaint(this); -} - -void SceneDelegate::postPaint() -{ - m_scene->postPaint(); -} - -void SceneDelegate::paint(RenderTarget *renderTarget, const QRegion ®ion) -{ - m_scene->paint(renderTarget, region.translated(viewport().topLeft())); -} - -Output *SceneDelegate::output() const -{ - return m_output; -} - -QRect SceneDelegate::viewport() const -{ - return m_output ? m_output->geometry() : m_scene->geometry(); -} - //**************************************** // Scene //**************************************** WorkspaceScene::WorkspaceScene(std::unique_ptr renderer) - : m_renderer(std::move(renderer)) + : Scene(std::move(renderer)) { } @@ -185,62 +132,11 @@ void WorkspaceScene::destroyDndIconItem() m_dndIcon.reset(); } -void WorkspaceScene::addRepaintFull() -{ - addRepaint(geometry()); -} - -void WorkspaceScene::addRepaint(int x, int y, int width, int height) -{ - addRepaint(QRegion(x, y, width, height)); -} - -void WorkspaceScene::addRepaint(const QRegion ®ion) -{ - for (const auto &delegate : std::as_const(m_delegates)) { - const QRect viewport = delegate->viewport(); - QRegion dirtyRegion = region & viewport; - dirtyRegion.translate(-viewport.topLeft()); - if (!dirtyRegion.isEmpty()) { - delegate->layer()->addRepaint(dirtyRegion); - } - } -} - QRegion WorkspaceScene::damage() const { return m_paintContext.damage; } -QRect WorkspaceScene::geometry() const -{ - return m_geometry; -} - -void WorkspaceScene::setGeometry(const QRect &rect) -{ - if (m_geometry != rect) { - m_geometry = rect; - addRepaintFull(); - } -} - -QList WorkspaceScene::delegates() const -{ - return m_delegates; -} - -void WorkspaceScene::addDelegate(SceneDelegate *delegate) -{ - m_delegates.append(delegate); -} - -void WorkspaceScene::removeDelegate(SceneDelegate *delegate) -{ - m_delegates.removeOne(delegate); - Q_EMIT delegateRemoved(delegate); -} - static SurfaceItem *findTopMostSurface(SurfaceItem *item) { const QList children = item->childItems(); @@ -470,11 +366,6 @@ void WorkspaceScene::paint(RenderTarget *renderTarget, const QRegion ®ion) m_renderer->endFrame(); } -ItemRenderer *WorkspaceScene::renderer() const -{ - return m_renderer.get(); -} - // the function that'll be eventually called by paintScreen() above void WorkspaceScene::finalPaintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) { diff --git a/src/scene/workspacescene.h b/src/scene/workspacescene.h index fc75470ce1..75656791ea 100644 --- a/src/scene/workspacescene.h +++ b/src/scene/workspacescene.h @@ -9,7 +9,8 @@ #pragma once -#include "core/renderlayerdelegate.h" +#include "scene/scene.h" + #include "kwineffects.h" #include "utils/common.h" #include "window.h" @@ -27,8 +28,6 @@ namespace Decoration class DecoratedClientImpl; } -class ItemRenderer; -class Output; class DecorationRenderer; class Deleted; class DragAndDropIconItem; @@ -42,28 +41,7 @@ class ShadowItem; class SurfaceItem; class WindowItem; -class SceneDelegate : public RenderLayerDelegate -{ -public: - explicit SceneDelegate(WorkspaceScene *scene); - explicit SceneDelegate(WorkspaceScene *scene, Output *output); - ~SceneDelegate() override; - - Output *output() const; - QRect viewport() const; - - QRegion repaints() const override; - SurfaceItem *scanoutCandidate() const override; - void prePaint() override; - void postPaint() override; - void paint(RenderTarget *renderTarget, const QRegion ®ion) override; - -private: - WorkspaceScene *m_scene; - Output *m_output = nullptr; -}; - -class KWIN_EXPORT WorkspaceScene : public QObject +class KWIN_EXPORT WorkspaceScene : public Scene { Q_OBJECT @@ -73,25 +51,11 @@ public: void initialize(); - /** - * Schedules a repaint for the specified @a region. - */ - void addRepaint(const QRegion ®ion); - void addRepaint(int x, int y, int width, int height); - void addRepaintFull(); - QRegion damage() const; - - QRect geometry() const; - void setGeometry(const QRect &rect); - - QList delegates() const; - void addDelegate(SceneDelegate *delegate); - void removeDelegate(SceneDelegate *delegate); - - SurfaceItem *scanoutCandidate() const; - void prePaint(SceneDelegate *delegate); - void postPaint(); - void paint(RenderTarget *renderTarget, const QRegion ®ion); + QRegion damage() const override; + SurfaceItem *scanoutCandidate() const override; + void prePaint(SceneDelegate *delegate) override; + void postPaint() override; + void paint(RenderTarget *renderTarget, const QRegion ®ion) override; /** * @brief Creates the Scene specific Shadow subclass. @@ -102,24 +66,6 @@ public: * @param window The Window for which the Shadow needs to be created. */ virtual Shadow *createShadow(Window *window) = 0; - // Flags controlling how painting is done. - enum { - // WindowItem (or at least part of it) will be painted opaque. - PAINT_WINDOW_OPAQUE = 1 << 0, - // WindowItem (or at least part of it) will be painted translucent. - PAINT_WINDOW_TRANSLUCENT = 1 << 1, - // WindowItem will be painted with transformed geometry. - PAINT_WINDOW_TRANSFORMED = 1 << 2, - // Paint only a region of the screen (can be optimized, cannot - // be used together with TRANSFORMED flags). - PAINT_SCREEN_REGION = 1 << 3, - // Whole screen will be painted with transformed geometry. - PAINT_SCREEN_TRANSFORMED = 1 << 4, - // At least one window will be painted with transformed geometry. - PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5, - // Clear whole background as the very first step, without optimizing it - PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6, - }; virtual bool makeOpenGLContextCurrent(); virtual void doneOpenGLContextCurrent(); @@ -140,12 +86,9 @@ public: return {}; } - ItemRenderer *renderer() const; - Q_SIGNALS: void preFrameRender(); void frameRendered(); - void delegateRemoved(SceneDelegate *delegate); protected: void createStackingOrder(); @@ -194,10 +137,7 @@ private: void createDndIconItem(); void destroyDndIconItem(); - std::unique_ptr m_renderer; std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero(); - QList m_delegates; - QRect m_geometry; // how many times finalPaintScreen() has been called int m_paintScreenCount = 0; PaintContext m_paintContext; diff --git a/src/scripting/windowthumbnailitem.cpp b/src/scripting/windowthumbnailitem.cpp index 19aec3faa6..a7ab64ed32 100644 --- a/src/scripting/windowthumbnailitem.cpp +++ b/src/scripting/windowthumbnailitem.cpp @@ -443,7 +443,7 @@ void WindowThumbnailItem::updateOffscreenTexture() // The thumbnail must be rendered using kwin's opengl context as VAOs are not // shared across contexts. Unfortunately, this also introduces a latency of 1 // frame, which is not ideal, but it is acceptable for things such as thumbnails. - const int mask = WorkspaceScene::PAINT_WINDOW_TRANSFORMED; + const int mask = Scene::PAINT_WINDOW_TRANSFORMED; Compositor::self()->scene()->renderer()->renderItem(m_client->windowItem(), mask, infiniteRegion(), data); GLFramebuffer::popFramebuffer(); diff --git a/src/unmanaged.cpp b/src/unmanaged.cpp index 29546690d7..41e4725daf 100644 --- a/src/unmanaged.cpp +++ b/src/unmanaged.cpp @@ -71,7 +71,7 @@ Unmanaged::~Unmanaged() { } -WindowItem *Unmanaged::createItem(WorkspaceScene *scene) +WindowItem *Unmanaged::createItem(Scene *scene) { return new WindowItemX11(this, scene); } diff --git a/src/unmanaged.h b/src/unmanaged.h index 0fcd81f1b7..721ceffe1d 100644 --- a/src/unmanaged.h +++ b/src/unmanaged.h @@ -59,7 +59,7 @@ public: { /* nothing to do */ return geometry; } - WindowItem *createItem(WorkspaceScene *scene) override; + WindowItem *createItem(Scene *scene) override; public Q_SLOTS: void release(ReleaseReason releaseReason = ReleaseReason::Release); diff --git a/src/waylandwindow.cpp b/src/waylandwindow.cpp index 10b849d6af..1aba0f0e96 100644 --- a/src/waylandwindow.cpp +++ b/src/waylandwindow.cpp @@ -53,7 +53,7 @@ WaylandWindow::WaylandWindow(SurfaceInterface *surface) updateIcon(); } -WindowItem *WaylandWindow::createItem(WorkspaceScene *scene) +WindowItem *WaylandWindow::createItem(Scene *scene) { return new WindowItemWayland(this, scene); } diff --git a/src/waylandwindow.h b/src/waylandwindow.h index baf563edbc..857d97ae50 100644 --- a/src/waylandwindow.h +++ b/src/waylandwindow.h @@ -44,7 +44,7 @@ protected: bool belongsToDesktop() const override; void doSetActive() override; void updateCaption() override; - WindowItem *createItem(WorkspaceScene *scene) override; + WindowItem *createItem(Scene *scene) override; void cleanGrouping(); void updateGeometry(const QRectF &rect); diff --git a/src/window.h b/src/window.h index 821d079701..9cbe11dac2 100644 --- a/src/window.h +++ b/src/window.h @@ -51,6 +51,7 @@ class ClientMachine; class Deleted; class EffectWindowImpl; class Tile; +class Scene; class Shadow; class SurfaceItem; class VirtualDesktop; @@ -1579,7 +1580,7 @@ protected: void getWmOpaqueRegion(); void discardShapeRegion(); - virtual WindowItem *createItem(WorkspaceScene *scene) = 0; + virtual WindowItem *createItem(Scene *scene) = 0; void deleteItem(); void getResourceClass(); diff --git a/src/x11window.cpp b/src/x11window.cpp index e831a7f518..f490f4c6ff 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -316,7 +316,7 @@ X11Window::~X11Window() Q_ASSERT(!check_active_modal); } -WindowItem *X11Window::createItem(WorkspaceScene *scene) +WindowItem *X11Window::createItem(Scene *scene) { return new WindowItemX11(this, scene); } diff --git a/src/x11window.h b/src/x11window.h index 8ebc4399f8..90f3329545 100644 --- a/src/x11window.h +++ b/src/x11window.h @@ -357,7 +357,7 @@ protected: QSizeF resizeIncrements() const override; bool acceptsFocus() const override; void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override; - WindowItem *createItem(WorkspaceScene *scene) override; + WindowItem *createItem(Scene *scene) override; // Signals for the scripting interface // Signals make an excellent way for communication