From 12e55c95b23c766f9b968597fcf651173e78944c Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Fri, 28 Feb 2025 21:20:00 +0100 Subject: [PATCH] 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 Reviewed-by: Xaver Hugl --- .../platforms/wayland/qwaylandshmbackingstore.cpp | 4 +++- .../platforms/wayland/qwaylandshmwindow.cpp | 15 +++++++++++++++ .../platforms/wayland/qwaylandshmwindow_p.h | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index 1abd6808bbc..a0265bdc338 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -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); diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp index 8fecad178bd..10c90d1c157 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp @@ -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 diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow_p.h b/src/plugins/platforms/wayland/qwaylandshmwindow_p.h index f11df5e4767..dab9e1e5350 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandshmwindow_p.h @@ -29,7 +29,8 @@ public: ~QWaylandShmWindow() override; WindowType windowType() const override; - QSurfaceFormat format() const override { return QSurfaceFormat(); } + + void setWindowFlags(Qt::WindowFlags flags) override; }; }