Merge the code to render Client's and Deleted's decoration in SceneOpenGL

The code was basically copy'n'pasted to handle both Client and Deleted
requiring to cast the Toplevel to both Client and Deleted to test whether
it is one of those.

This is now changed from runtime to compile time polymorphism. A
templated method is used to start the rendering process for the decos.
This on the one hand simplifies the code and on the other does not
require any dynamic casts any more as we use the available check on
Toplevel whether it is a Client or Deleted.
This commit is contained in:
Martin Gräßlin 2012-09-06 12:55:15 +02:00
parent fe440377bb
commit db9368fc26
4 changed files with 58 additions and 61 deletions

View file

@ -134,7 +134,7 @@ void Deleted::debug(QDebug& stream) const
stream << "\'ID:" << window() << "\' (deleted)";
}
void Deleted::layoutDecorationRects(QRect& left, QRect& top, QRect& right, QRect& bottom) const
void Deleted::layoutDecorationRects(QRect& left, QRect& top, QRect& right, QRect& bottom, int) const
{
left = decoration_left;
top = decoration_top;

View file

@ -58,7 +58,7 @@ public:
bool noBorder() const {
return no_border;
}
void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const;
void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom, int unused = 0) const;
QRect decorationRect() const;
virtual Layer layer() const {
return m_layer;
@ -67,6 +67,10 @@ public:
return m_minimized;
}
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
bool decorationPixmapRequiresRepaint() const {
return false;
}
void ensureDecorationPixmapsPainted() {}
protected:
virtual void debug(QDebug& stream) const;
virtual bool shouldUnredirect() const;

View file

@ -720,8 +720,6 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData
beginRenderWindow(mask, data);
WindowQuadList decoration = data.quads.select(WindowQuadDecoration);
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
vbo->reset();
@ -730,63 +728,10 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData
paintShadow(region, data, hardwareClipping);
}
// decorations
Client *client = dynamic_cast<Client*>(toplevel);
Deleted *deleted = dynamic_cast<Deleted*>(toplevel);
if (client || deleted) {
bool noBorder = true;
bool updateDeco = false;
const QPixmap *left = NULL;
const QPixmap *top = NULL;
const QPixmap *right = NULL;
const QPixmap *bottom = NULL;
QRect topRect, leftRect, rightRect, bottomRect;
if (client && !client->noBorder()) {
noBorder = false;
updateDeco = client->decorationPixmapRequiresRepaint();
client->ensureDecorationPixmapsPainted();
client->layoutDecorationRects(leftRect, topRect, rightRect, bottomRect, Client::WindowRelative);
left = client->leftDecoPixmap();
top = client->topDecoPixmap();
right = client->rightDecoPixmap();
bottom = client->bottomDecoPixmap();
}
if (deleted && !deleted->noBorder()) {
noBorder = false;
left = deleted->leftDecoPixmap();
top = deleted->topDecoPixmap();
right = deleted->rightDecoPixmap();
bottom = deleted->bottomDecoPixmap();
deleted->layoutDecorationRects(leftRect, topRect, rightRect, bottomRect);
}
if (!noBorder) {
WindowQuadList topList, leftList, rightList, bottomList;
foreach (const WindowQuad & quad, decoration) {
if (topRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
topList.append(quad);
continue;
}
if (bottomRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
bottomList.append(quad);
continue;
}
if (leftRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
leftList.append(quad);
continue;
}
if (rightRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
rightList.append(quad);
continue;
}
}
paintDecoration(top, DecorationTop, region, topRect, data, topList, updateDeco, hardwareClipping);
paintDecoration(left, DecorationLeft, region, leftRect, data, leftList, updateDeco, hardwareClipping);
paintDecoration(right, DecorationRight, region, rightRect, data, rightList, updateDeco, hardwareClipping);
paintDecoration(bottom, DecorationBottom, region, bottomRect, data, bottomList, updateDeco, hardwareClipping);
}
if (toplevel->isClient()) {
paintDecorations<Client>(data, region, hardwareClipping);
} else if (toplevel->isDeleted()) {
paintDecorations<Deleted>(data, region, hardwareClipping);
}
// paint the content
@ -813,6 +758,52 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData
endRenderWindow(data);
}
template<class T>
void SceneOpenGL::Window::paintDecorations(const WindowPaintData &data, const QRegion &region, bool hardwareClipping)
{
T* t = static_cast<T*>(toplevel);
if (t->noBorder()) {
return;
}
WindowQuadList decoration = data.quads.select(WindowQuadDecoration);
QRect topRect, leftRect, rightRect, bottomRect;
const bool updateDeco = t->decorationPixmapRequiresRepaint();
t->ensureDecorationPixmapsPainted();
t->layoutDecorationRects(leftRect, topRect, rightRect, bottomRect, Client::WindowRelative);
const QPixmap *left = t->leftDecoPixmap();
const QPixmap *top = t->topDecoPixmap();
const QPixmap *right = t->rightDecoPixmap();
const QPixmap *bottom = t->bottomDecoPixmap();
WindowQuadList topList, leftList, rightList, bottomList;
foreach (const WindowQuad & quad, decoration) {
if (topRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
topList.append(quad);
continue;
}
if (bottomRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
bottomList.append(quad);
continue;
}
if (leftRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
leftList.append(quad);
continue;
}
if (rightRect.contains(QPoint(quad.originalLeft(), quad.originalTop()))) {
rightList.append(quad);
continue;
}
}
paintDecoration(top, DecorationTop, region, topRect, data, topList, updateDeco, hardwareClipping);
paintDecoration(left, DecorationLeft, region, leftRect, data, leftList, updateDeco, hardwareClipping);
paintDecoration(right, DecorationRight, region, rightRect, data, rightList, updateDeco, hardwareClipping);
paintDecoration(bottom, DecorationBottom, region, bottomRect, data, bottomList, updateDeco, hardwareClipping);
}
void SceneOpenGL::Window::paintDecoration(const QPixmap* decoration, TextureType decorationType,
const QRegion& region, const QRect& rect, const WindowPaintData& data,
const WindowQuadList& quads, bool updateDeco, bool hardwareClipping)

View file

@ -212,6 +212,8 @@ protected:
GLTexture *textureForType(TextureType type);
private:
template<class T>
void paintDecorations(const WindowPaintData &data, const QRegion &region, bool hardwareClipping);
Texture *texture;
Texture *topTexture;
Texture *leftTexture;