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:
parent
21d410710c
commit
0e906ec182
10 changed files with 122 additions and 119 deletions
|
@ -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(),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ®ion) override;
|
void paint(RenderTarget *renderTarget, const QRegion ®ion) 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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
//****************************************
|
//****************************************
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
17
src/shadow.h
17
src/shadow.h
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue