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.
icc-effect-5.14.5
Martin Gräßlin 2014-07-23 09:20:28 +02:00
parent a9587dd19d
commit c12199a8e0
10 changed files with 83 additions and 21 deletions

View File

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "decorationrenderer.h"
#include "decoratedclient.h"
#include "client.h"
#include "deleted.h"
#include <kwinglobals.h>
@ -63,6 +64,7 @@ QRegion Renderer::getScheduled()
QImage Renderer::renderToImage(const QRect &geo)
{
Q_ASSERT(m_client);
QImage image(geo.width(), geo.height(), QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::transparent);
QPainter p(&image);
@ -73,6 +75,12 @@ QImage Renderer::renderToImage(const QRect &geo)
return image;
}
void Renderer::reparent(Deleted *deleted)
{
setParent(deleted);
m_client = nullptr;
}
X11Renderer::X11Renderer(DecoratedClientImpl *client)
: Renderer(client)
, m_scheduleTimer(new QTimer(this))

View File

@ -30,6 +30,8 @@ class QTimer;
namespace KWin
{
class Deleted;
namespace Decoration
{
@ -43,6 +45,13 @@ public:
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:
void renderScheduled(const QRect &geo);

View File

@ -24,6 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "client.h"
#include "netinfo.h"
#include "shadow.h"
#include "decorations/decoratedclient.h"
#include "decorations/decorationrenderer.h"
#include <QDebug>
@ -35,14 +37,11 @@ Deleted::Deleted()
, delete_refcount(1)
, m_frame(XCB_WINDOW_NONE)
, no_border(true)
, padding_left(0)
, padding_top(0)
, padding_right(0)
, padding_bottom(0)
, m_layer(UnknownLayer)
, m_minimized(false)
, m_modal(false)
, m_wasClient(false)
, m_decorationRenderer(nullptr)
{
}
@ -86,18 +85,18 @@ void Deleted::copyToDeleted(Toplevel* c)
if (client) {
m_wasClient = true;
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) {
client->layoutDecorationRects(decoration_left,
decoration_top,
decoration_right,
decoration_bottom,
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_modal = client->isModal();
@ -154,7 +153,7 @@ void Deleted::layoutDecorationRects(QRect& left, QRect& top, QRect& right, QRect
QRect Deleted::decorationRect() const
{
return rect().adjusted(-padding_left, -padding_top, padding_top, padding_bottom);
return rect();
}
QRect Deleted::transparentRect() const

View File

@ -26,6 +26,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin
{
namespace Decoration
{
class Renderer;
}
class Deleted
: public Toplevel
{
@ -66,6 +71,10 @@ public:
bool wasClient() const {
return m_wasClient;
}
const Decoration::Renderer *decorationRenderer() const {
return m_decorationRenderer;
}
protected:
virtual void debug(QDebug& stream) const;
virtual bool shouldUnredirect() const;
@ -88,12 +97,12 @@ private:
QRect decoration_right;
QRect decoration_top;
QRect decoration_bottom;
int padding_left, padding_top, padding_right, padding_bottom;
Layer m_layer;
bool m_minimized;
bool m_modal;
ClientList m_mainClients;
bool m_wasClient;
Decoration::Renderer *m_decorationRenderer;
};
inline void Deleted::refWindow()

View File

@ -970,7 +970,6 @@ void SceneOpenGL::Window::endRenderWindow()
GLTexture *SceneOpenGL::Window::getDecorationTexture() const
{
// TODO: deleted
if (toplevel->isClient()) {
Client *client = static_cast<Client *>(toplevel);
if (client->noBorder()) {
@ -983,6 +982,14 @@ GLTexture *SceneOpenGL::Window::getDecorationTexture() const
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;
}
@ -2098,4 +2105,10 @@ void SceneOpenGLDecorationRenderer::resizeTexture()
}
}
void SceneOpenGLDecorationRenderer::reparent(Deleted *deleted)
{
render();
Renderer::reparent(deleted);
}
} // namespace

View File

@ -631,10 +631,14 @@ public:
virtual ~SceneOpenGLDecorationRenderer();
void render() override;
void reparent(Deleted *deleted) override;
GLTexture *texture() {
return m_texture.data();
}
GLTexture *texture() const {
return m_texture.data();
}
private:
void resizeTexture();

View File

@ -443,11 +443,12 @@ void SceneQPainter::Window::renderWindowDecorations(QPainter *painter)
}
bool noBorder = true;
SceneQPainterDecorationRenderer *renderer = nullptr;
const SceneQPainterDecorationRenderer *renderer = nullptr;
QRect dtr, dlr, drr, dbr;
if (client && !client->noBorder()) {
if (Decoration::DecoratedClientImpl *impl = client->decoratedClient()) {
if (SceneQPainterDecorationRenderer *r = static_cast<SceneQPainterDecorationRenderer *>(impl->renderer())) {
r->render();
renderer = r;
}
}
@ -455,15 +456,13 @@ void SceneQPainter::Window::renderWindowDecorations(QPainter *painter)
noBorder = false;
} else if (deleted && !deleted->noBorder()) {
noBorder = false;
// TODO: renderer
deleted->layoutDecorationRects(dlr, dtr, drr, dbr);
renderer = static_cast<const SceneQPainterDecorationRenderer *>(deleted->decorationRenderer());
}
if (noBorder || !renderer) {
return;
}
renderer->render();
painter->drawImage(dtr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Top));
painter->drawImage(dlr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Left));
painter->drawImage(drr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Right));
@ -692,4 +691,10 @@ void SceneQPainterDecorationRenderer::resizeImages()
checkAndCreate(int(DecorationPart::Bottom), bottom.size());
}
void SceneQPainterDecorationRenderer::reparent(Deleted *deleted)
{
render();
Renderer::reparent(deleted);
}
} // KWin

View File

@ -245,6 +245,7 @@ public:
virtual ~SceneQPainterDecorationRenderer();
void render() override;
void reparent(Deleted *deleted) override;
QImage image(DecorationPart part) const;

View File

@ -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 bottom = XCB_RENDER_PICTURE_NONE;
QRect dtr, dlr, drr, dbr;
SceneXRenderDecorationRenderer *renderer = nullptr;
// TODO: deleted
const SceneXRenderDecorationRenderer *renderer = nullptr;
if (client) {
if (client && !client->noBorder()) {
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();
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) {
renderer->render();
left = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Left);
top = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Top);
right = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Right);
@ -1415,6 +1422,12 @@ xcb_render_picture_t SceneXRenderDecorationRenderer::picture(SceneXRenderDecorat
return *picture;
}
void SceneXRenderDecorationRenderer::reparent(Deleted *deleted)
{
render();
Renderer::reparent(deleted);
}
#undef DOUBLE_TO_FIXED
#undef FIXED_TO_DOUBLE

View File

@ -354,6 +354,7 @@ public:
virtual ~SceneXRenderDecorationRenderer();
void render() override;
void reparent(Deleted *deleted) override;
xcb_render_picture_t picture(DecorationPart part) const;