Store shadow elements as QImages

At quick glance, it doesn't seem like there's any benefit from storing
the shadow elements as pixmaps. It saves us some QImage <-> QPixmap
conversions too.
This commit is contained in:
Vlad Zahorodnii 2023-01-17 20:31:53 +02:00
parent be7083eb46
commit 7c58f169e0
3 changed files with 31 additions and 38 deletions

View file

@ -190,14 +190,14 @@ bool SceneOpenGLShadow::prepareBackend()
return true;
}
const QSize top(shadowPixmap(ShadowElementTop).size());
const QSize topRight(shadowPixmap(ShadowElementTopRight).size());
const QSize right(shadowPixmap(ShadowElementRight).size());
const QSize bottom(shadowPixmap(ShadowElementBottom).size());
const QSize bottomLeft(shadowPixmap(ShadowElementBottomLeft).size());
const QSize left(shadowPixmap(ShadowElementLeft).size());
const QSize topLeft(shadowPixmap(ShadowElementTopLeft).size());
const QSize bottomRight(shadowPixmap(ShadowElementBottomRight).size());
const QSize top(shadowElement(ShadowElementTop).size());
const QSize topRight(shadowElement(ShadowElementTopRight).size());
const QSize right(shadowElement(ShadowElementRight).size());
const QSize bottom(shadowElement(ShadowElementBottom).size());
const QSize bottomLeft(shadowElement(ShadowElementBottomLeft).size());
const QSize left(shadowElement(ShadowElementLeft).size());
const QSize topLeft(shadowElement(ShadowElementTopLeft).size());
const QSize bottomRight(shadowElement(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 height = std::max({topLeft.height(), top.height(), topRight.height()}) + std::max(left.height(), right.height()) + std::max({bottomLeft.height(), bottom.height(), bottomRight.height()});
@ -215,16 +215,16 @@ bool SceneOpenGLShadow::prepareBackend()
QPainter p;
p.begin(&image);
p.drawPixmap(0, 0, topLeft.width(), topLeft.height(), shadowPixmap(ShadowElementTopLeft));
p.drawPixmap(innerRectLeft, 0, top.width(), top.height(), shadowPixmap(ShadowElementTop));
p.drawPixmap(width - topRight.width(), 0, topRight.width(), topRight.height(), shadowPixmap(ShadowElementTopRight));
p.drawImage(QRectF(0, 0, topLeft.width(), topLeft.height()), shadowElement(ShadowElementTopLeft));
p.drawImage(QRectF(innerRectLeft, 0, top.width(), top.height()), shadowElement(ShadowElementTop));
p.drawImage(QRectF(width - topRight.width(), 0, topRight.width(), topRight.height()), shadowElement(ShadowElementTopRight));
p.drawPixmap(0, innerRectTop, left.width(), left.height(), shadowPixmap(ShadowElementLeft));
p.drawPixmap(width - right.width(), innerRectTop, right.width(), right.height(), shadowPixmap(ShadowElementRight));
p.drawImage(QRectF(0, innerRectTop, left.width(), left.height()), shadowElement(ShadowElementLeft));
p.drawImage(QRectF(width - right.width(), innerRectTop, right.width(), right.height()), shadowElement(ShadowElementRight));
p.drawPixmap(0, height - bottomLeft.height(), bottomLeft.width(), bottomLeft.height(), shadowPixmap(ShadowElementBottomLeft));
p.drawPixmap(innerRectLeft, height - bottom.height(), bottom.width(), bottom.height(), shadowPixmap(ShadowElementBottom));
p.drawPixmap(width - bottomRight.width(), height - bottomRight.height(), bottomRight.width(), bottomRight.height(), shadowPixmap(ShadowElementBottomRight));
p.drawImage(QRectF(0, height - bottomLeft.height(), bottomLeft.width(), bottomLeft.height()), shadowElement(ShadowElementBottomLeft));
p.drawImage(QRectF(innerRectLeft, height - bottom.height(), bottom.width(), bottom.height()), shadowElement(ShadowElementBottom));
p.drawImage(QRectF(width - bottomRight.width(), height - bottomRight.height(), bottomRight.width(), bottomRight.height()), shadowElement(ShadowElementBottomRight));
p.end();

View file

@ -162,7 +162,7 @@ bool Shadow::init(const QVector<uint32_t> &data)
}
auto &geo = pixmapGeometries[i];
QImage image(xcb_get_image_data(reply), geo->width, geo->height, QImage::Format_ARGB32);
m_shadowElements[i] = QPixmap::fromImage(image);
m_shadowElements[i] = image.copy();
free(reply);
}
m_offset = QMargins(data[ShadowElementsCount + 3],
@ -203,13 +203,13 @@ bool Shadow::init(KDecoration2::Decoration *decoration)
return true;
}
static QPixmap shadowTileForBuffer(KWaylandServer::ClientBuffer *buffer)
static QImage shadowTileForBuffer(KWaylandServer::ClientBuffer *buffer)
{
auto shmBuffer = qobject_cast<KWaylandServer::ShmClientBuffer *>(buffer);
if (shmBuffer) {
return QPixmap::fromImage(shmBuffer->data().copy());
return shmBuffer->data().copy();
}
return QPixmap();
return QImage();
}
bool Shadow::init(const QPointer<KWaylandServer::ShadowInterface> &shadow)
@ -252,14 +252,14 @@ bool Shadow::init(const QWindow *window)
const QImage bottomTile = window->property("kwin_shadow_bottom_tile").value<QImage>();
const QImage bottomLeftTile = window->property("kwin_shadow_bottom_left_tile").value<QImage>();
m_shadowElements[ShadowElementLeft] = QPixmap::fromImage(leftTile);
m_shadowElements[ShadowElementTopLeft] = QPixmap::fromImage(topLeftTile);
m_shadowElements[ShadowElementTop] = QPixmap::fromImage(topTile);
m_shadowElements[ShadowElementTopRight] = QPixmap::fromImage(topRightTile);
m_shadowElements[ShadowElementRight] = QPixmap::fromImage(rightTile);
m_shadowElements[ShadowElementBottomRight] = QPixmap::fromImage(bottomRightTile);
m_shadowElements[ShadowElementBottom] = QPixmap::fromImage(bottomTile);
m_shadowElements[ShadowElementBottomLeft] = QPixmap::fromImage(bottomLeftTile);
m_shadowElements[ShadowElementLeft] = leftTile;
m_shadowElements[ShadowElementTopLeft] = topLeftTile;
m_shadowElements[ShadowElementTop] = topTile;
m_shadowElements[ShadowElementTopRight] = topRightTile;
m_shadowElements[ShadowElementRight] = rightTile;
m_shadowElements[ShadowElementBottomRight] = bottomRightTile;
m_shadowElements[ShadowElementBottom] = bottomTile;
m_shadowElements[ShadowElementBottomLeft] = bottomLeftTile;
m_offset = window->property("kwin_shadow_padding").value<QMargins>();
Q_EMIT offsetChanged();
@ -369,9 +369,4 @@ QSize Shadow::elementSize(Shadow::ShadowElements element) const
}
}
void Shadow::setShadowElement(const QPixmap &shadow, Shadow::ShadowElements element)
{
m_shadowElements[element] = shadow;
}
} // namespace

View file

@ -10,7 +10,6 @@
#pragma once
#include <QObject>
#include <QPixmap>
#include <kwineffects.h>
namespace KDecoration2
@ -125,13 +124,12 @@ public Q_SLOTS:
protected:
Shadow(Window *window);
inline const QPixmap &shadowPixmap(ShadowElements element) const
inline const QImage &shadowElement(ShadowElements element) const
{
return m_shadowElements[element];
};
virtual bool prepareBackend() = 0;
void setShadowElement(const QPixmap &shadow, ShadowElements element);
private:
static std::unique_ptr<Shadow> createShadowFromX11(Window *window);
@ -144,8 +142,8 @@ private:
bool init(const QPointer<KWaylandServer::ShadowInterface> &shadow);
bool init(const QWindow *window);
Window *m_window;
// shadow pixmaps
QPixmap m_shadowElements[ShadowElementsCount];
// shadow elements
QImage m_shadowElements[ShadowElementsCount];
// shadow offsets
QMargins m_offset;
// caches