Honor request for (no) alpha channel in SHM windows

Currently, all QWaylandShmWindows are ARGB32, even if the
application did not request an alpha channel (most toplevel
windows without client-side decoration).

Instead, create an ARGB32 or RGB32 buffer depending on whether
the surface requested an alpha channel. In order to do this,
set the red/green/blue channel of the QSurfaceFormat to 8 (since
that's all we support right now). Alpha channel is set to 8 or 0
depending on whether the surface requested alpha.

Due to client-side decorations we cannot know in advance whether we
need an alpha channel, so we have to update the surface format in
setWindowFlags.

While it doesn't particularly matter from the compositor's POV
(ARGB and XRGB are the same size and there's the opaque region
on the surface), Qt's backing store can skip certain steps in
the rendering, such as clearing the paint region before painting
when the surface is opaque.

Change-Id: I7b74f19ddb05d8ca9ae325f8fd5f42f41875cc51
Reviewed-by: David Redondo <qt@david-redondo.de>
Reviewed-by: Xaver Hugl <xaver.hugl@kde.org>
This commit is contained in:
Kai Uwe Broulik 2025-02-28 21:20:00 +01:00
parent abcea0d249
commit 12e55c95b2
3 changed files with 20 additions and 2 deletions

View File

@ -283,7 +283,9 @@ QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size, bool &b
return buffer;
if (mBuffers.size() < MAX_BUFFERS) {
QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format();
QImage::Format format = QImage::Format_ARGB32_Premultiplied;
if (!waylandWindow()->format().hasAlpha())
format = QImage::Format_RGB32;
QWaylandShmBuffer *b = new QWaylandShmBuffer(mDisplay, size, format, waylandWindow()->scale());
bufferWasRecreated = true;
mBuffers.push_front(b);

View File

@ -14,6 +14,12 @@ namespace QtWaylandClient {
QWaylandShmWindow::QWaylandShmWindow(QWindow *window, QWaylandDisplay *display)
: QWaylandWindow(window, display)
{
mSurfaceFormat.setRedBufferSize(8);
mSurfaceFormat.setGreenBufferSize(8);
mSurfaceFormat.setBlueBufferSize(8);
const QSurfaceFormat format = window->requestedFormat();
mSurfaceFormat.setAlphaBufferSize(format.hasAlpha() ? 8 : 0);
}
QWaylandShmWindow::~QWaylandShmWindow()
@ -25,6 +31,15 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
return QWaylandWindow::Shm;
}
void QWaylandShmWindow::setWindowFlags(Qt::WindowFlags flags)
{
QWaylandWindow::setWindowFlags(flags);
const QSurfaceFormat format = window()->requestedFormat();
if (!format.hasAlpha())
mSurfaceFormat.setAlphaBufferSize(mWindowDecorationEnabled ? 8 : 0);
}
}
QT_END_NAMESPACE

View File

@ -29,7 +29,8 @@ public:
~QWaylandShmWindow() override;
WindowType windowType() const override;
QSurfaceFormat format() const override { return QSurfaceFormat(); }
void setWindowFlags(Qt::WindowFlags flags) override;
};
}