scene: Decouple scene bits from Shadow class

Currently the Shadow class is scene specific, which adds coupling
between Window and scene bits.

This change introduces ShadowTextureProvider that contains scene
specific stuff so the Shadow acts like a data source and is not coupled
to concrete scene.
This commit is contained in:
Vlad Zahorodnii 2023-01-17 20:22:28 +02:00
parent 21d410710c
commit 0e906ec182
10 changed files with 122 additions and 119 deletions

View file

@ -159,9 +159,9 @@ void ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context)
if (auto shadowItem = qobject_cast<ShadowItem *>(item)) { if (auto shadowItem = qobject_cast<ShadowItem *>(item)) {
if (!geometry.isEmpty()) { if (!geometry.isEmpty()) {
SceneOpenGLShadow *shadow = static_cast<SceneOpenGLShadow *>(shadowItem->shadow()); OpenGLShadowTextureProvider *textureProvider = static_cast<OpenGLShadowTextureProvider *>(shadowItem->textureProvider());
context->renderNodes.append(RenderNode{ context->renderNodes.append(RenderNode{
.texture = shadow->shadowTexture(), .texture = textureProvider->shadowTexture(),
.geometry = geometry, .geometry = geometry,
.transformMatrix = context->transformStack.top(), .transformMatrix = context->transformStack.top(),
.opacity = context->opacityStack.top(), .opacity = context->opacityStack.top(),

View file

@ -5,16 +5,28 @@
*/ */
#include "scene/shadowitem.h" #include "scene/shadowitem.h"
#include "composite.h"
#include "deleted.h" #include "deleted.h"
#include "scene/workspacescene.h"
#include "shadow.h" #include "shadow.h"
namespace KWin namespace KWin
{ {
ShadowTextureProvider::ShadowTextureProvider(Shadow *shadow)
: m_shadow(shadow)
{
}
ShadowTextureProvider::~ShadowTextureProvider()
{
}
ShadowItem::ShadowItem(Shadow *shadow, Window *window, Scene *scene, Item *parent) ShadowItem::ShadowItem(Shadow *shadow, Window *window, Scene *scene, Item *parent)
: Item(scene, parent) : Item(scene, parent)
, m_window(window) , m_window(window)
, m_shadow(shadow) , m_shadow(shadow)
, m_textureProvider(Compositor::self()->scene()->createShadowTextureProvider(shadow))
{ {
connect(window, &Window::windowClosed, this, &ShadowItem::handleWindowClosed); connect(window, &Window::windowClosed, this, &ShadowItem::handleWindowClosed);
@ -35,6 +47,11 @@ Shadow *ShadowItem::shadow() const
return m_shadow; return m_shadow;
} }
ShadowTextureProvider *ShadowItem::textureProvider() const
{
return m_textureProvider.get();
}
void ShadowItem::updateGeometry() void ShadowItem::updateGeometry()
{ {
const QRectF rect = m_shadow->rect() + m_shadow->offset(); const QRectF rect = m_shadow->rect() + m_shadow->offset();
@ -48,6 +65,7 @@ void ShadowItem::handleTextureChanged()
{ {
scheduleRepaint(rect()); scheduleRepaint(rect());
discardQuads(); discardQuads();
m_textureDirty = true;
} }
void ShadowItem::handleWindowClosed(Window *original, Deleted *deleted) void ShadowItem::handleWindowClosed(Window *original, Deleted *deleted)
@ -287,4 +305,12 @@ WindowQuadList ShadowItem::buildQuads() const
return quads; return quads;
} }
void ShadowItem::preprocess()
{
if (m_textureDirty) {
m_textureDirty = false;
m_textureProvider->update();
}
}
} // namespace KWin } // namespace KWin

View file

@ -15,6 +15,20 @@ class Deleted;
class Shadow; class Shadow;
class Window; class Window;
class KWIN_EXPORT ShadowTextureProvider
{
public:
explicit ShadowTextureProvider(Shadow *shadow);
virtual ~ShadowTextureProvider();
Shadow *shadow() const { return m_shadow; }
virtual void update() = 0;
protected:
Shadow *m_shadow;
};
/** /**
* The ShadowItem class represents a nine-tile patch server-side drop-shadow. * The ShadowItem class represents a nine-tile patch server-side drop-shadow.
*/ */
@ -27,9 +41,11 @@ public:
~ShadowItem() override; ~ShadowItem() override;
Shadow *shadow() const; Shadow *shadow() const;
ShadowTextureProvider *textureProvider() const;
protected: protected:
WindowQuadList buildQuads() const override; WindowQuadList buildQuads() const override;
void preprocess() override;
private Q_SLOTS: private Q_SLOTS:
void handleTextureChanged(); void handleTextureChanged();
@ -39,6 +55,8 @@ private Q_SLOTS:
private: private:
Window *m_window; Window *m_window;
Shadow *m_shadow = nullptr; Shadow *m_shadow = nullptr;
std::unique_ptr<ShadowTextureProvider> m_textureProvider;
bool m_textureDirty = true;
}; };
} // namespace KWin } // namespace KWin

View file

@ -38,6 +38,7 @@ class RenderLoop;
class WorkspaceScene; class WorkspaceScene;
class Shadow; class Shadow;
class ShadowItem; class ShadowItem;
class ShadowTextureProvider;
class SurfaceItem; class SurfaceItem;
class WindowItem; class WindowItem;
@ -57,21 +58,12 @@ public:
void postPaint() override; void postPaint() override;
void paint(RenderTarget *renderTarget, const QRegion &region) override; void paint(RenderTarget *renderTarget, const QRegion &region) override;
/**
* @brief Creates the Scene specific Shadow subclass.
*
* An implementing class has to create a proper instance. It is not allowed to
* return @c null.
*
* @param window The Window for which the Shadow needs to be created.
*/
virtual std::unique_ptr<Shadow> createShadow(Window *window) = 0;
virtual bool makeOpenGLContextCurrent(); virtual bool makeOpenGLContextCurrent();
virtual void doneOpenGLContextCurrent(); virtual void doneOpenGLContextCurrent();
virtual bool supportsNativeFence() const; virtual bool supportsNativeFence() const;
virtual DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *) = 0; virtual DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *) = 0;
virtual std::unique_ptr<ShadowTextureProvider> createShadowTextureProvider(Shadow *shadow) = 0;
/** /**
* Whether the Scene is able to drive animations. * Whether the Scene is able to drive animations.

View file

@ -19,6 +19,7 @@
#include "core/output.h" #include "core/output.h"
#include "decorations/decoratedclient.h" #include "decorations/decoratedclient.h"
#include "scene/itemrenderer_opengl.h" #include "scene/itemrenderer_opengl.h"
#include "shadow.h"
#include "window.h" #include "window.h"
#include <cmath> #include <cmath>
@ -69,16 +70,16 @@ bool WorkspaceSceneOpenGL::supportsNativeFence() const
return m_backend->supportsNativeFence(); return m_backend->supportsNativeFence();
} }
std::unique_ptr<Shadow> WorkspaceSceneOpenGL::createShadow(Window *window)
{
return std::make_unique<SceneOpenGLShadow>(window);
}
DecorationRenderer *WorkspaceSceneOpenGL::createDecorationRenderer(Decoration::DecoratedClientImpl *impl) DecorationRenderer *WorkspaceSceneOpenGL::createDecorationRenderer(Decoration::DecoratedClientImpl *impl)
{ {
return new SceneOpenGLDecorationRenderer(impl); return new SceneOpenGLDecorationRenderer(impl);
} }
std::unique_ptr<ShadowTextureProvider> WorkspaceSceneOpenGL::createShadowTextureProvider(Shadow *shadow)
{
return std::make_unique<OpenGLShadowTextureProvider>(shadow);
}
bool WorkspaceSceneOpenGL::animationsSupported() const bool WorkspaceSceneOpenGL::animationsSupported() const
{ {
return !GLPlatform::instance()->isSoftwareEmulation(); return !GLPlatform::instance()->isSoftwareEmulation();
@ -99,15 +100,15 @@ public:
DecorationShadowTextureCache(const DecorationShadowTextureCache &) = delete; DecorationShadowTextureCache(const DecorationShadowTextureCache &) = delete;
static DecorationShadowTextureCache &instance(); static DecorationShadowTextureCache &instance();
void unregister(SceneOpenGLShadow *shadow); void unregister(ShadowTextureProvider *provider);
std::shared_ptr<GLTexture> getTexture(SceneOpenGLShadow *shadow); std::shared_ptr<GLTexture> getTexture(ShadowTextureProvider *provider);
private: private:
DecorationShadowTextureCache() = default; DecorationShadowTextureCache() = default;
struct Data struct Data
{ {
std::shared_ptr<GLTexture> texture; std::shared_ptr<GLTexture> texture;
QVector<SceneOpenGLShadow *> shadows; QVector<ShadowTextureProvider *> providers;
}; };
QHash<KDecoration2::DecorationShadow *, Data> m_cache; QHash<KDecoration2::DecorationShadow *, Data> m_cache;
}; };
@ -123,22 +124,22 @@ DecorationShadowTextureCache::~DecorationShadowTextureCache()
Q_ASSERT(m_cache.isEmpty()); Q_ASSERT(m_cache.isEmpty());
} }
void DecorationShadowTextureCache::unregister(SceneOpenGLShadow *shadow) void DecorationShadowTextureCache::unregister(ShadowTextureProvider *provider)
{ {
auto it = m_cache.begin(); auto it = m_cache.begin();
while (it != m_cache.end()) { while (it != m_cache.end()) {
auto &d = it.value(); auto &d = it.value();
// check whether the Vector of Shadows contains our shadow and remove all of them // check whether the Vector of Shadows contains our shadow and remove all of them
auto glIt = d.shadows.begin(); auto glIt = d.providers.begin();
while (glIt != d.shadows.end()) { while (glIt != d.providers.end()) {
if (*glIt == shadow) { if (*glIt == provider) {
glIt = d.shadows.erase(glIt); glIt = d.providers.erase(glIt);
} else { } else {
glIt++; glIt++;
} }
} }
// if there are no shadows any more we can erase the cache entry // if there are no shadows any more we can erase the cache entry
if (d.shadows.isEmpty()) { if (d.providers.isEmpty()) {
it = m_cache.erase(it); it = m_cache.erase(it);
} else { } else {
it++; it++;
@ -146,31 +147,32 @@ void DecorationShadowTextureCache::unregister(SceneOpenGLShadow *shadow)
} }
} }
std::shared_ptr<GLTexture> DecorationShadowTextureCache::getTexture(SceneOpenGLShadow *shadow) std::shared_ptr<GLTexture> DecorationShadowTextureCache::getTexture(ShadowTextureProvider *provider)
{ {
Shadow *shadow = provider->shadow();
Q_ASSERT(shadow->hasDecorationShadow()); Q_ASSERT(shadow->hasDecorationShadow());
unregister(shadow); unregister(provider);
const auto &decoShadow = shadow->decorationShadow().toStrongRef(); const auto &decoShadow = shadow->decorationShadow().toStrongRef();
Q_ASSERT(!decoShadow.isNull()); Q_ASSERT(!decoShadow.isNull());
auto it = m_cache.find(decoShadow.data()); auto it = m_cache.find(decoShadow.data());
if (it != m_cache.end()) { if (it != m_cache.end()) {
Q_ASSERT(!it.value().shadows.contains(shadow)); Q_ASSERT(!it.value().providers.contains(provider));
it.value().shadows << shadow; it.value().providers << provider;
return it.value().texture; return it.value().texture;
} }
Data d; Data d;
d.shadows << shadow; d.providers << provider;
d.texture = std::make_shared<GLTexture>(shadow->decorationShadowImage()); d.texture = std::make_shared<GLTexture>(shadow->decorationShadowImage());
m_cache.insert(decoShadow.data(), d); m_cache.insert(decoShadow.data(), d);
return d.texture; return d.texture;
} }
SceneOpenGLShadow::SceneOpenGLShadow(Window *window) OpenGLShadowTextureProvider::OpenGLShadowTextureProvider(Shadow *shadow)
: Shadow(window) : ShadowTextureProvider(shadow)
{ {
} }
SceneOpenGLShadow::~SceneOpenGLShadow() OpenGLShadowTextureProvider::~OpenGLShadowTextureProvider()
{ {
WorkspaceScene *scene = Compositor::self()->scene(); WorkspaceScene *scene = Compositor::self()->scene();
if (scene) { if (scene) {
@ -180,30 +182,28 @@ SceneOpenGLShadow::~SceneOpenGLShadow()
} }
} }
bool SceneOpenGLShadow::prepareBackend() void OpenGLShadowTextureProvider::update()
{ {
if (hasDecorationShadow()) { if (m_shadow->hasDecorationShadow()) {
// simplifies a lot by going directly to // simplifies a lot by going directly to
WorkspaceScene *scene = Compositor::self()->scene();
scene->makeOpenGLContextCurrent();
m_texture = DecorationShadowTextureCache::instance().getTexture(this); m_texture = DecorationShadowTextureCache::instance().getTexture(this);
return;
return true;
} }
const QSize top(shadowElement(ShadowElementTop).size());
const QSize topRight(shadowElement(ShadowElementTopRight).size()); const QSize top(m_shadow->shadowElement(Shadow::ShadowElementTop).size());
const QSize right(shadowElement(ShadowElementRight).size()); const QSize topRight(m_shadow->shadowElement(Shadow::ShadowElementTopRight).size());
const QSize bottom(shadowElement(ShadowElementBottom).size()); const QSize right(m_shadow->shadowElement(Shadow::ShadowElementRight).size());
const QSize bottomLeft(shadowElement(ShadowElementBottomLeft).size()); const QSize bottom(m_shadow->shadowElement(Shadow::ShadowElementBottom).size());
const QSize left(shadowElement(ShadowElementLeft).size()); const QSize bottomLeft(m_shadow->shadowElement(Shadow::ShadowElementBottomLeft).size());
const QSize topLeft(shadowElement(ShadowElementTopLeft).size()); const QSize left(m_shadow->shadowElement(Shadow::ShadowElementLeft).size());
const QSize bottomRight(shadowElement(ShadowElementBottomRight).size()); const QSize topLeft(m_shadow->shadowElement(Shadow::ShadowElementTopLeft).size());
const QSize bottomRight(m_shadow->shadowElement(Shadow::ShadowElementBottomRight).size());
const int width = std::max({topLeft.width(), left.width(), bottomLeft.width()}) + std::max(top.width(), bottom.width()) + std::max({topRight.width(), right.width(), bottomRight.width()}); const int width = std::max({topLeft.width(), left.width(), bottomLeft.width()}) + std::max(top.width(), bottom.width()) + std::max({topRight.width(), right.width(), bottomRight.width()});
const int height = std::max({topLeft.height(), top.height(), topRight.height()}) + std::max(left.height(), right.height()) + std::max({bottomLeft.height(), bottom.height(), bottomRight.height()}); const int height = std::max({topLeft.height(), top.height(), topRight.height()}) + std::max(left.height(), right.height()) + std::max({bottomLeft.height(), bottom.height(), bottomRight.height()});
if (width == 0 || height == 0) { if (width == 0 || height == 0) {
return false; return;
} }
QImage image(width, height, QImage::Format_ARGB32); QImage image(width, height, QImage::Format_ARGB32);
@ -215,16 +215,16 @@ bool SceneOpenGLShadow::prepareBackend()
QPainter p; QPainter p;
p.begin(&image); p.begin(&image);
p.drawImage(QRectF(0, 0, topLeft.width(), topLeft.height()), shadowElement(ShadowElementTopLeft)); p.drawImage(QRectF(0, 0, topLeft.width(), topLeft.height()), m_shadow->shadowElement(Shadow::ShadowElementTopLeft));
p.drawImage(QRectF(innerRectLeft, 0, top.width(), top.height()), shadowElement(ShadowElementTop)); p.drawImage(QRectF(innerRectLeft, 0, top.width(), top.height()), m_shadow->shadowElement(Shadow::ShadowElementTop));
p.drawImage(QRectF(width - topRight.width(), 0, topRight.width(), topRight.height()), shadowElement(ShadowElementTopRight)); p.drawImage(QRectF(width - topRight.width(), 0, topRight.width(), topRight.height()), m_shadow->shadowElement(Shadow::ShadowElementTopRight));
p.drawImage(QRectF(0, innerRectTop, left.width(), left.height()), shadowElement(ShadowElementLeft)); p.drawImage(QRectF(0, innerRectTop, left.width(), left.height()), m_shadow->shadowElement(Shadow::ShadowElementLeft));
p.drawImage(QRectF(width - right.width(), innerRectTop, right.width(), right.height()), shadowElement(ShadowElementRight)); p.drawImage(QRectF(width - right.width(), innerRectTop, right.width(), right.height()), m_shadow->shadowElement(Shadow::ShadowElementRight));
p.drawImage(QRectF(0, height - bottomLeft.height(), bottomLeft.width(), bottomLeft.height()), shadowElement(ShadowElementBottomLeft)); p.drawImage(QRectF(0, height - bottomLeft.height(), bottomLeft.width(), bottomLeft.height()), m_shadow->shadowElement(Shadow::ShadowElementBottomLeft));
p.drawImage(QRectF(innerRectLeft, height - bottom.height(), bottom.width(), bottom.height()), shadowElement(ShadowElementBottom)); p.drawImage(QRectF(innerRectLeft, height - bottom.height(), bottom.width(), bottom.height()), m_shadow->shadowElement(Shadow::ShadowElementBottom));
p.drawImage(QRectF(width - bottomRight.width(), height - bottomRight.height(), bottomRight.width(), bottomRight.height()), shadowElement(ShadowElementBottomRight)); p.drawImage(QRectF(width - bottomRight.width(), height - bottomRight.height(), bottomRight.width(), bottomRight.height()), m_shadow->shadowElement(Shadow::ShadowElementBottomRight));
p.end(); p.end();
@ -251,8 +251,6 @@ bool SceneOpenGLShadow::prepareBackend()
} }
} }
WorkspaceScene *scene = Compositor::self()->scene();
scene->makeOpenGLContextCurrent();
m_texture = std::make_shared<GLTexture>(image); m_texture = std::make_shared<GLTexture>(image);
if (m_texture->internalFormat() == GL_R8) { if (m_texture->internalFormat() == GL_R8) {
@ -260,8 +258,6 @@ bool SceneOpenGLShadow::prepareBackend()
m_texture->bind(); m_texture->bind();
m_texture->setSwizzle(GL_ZERO, GL_ZERO, GL_ZERO, GL_RED); m_texture->setSwizzle(GL_ZERO, GL_ZERO, GL_ZERO, GL_RED);
} }
return true;
} }
SceneOpenGLDecorationRenderer::SceneOpenGLDecorationRenderer(Decoration::DecoratedClientImpl *client) SceneOpenGLDecorationRenderer::SceneOpenGLDecorationRenderer(Decoration::DecoratedClientImpl *client)

View file

@ -13,8 +13,8 @@
#include "openglbackend.h" #include "openglbackend.h"
#include "scene/decorationitem.h" #include "scene/decorationitem.h"
#include "scene/shadowitem.h"
#include "scene/workspacescene.h" #include "scene/workspacescene.h"
#include "shadow.h"
#include "kwinglutils.h" #include "kwinglutils.h"
@ -30,11 +30,11 @@ public:
explicit WorkspaceSceneOpenGL(OpenGLBackend *backend); explicit WorkspaceSceneOpenGL(OpenGLBackend *backend);
~WorkspaceSceneOpenGL() override; ~WorkspaceSceneOpenGL() override;
std::unique_ptr<Shadow> createShadow(Window *window) override;
bool makeOpenGLContextCurrent() override; bool makeOpenGLContextCurrent() override;
void doneOpenGLContextCurrent() override; void doneOpenGLContextCurrent() override;
bool supportsNativeFence() const override; bool supportsNativeFence() const override;
DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override; DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override;
std::unique_ptr<ShadowTextureProvider> createShadowTextureProvider(Shadow *shadow) override;
bool animationsSupported() const override; bool animationsSupported() const override;
OpenGLBackend *backend() const OpenGLBackend *backend() const
@ -55,20 +55,18 @@ private:
* This class extends Shadow by the Elements required for OpenGL rendering. * This class extends Shadow by the Elements required for OpenGL rendering.
* @author Martin Gräßlin <mgraesslin@kde.org> * @author Martin Gräßlin <mgraesslin@kde.org>
*/ */
class SceneOpenGLShadow class OpenGLShadowTextureProvider : public ShadowTextureProvider
: public Shadow
{ {
public: public:
explicit SceneOpenGLShadow(Window *window); explicit OpenGLShadowTextureProvider(Shadow *shadow);
~SceneOpenGLShadow() override; ~OpenGLShadowTextureProvider() override;
GLTexture *shadowTexture() GLTexture *shadowTexture()
{ {
return m_texture.get(); return m_texture.get();
} }
protected: void update() override;
bool prepareBackend() override;
private: private:
std::shared_ptr<GLTexture> m_texture; std::shared_ptr<GLTexture> m_texture;

View file

@ -36,33 +36,28 @@ WorkspaceSceneQPainter::~WorkspaceSceneQPainter()
{ {
} }
std::unique_ptr<Shadow> WorkspaceSceneQPainter::createShadow(Window *window)
{
return std::make_unique<SceneQPainterShadow>(window);
}
DecorationRenderer *WorkspaceSceneQPainter::createDecorationRenderer(Decoration::DecoratedClientImpl *impl) DecorationRenderer *WorkspaceSceneQPainter::createDecorationRenderer(Decoration::DecoratedClientImpl *impl)
{ {
return new SceneQPainterDecorationRenderer(impl); return new SceneQPainterDecorationRenderer(impl);
} }
std::unique_ptr<ShadowTextureProvider> WorkspaceSceneQPainter::createShadowTextureProvider(Shadow *shadow)
{
return std::make_unique<QPainterShadowTextureProvider>(shadow);
}
//**************************************** //****************************************
// QPainterShadow // QPainterShadow
//**************************************** //****************************************
SceneQPainterShadow::SceneQPainterShadow(Window *window) QPainterShadowTextureProvider::QPainterShadowTextureProvider(Shadow *shadow)
: Shadow(window) : ShadowTextureProvider(shadow)
{ {
} }
SceneQPainterShadow::~SceneQPainterShadow() void QPainterShadowTextureProvider::update()
{ {
} }
bool SceneQPainterShadow::prepareBackend()
{
return true;
}
//**************************************** //****************************************
// QPainterDecorationRenderer // QPainterDecorationRenderer
//**************************************** //****************************************

View file

@ -11,8 +11,8 @@
#include "qpainterbackend.h" #include "qpainterbackend.h"
#include "scene/decorationitem.h" #include "scene/decorationitem.h"
#include "scene/shadowitem.h"
#include "scene/workspacescene.h" #include "scene/workspacescene.h"
#include "shadow.h"
namespace KWin namespace KWin
{ {
@ -25,8 +25,8 @@ public:
explicit WorkspaceSceneQPainter(QPainterBackend *backend); explicit WorkspaceSceneQPainter(QPainterBackend *backend);
~WorkspaceSceneQPainter() override; ~WorkspaceSceneQPainter() override;
std::unique_ptr<Shadow> createShadow(Window *window) override;
DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override; DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override;
std::unique_ptr<ShadowTextureProvider> createShadowTextureProvider(Shadow *shadow) override;
bool animationsSupported() const override bool animationsSupported() const override
{ {
@ -42,14 +42,12 @@ private:
QPainterBackend *m_backend; QPainterBackend *m_backend;
}; };
class SceneQPainterShadow : public Shadow class QPainterShadowTextureProvider : public ShadowTextureProvider
{ {
public: public:
SceneQPainterShadow(Window *window); explicit QPainterShadowTextureProvider(Shadow *shadow);
~SceneQPainterShadow() override;
protected: void update() override;
bool prepareBackend() override;
}; };
class SceneQPainterDecorationRenderer : public DecorationRenderer class SceneQPainterDecorationRenderer : public DecorationRenderer

View file

@ -10,9 +10,7 @@
#include "shadow.h" #include "shadow.h"
// kwin // kwin
#include "atoms.h" #include "atoms.h"
#include "composite.h"
#include "internalwindow.h" #include "internalwindow.h"
#include "scene/workspacescene.h"
#include "wayland/shadow_interface.h" #include "wayland/shadow_interface.h"
#include "wayland/shmclientbuffer.h" #include "wayland/shmclientbuffer.h"
#include "wayland/surface_interface.h" #include "wayland/surface_interface.h"
@ -60,7 +58,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromX11(Window *window)
{ {
auto data = Shadow::readX11ShadowProperty(window->window()); auto data = Shadow::readX11ShadowProperty(window->window());
if (!data.isEmpty()) { if (!data.isEmpty()) {
auto shadow = Compositor::self()->scene()->createShadow(window); auto shadow = std::make_unique<Shadow>(window);
if (!shadow->init(data)) { if (!shadow->init(data)) {
return nullptr; return nullptr;
} }
@ -75,7 +73,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromDecoration(Window *window)
if (!window->decoration()) { if (!window->decoration()) {
return nullptr; return nullptr;
} }
auto shadow = Compositor::self()->scene()->createShadow(window); auto shadow = std::make_unique<Shadow>(window);
if (!shadow->init(window->decoration())) { if (!shadow->init(window->decoration())) {
return nullptr; return nullptr;
} }
@ -92,7 +90,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromWayland(Window *window)
if (!s) { if (!s) {
return nullptr; return nullptr;
} }
auto shadow = Compositor::self()->scene()->createShadow(window); auto shadow = std::make_unique<Shadow>(window);
if (!shadow->init(s)) { if (!shadow->init(s)) {
return nullptr; return nullptr;
} }
@ -109,7 +107,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromInternalWindow(Window *window)
if (!handle) { if (!handle) {
return nullptr; return nullptr;
} }
auto shadow = Compositor::self()->scene()->createShadow(window); auto shadow = std::make_unique<Shadow>(window);
if (!shadow->init(handle)) { if (!shadow->init(handle)) {
return nullptr; return nullptr;
} }
@ -170,9 +168,6 @@ bool Shadow::init(const QVector<uint32_t> &data)
data[ShadowElementsCount + 1], data[ShadowElementsCount + 1],
data[ShadowElementsCount + 2]); data[ShadowElementsCount + 2]);
Q_EMIT offsetChanged(); Q_EMIT offsetChanged();
if (!prepareBackend()) {
return false;
}
Q_EMIT textureChanged(); Q_EMIT textureChanged();
return true; return true;
} }
@ -196,9 +191,6 @@ bool Shadow::init(KDecoration2::Decoration *decoration)
m_offset = m_decorationShadow->padding(); m_offset = m_decorationShadow->padding();
Q_EMIT offsetChanged(); Q_EMIT offsetChanged();
if (!prepareBackend()) {
return false;
}
Q_EMIT textureChanged(); Q_EMIT textureChanged();
return true; return true;
} }
@ -229,9 +221,6 @@ bool Shadow::init(const QPointer<KWaylandServer::ShadowInterface> &shadow)
m_offset = shadow->offset().toMargins(); m_offset = shadow->offset().toMargins();
Q_EMIT offsetChanged(); Q_EMIT offsetChanged();
if (!prepareBackend()) {
return false;
}
Q_EMIT textureChanged(); Q_EMIT textureChanged();
return true; return true;
} }
@ -263,10 +252,6 @@ bool Shadow::init(const QWindow *window)
m_offset = window->property("kwin_shadow_padding").value<QMargins>(); m_offset = window->property("kwin_shadow_padding").value<QMargins>();
Q_EMIT offsetChanged(); Q_EMIT offsetChanged();
if (!prepareBackend()) {
return false;
}
Q_EMIT textureChanged(); Q_EMIT textureChanged();
return true; return true;
} }

View file

@ -47,6 +47,7 @@ class KWIN_EXPORT Shadow : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Shadow(Window *window);
~Shadow() override; ~Shadow() override;
/** /**
@ -58,7 +59,7 @@ public:
* delete the Shadow. * delete the Shadow.
* @returns @c true when the shadow has been updated, @c false if the property is not set anymore. * @returns @c true when the shadow has been updated, @c false if the property is not set anymore.
*/ */
virtual bool updateShadow(); bool updateShadow();
/** /**
* Factory Method to create the shadow from the property. * Factory Method to create the shadow from the property.
@ -112,6 +113,10 @@ public:
{ {
return m_offset; return m_offset;
} }
inline const QImage &shadowElement(ShadowElements element) const
{
return m_shadowElements[element];
}
Q_SIGNALS: Q_SIGNALS:
void offsetChanged(); void offsetChanged();
@ -121,16 +126,6 @@ Q_SIGNALS:
public Q_SLOTS: public Q_SLOTS:
void geometryChanged(); void geometryChanged();
protected:
Shadow(Window *window);
inline const QImage &shadowElement(ShadowElements element) const
{
return m_shadowElements[element];
};
virtual bool prepareBackend() = 0;
private: private:
static std::unique_ptr<Shadow> createShadowFromX11(Window *window); static std::unique_ptr<Shadow> createShadowFromX11(Window *window);
static std::unique_ptr<Shadow> createShadowFromDecoration(Window *window); static std::unique_ptr<Shadow> createShadowFromDecoration(Window *window);