Pass Decoration::Renderer to Deleted and use it in the Scenes
The Renderer gets reparented to the Deleted. While passing it to the Deleted the Scene's implementation can ensure that the buffers are up to date. After passing to Deleted it's no longer allowed to call the render method.
This commit is contained in:
parent
a9587dd19d
commit
c12199a8e0
10 changed files with 83 additions and 21 deletions
|
@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "decorationrenderer.h"
|
#include "decorationrenderer.h"
|
||||||
#include "decoratedclient.h"
|
#include "decoratedclient.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "deleted.h"
|
||||||
|
|
||||||
#include <kwinglobals.h>
|
#include <kwinglobals.h>
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ QRegion Renderer::getScheduled()
|
||||||
|
|
||||||
QImage Renderer::renderToImage(const QRect &geo)
|
QImage Renderer::renderToImage(const QRect &geo)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(m_client);
|
||||||
QImage image(geo.width(), geo.height(), QImage::Format_ARGB32_Premultiplied);
|
QImage image(geo.width(), geo.height(), QImage::Format_ARGB32_Premultiplied);
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
QPainter p(&image);
|
QPainter p(&image);
|
||||||
|
@ -73,6 +75,12 @@ QImage Renderer::renderToImage(const QRect &geo)
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::reparent(Deleted *deleted)
|
||||||
|
{
|
||||||
|
setParent(deleted);
|
||||||
|
m_client = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
X11Renderer::X11Renderer(DecoratedClientImpl *client)
|
X11Renderer::X11Renderer(DecoratedClientImpl *client)
|
||||||
: Renderer(client)
|
: Renderer(client)
|
||||||
, m_scheduleTimer(new QTimer(this))
|
, m_scheduleTimer(new QTimer(this))
|
||||||
|
|
|
@ -30,6 +30,8 @@ class QTimer;
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Deleted;
|
||||||
|
|
||||||
namespace Decoration
|
namespace Decoration
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -43,6 +45,13 @@ public:
|
||||||
|
|
||||||
void schedule(const QRect &rect);
|
void schedule(const QRect &rect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reparents this Renderer to the @p deleted.
|
||||||
|
* After this call the Renderer is no longer able to render
|
||||||
|
* anything, client() returns a nullptr.
|
||||||
|
**/
|
||||||
|
virtual void reparent(Deleted *deleted);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void renderScheduled(const QRect &geo);
|
void renderScheduled(const QRect &geo);
|
||||||
|
|
||||||
|
|
21
deleted.cpp
21
deleted.cpp
|
@ -24,6 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "netinfo.h"
|
#include "netinfo.h"
|
||||||
#include "shadow.h"
|
#include "shadow.h"
|
||||||
|
#include "decorations/decoratedclient.h"
|
||||||
|
#include "decorations/decorationrenderer.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
@ -35,14 +37,11 @@ Deleted::Deleted()
|
||||||
, delete_refcount(1)
|
, delete_refcount(1)
|
||||||
, m_frame(XCB_WINDOW_NONE)
|
, m_frame(XCB_WINDOW_NONE)
|
||||||
, no_border(true)
|
, no_border(true)
|
||||||
, padding_left(0)
|
|
||||||
, padding_top(0)
|
|
||||||
, padding_right(0)
|
|
||||||
, padding_bottom(0)
|
|
||||||
, m_layer(UnknownLayer)
|
, m_layer(UnknownLayer)
|
||||||
, m_minimized(false)
|
, m_minimized(false)
|
||||||
, m_modal(false)
|
, m_modal(false)
|
||||||
, m_wasClient(false)
|
, m_wasClient(false)
|
||||||
|
, m_decorationRenderer(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,18 +85,18 @@ void Deleted::copyToDeleted(Toplevel* c)
|
||||||
if (client) {
|
if (client) {
|
||||||
m_wasClient = true;
|
m_wasClient = true;
|
||||||
no_border = client->noBorder();
|
no_border = client->noBorder();
|
||||||
#if 0
|
|
||||||
padding_left = client->paddingLeft();
|
|
||||||
padding_right = client->paddingRight();
|
|
||||||
padding_bottom = client->paddingBottom();
|
|
||||||
padding_top = client->paddingTop();
|
|
||||||
#endif
|
|
||||||
if (!no_border) {
|
if (!no_border) {
|
||||||
client->layoutDecorationRects(decoration_left,
|
client->layoutDecorationRects(decoration_left,
|
||||||
decoration_top,
|
decoration_top,
|
||||||
decoration_right,
|
decoration_right,
|
||||||
decoration_bottom,
|
decoration_bottom,
|
||||||
Client::WindowRelative);
|
Client::WindowRelative);
|
||||||
|
if (Decoration::DecoratedClientImpl *decoClient = client->decoratedClient()) {
|
||||||
|
if (Decoration::Renderer *renderer = decoClient->renderer()) {
|
||||||
|
m_decorationRenderer = renderer;
|
||||||
|
m_decorationRenderer->reparent(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_minimized = client->isMinimized();
|
m_minimized = client->isMinimized();
|
||||||
m_modal = client->isModal();
|
m_modal = client->isModal();
|
||||||
|
@ -154,7 +153,7 @@ void Deleted::layoutDecorationRects(QRect& left, QRect& top, QRect& right, QRect
|
||||||
|
|
||||||
QRect Deleted::decorationRect() const
|
QRect Deleted::decorationRect() const
|
||||||
{
|
{
|
||||||
return rect().adjusted(-padding_left, -padding_top, padding_top, padding_bottom);
|
return rect();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect Deleted::transparentRect() const
|
QRect Deleted::transparentRect() const
|
||||||
|
|
11
deleted.h
11
deleted.h
|
@ -26,6 +26,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace Decoration
|
||||||
|
{
|
||||||
|
class Renderer;
|
||||||
|
}
|
||||||
|
|
||||||
class Deleted
|
class Deleted
|
||||||
: public Toplevel
|
: public Toplevel
|
||||||
{
|
{
|
||||||
|
@ -66,6 +71,10 @@ public:
|
||||||
bool wasClient() const {
|
bool wasClient() const {
|
||||||
return m_wasClient;
|
return m_wasClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Decoration::Renderer *decorationRenderer() const {
|
||||||
|
return m_decorationRenderer;
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
virtual void debug(QDebug& stream) const;
|
virtual void debug(QDebug& stream) const;
|
||||||
virtual bool shouldUnredirect() const;
|
virtual bool shouldUnredirect() const;
|
||||||
|
@ -88,12 +97,12 @@ private:
|
||||||
QRect decoration_right;
|
QRect decoration_right;
|
||||||
QRect decoration_top;
|
QRect decoration_top;
|
||||||
QRect decoration_bottom;
|
QRect decoration_bottom;
|
||||||
int padding_left, padding_top, padding_right, padding_bottom;
|
|
||||||
Layer m_layer;
|
Layer m_layer;
|
||||||
bool m_minimized;
|
bool m_minimized;
|
||||||
bool m_modal;
|
bool m_modal;
|
||||||
ClientList m_mainClients;
|
ClientList m_mainClients;
|
||||||
bool m_wasClient;
|
bool m_wasClient;
|
||||||
|
Decoration::Renderer *m_decorationRenderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void Deleted::refWindow()
|
inline void Deleted::refWindow()
|
||||||
|
|
|
@ -970,7 +970,6 @@ void SceneOpenGL::Window::endRenderWindow()
|
||||||
|
|
||||||
GLTexture *SceneOpenGL::Window::getDecorationTexture() const
|
GLTexture *SceneOpenGL::Window::getDecorationTexture() const
|
||||||
{
|
{
|
||||||
// TODO: deleted
|
|
||||||
if (toplevel->isClient()) {
|
if (toplevel->isClient()) {
|
||||||
Client *client = static_cast<Client *>(toplevel);
|
Client *client = static_cast<Client *>(toplevel);
|
||||||
if (client->noBorder()) {
|
if (client->noBorder()) {
|
||||||
|
@ -983,6 +982,14 @@ GLTexture *SceneOpenGL::Window::getDecorationTexture() const
|
||||||
return renderer->texture();
|
return renderer->texture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (toplevel->isDeleted()) {
|
||||||
|
Deleted *deleted = static_cast<Deleted *>(toplevel);
|
||||||
|
if (!deleted->wasClient() || deleted->noBorder()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (const SceneOpenGLDecorationRenderer *renderer = static_cast<const SceneOpenGLDecorationRenderer*>(deleted->decorationRenderer())) {
|
||||||
|
return renderer->texture();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2098,4 +2105,10 @@ void SceneOpenGLDecorationRenderer::resizeTexture()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneOpenGLDecorationRenderer::reparent(Deleted *deleted)
|
||||||
|
{
|
||||||
|
render();
|
||||||
|
Renderer::reparent(deleted);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -631,10 +631,14 @@ public:
|
||||||
virtual ~SceneOpenGLDecorationRenderer();
|
virtual ~SceneOpenGLDecorationRenderer();
|
||||||
|
|
||||||
void render() override;
|
void render() override;
|
||||||
|
void reparent(Deleted *deleted) override;
|
||||||
|
|
||||||
GLTexture *texture() {
|
GLTexture *texture() {
|
||||||
return m_texture.data();
|
return m_texture.data();
|
||||||
}
|
}
|
||||||
|
GLTexture *texture() const {
|
||||||
|
return m_texture.data();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resizeTexture();
|
void resizeTexture();
|
||||||
|
|
|
@ -443,11 +443,12 @@ void SceneQPainter::Window::renderWindowDecorations(QPainter *painter)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool noBorder = true;
|
bool noBorder = true;
|
||||||
SceneQPainterDecorationRenderer *renderer = nullptr;
|
const SceneQPainterDecorationRenderer *renderer = nullptr;
|
||||||
QRect dtr, dlr, drr, dbr;
|
QRect dtr, dlr, drr, dbr;
|
||||||
if (client && !client->noBorder()) {
|
if (client && !client->noBorder()) {
|
||||||
if (Decoration::DecoratedClientImpl *impl = client->decoratedClient()) {
|
if (Decoration::DecoratedClientImpl *impl = client->decoratedClient()) {
|
||||||
if (SceneQPainterDecorationRenderer *r = static_cast<SceneQPainterDecorationRenderer *>(impl->renderer())) {
|
if (SceneQPainterDecorationRenderer *r = static_cast<SceneQPainterDecorationRenderer *>(impl->renderer())) {
|
||||||
|
r->render();
|
||||||
renderer = r;
|
renderer = r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,15 +456,13 @@ void SceneQPainter::Window::renderWindowDecorations(QPainter *painter)
|
||||||
noBorder = false;
|
noBorder = false;
|
||||||
} else if (deleted && !deleted->noBorder()) {
|
} else if (deleted && !deleted->noBorder()) {
|
||||||
noBorder = false;
|
noBorder = false;
|
||||||
// TODO: renderer
|
|
||||||
deleted->layoutDecorationRects(dlr, dtr, drr, dbr);
|
deleted->layoutDecorationRects(dlr, dtr, drr, dbr);
|
||||||
|
renderer = static_cast<const SceneQPainterDecorationRenderer *>(deleted->decorationRenderer());
|
||||||
}
|
}
|
||||||
if (noBorder || !renderer) {
|
if (noBorder || !renderer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->render();
|
|
||||||
|
|
||||||
painter->drawImage(dtr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Top));
|
painter->drawImage(dtr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Top));
|
||||||
painter->drawImage(dlr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Left));
|
painter->drawImage(dlr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Left));
|
||||||
painter->drawImage(drr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Right));
|
painter->drawImage(drr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Right));
|
||||||
|
@ -692,4 +691,10 @@ void SceneQPainterDecorationRenderer::resizeImages()
|
||||||
checkAndCreate(int(DecorationPart::Bottom), bottom.size());
|
checkAndCreate(int(DecorationPart::Bottom), bottom.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneQPainterDecorationRenderer::reparent(Deleted *deleted)
|
||||||
|
{
|
||||||
|
render();
|
||||||
|
Renderer::reparent(deleted);
|
||||||
|
}
|
||||||
|
|
||||||
} // KWin
|
} // KWin
|
||||||
|
|
|
@ -245,6 +245,7 @@ public:
|
||||||
virtual ~SceneQPainterDecorationRenderer();
|
virtual ~SceneQPainterDecorationRenderer();
|
||||||
|
|
||||||
void render() override;
|
void render() override;
|
||||||
|
void reparent(Deleted *deleted) override;
|
||||||
|
|
||||||
QImage image(DecorationPart part) const;
|
QImage image(DecorationPart part) const;
|
||||||
|
|
||||||
|
|
|
@ -722,19 +722,26 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat
|
||||||
xcb_render_picture_t right = XCB_RENDER_PICTURE_NONE;
|
xcb_render_picture_t right = XCB_RENDER_PICTURE_NONE;
|
||||||
xcb_render_picture_t bottom = XCB_RENDER_PICTURE_NONE;
|
xcb_render_picture_t bottom = XCB_RENDER_PICTURE_NONE;
|
||||||
QRect dtr, dlr, drr, dbr;
|
QRect dtr, dlr, drr, dbr;
|
||||||
SceneXRenderDecorationRenderer *renderer = nullptr;
|
const SceneXRenderDecorationRenderer *renderer = nullptr;
|
||||||
// TODO: deleted
|
|
||||||
if (client) {
|
if (client) {
|
||||||
if (client && !client->noBorder()) {
|
if (client && !client->noBorder()) {
|
||||||
if (Decoration::DecoratedClientImpl *impl = client->decoratedClient()) {
|
if (Decoration::DecoratedClientImpl *impl = client->decoratedClient()) {
|
||||||
renderer = static_cast<SceneXRenderDecorationRenderer*>(impl->renderer());
|
SceneXRenderDecorationRenderer *r = static_cast<SceneXRenderDecorationRenderer*>(impl->renderer());
|
||||||
|
if (r) {
|
||||||
|
r->render();
|
||||||
|
renderer = r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
noBorder = client->noBorder();
|
noBorder = client->noBorder();
|
||||||
client->layoutDecorationRects(dlr, dtr, drr, dbr, Client::WindowRelative);
|
client->layoutDecorationRects(dlr, dtr, drr, dbr, Client::WindowRelative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (deleted && !deleted->noBorder()) {
|
||||||
|
renderer = static_cast<const SceneXRenderDecorationRenderer*>(deleted->decorationRenderer());
|
||||||
|
noBorder = deleted->noBorder();
|
||||||
|
deleted->layoutDecorationRects(dlr, dtr, drr, dbr, Client::WindowRelative);
|
||||||
|
}
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
renderer->render();
|
|
||||||
left = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Left);
|
left = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Left);
|
||||||
top = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Top);
|
top = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Top);
|
||||||
right = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Right);
|
right = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Right);
|
||||||
|
@ -1415,6 +1422,12 @@ xcb_render_picture_t SceneXRenderDecorationRenderer::picture(SceneXRenderDecorat
|
||||||
return *picture;
|
return *picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneXRenderDecorationRenderer::reparent(Deleted *deleted)
|
||||||
|
{
|
||||||
|
render();
|
||||||
|
Renderer::reparent(deleted);
|
||||||
|
}
|
||||||
|
|
||||||
#undef DOUBLE_TO_FIXED
|
#undef DOUBLE_TO_FIXED
|
||||||
#undef FIXED_TO_DOUBLE
|
#undef FIXED_TO_DOUBLE
|
||||||
|
|
||||||
|
|
|
@ -354,6 +354,7 @@ public:
|
||||||
virtual ~SceneXRenderDecorationRenderer();
|
virtual ~SceneXRenderDecorationRenderer();
|
||||||
|
|
||||||
void render() override;
|
void render() override;
|
||||||
|
void reparent(Deleted *deleted) override;
|
||||||
|
|
||||||
xcb_render_picture_t picture(DecorationPart part) const;
|
xcb_render_picture_t picture(DecorationPart part) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue