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.
This commit is contained in:
Vlad Zahorodnii 2022-12-19 00:20:28 +02:00
parent 6c71bfd800
commit f37acaff54
38 changed files with 300 additions and 226 deletions

View file

@ -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

View file

@ -52,7 +52,7 @@ Deleted::~Deleted()
deleteShadow();
}
WindowItem *Deleted::createItem(WorkspaceScene *scene)
WindowItem *Deleted::createItem(Scene *scene)
{
Q_UNREACHABLE();
}

View file

@ -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.

View file

@ -67,7 +67,7 @@ InternalWindow::~InternalWindow()
{
}
WindowItem *InternalWindow::createItem(WorkspaceScene *scene)
WindowItem *InternalWindow::createItem(Scene *scene)
{
return new WindowItemInternal(this, scene);
}

View file

@ -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);

View file

@ -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();
}

View file

@ -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)
{

View file

@ -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;

View file

@ -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<SurfaceItemWayland>(icon->surface(), scene, this);

View file

@ -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);

View file

@ -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;
}

View file

@ -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<Item> m_parentItem;
QList<Item *> m_childItems;
QMatrix4x4 m_transform;

View file

@ -252,7 +252,7 @@ void ItemRendererOpenGL::renderItem(Item *item, int mask, const QRegion &region,
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()),
};

View file

@ -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());
}

143
src/scene/scene.cpp Normal file
View file

@ -0,0 +1,143 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
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 &region)
{
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<ItemRenderer> &&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 &region)
{
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<SceneDelegate *> 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

98
src/scene/scene.h Normal file
View file

@ -0,0 +1,98 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "core/renderlayerdelegate.h"
#include <QObject>
#include <memory>
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 &region) 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<ItemRenderer> &&renderer);
~Scene() override;
ItemRenderer *renderer() const;
void addRepaint(const QRegion &region);
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<SceneDelegate *> 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 &region) = 0;
Q_SIGNALS:
void delegateRemoved(SceneDelegate *delegate);
protected:
std::unique_ptr<ItemRenderer> m_renderer;
QList<SceneDelegate *> m_delegates;
QRect m_geometry;
};
} // namespace KWin

View file

@ -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)

View file

@ -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;

View file

@ -9,7 +9,7 @@
namespace KWin
{
SurfaceItem::SurfaceItem(WorkspaceScene *scene, Item *parent)
SurfaceItem::SurfaceItem(Scene *scene, Item *parent)
: Item(scene, parent)
{
}

View file

@ -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<SurfacePixmap> createPixmap() = 0;
void preprocess() override;

View file

@ -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)
{

View file

@ -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;

View file

@ -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)
{

View file

@ -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<QRectF> 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<QRectF> shape() const override;

View file

@ -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)
{

View file

@ -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;

View file

@ -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));

View file

@ -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

View file

@ -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 &region)
{
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<ItemRenderer> 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 &region)
{
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<SceneDelegate *> 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<Item *> children = item->childItems();
@ -470,11 +366,6 @@ void WorkspaceScene::paint(RenderTarget *renderTarget, const QRegion &region)
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 &region, ScreenPaintData &data)
{

View file

@ -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 &region) 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 &region);
void addRepaint(int x, int y, int width, int height);
void addRepaintFull();
QRegion damage() const;
QRect geometry() const;
void setGeometry(const QRect &rect);
QList<SceneDelegate *> 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 &region);
QRegion damage() const override;
SurfaceItem *scanoutCandidate() const override;
void prePaint(SceneDelegate *delegate) override;
void postPaint() override;
void paint(RenderTarget *renderTarget, const QRegion &region) 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<ItemRenderer> m_renderer;
std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();
QList<SceneDelegate *> m_delegates;
QRect m_geometry;
// how many times finalPaintScreen() has been called
int m_paintScreenCount = 0;
PaintContext m_paintContext;

View file

@ -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();

View file

@ -71,7 +71,7 @@ Unmanaged::~Unmanaged()
{
}
WindowItem *Unmanaged::createItem(WorkspaceScene *scene)
WindowItem *Unmanaged::createItem(Scene *scene)
{
return new WindowItemX11(this, scene);
}

View file

@ -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);

View file

@ -53,7 +53,7 @@ WaylandWindow::WaylandWindow(SurfaceInterface *surface)
updateIcon();
}
WindowItem *WaylandWindow::createItem(WorkspaceScene *scene)
WindowItem *WaylandWindow::createItem(Scene *scene)
{
return new WindowItemWayland(this, scene);
}

View file

@ -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);

View file

@ -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();

View file

@ -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);
}

View file

@ -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