community/kwin: apply fix for the Librem 5

The Librem 5 is currently broken with Plasma. Interestingly enough the
device reports 3 displays even though it really only as 2 (internal and
USB-C out) and KWin picks the wrong. Then it tries to do a buffer copy
between... the same device...

This patch makes KWin use the right display. Figured out on Akademy with
a KWin dev, yay for conferences!
This commit is contained in:
Bart Ribbers 2024-09-10 12:10:54 +02:00
parent 49d3c2bc05
commit 74d0088968
2 changed files with 130 additions and 2 deletions

View File

@ -0,0 +1,125 @@
From 829c0b2ed51e210843b12146709fd5f092941f99 Mon Sep 17 00:00:00 2001
From: Xaver Hugl <xaver.hugl@gmail.com>
Date: Tue, 10 Sep 2024 11:47:39 +0200
Subject: [PATCH] backends/drm: don't do multi gpu copies if we'd copy from and
to the same render device
Some hardware has multiple display devices but only one render device; doing a copy in that
case reduces performance for no reason.
---
src/backends/drm/drm_egl_layer_surface.cpp | 7 ++++
src/opengl/egldisplay.cpp | 48 ++++++++++++----------
src/opengl/egldisplay.h | 2 +
3 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/src/backends/drm/drm_egl_layer_surface.cpp b/src/backends/drm/drm_egl_layer_surface.cpp
index 372f0610f05..73bea02cfbc 100644
--- a/src/backends/drm/drm_egl_layer_surface.cpp
+++ b/src/backends/drm/drm_egl_layer_surface.cpp
@@ -407,6 +407,13 @@ std::unique_ptr<EglGbmLayerSurface::Surface> EglGbmLayerSurface::createSurface(c
if (m_gpu == m_eglBackend->gpu()) {
return doTestFormats(formats, MultiGpuImportMode::None);
}
+ // special case, we're using different display devices but the same render device
+ const auto display = m_eglBackend->displayForGpu(m_gpu);
+ if (display && display->renderNode() == m_eglBackend->eglDisplayObject()->renderNode()) {
+ if (auto surface = doTestFormats(formats, MultiGpuImportMode::None)) {
+ return surface;
+ }
+ }
if (auto surface = doTestFormats(formats, MultiGpuImportMode::Egl)) {
qCDebug(KWIN_DRM) << "chose egl import with format" << formatName(surface->gbmSwapchain->format()).name << "and modifier" << surface->gbmSwapchain->modifier();
return surface;
diff --git a/src/opengl/egldisplay.cpp b/src/opengl/egldisplay.cpp
index b4e9a54b97c..50b0f11b369 100644
--- a/src/opengl/egldisplay.cpp
+++ b/src/opengl/egldisplay.cpp
@@ -77,6 +77,7 @@ EglDisplay::EglDisplay(::EGLDisplay display, const QList<QByteArray> &extensions
: m_handle(display)
, m_extensions(extensions)
, m_owning(owning)
+ , m_renderNode(getRenderNode())
, m_supportsBufferAge(extensions.contains(QByteArrayLiteral("EGL_EXT_buffer_age")) && qgetenv("KWIN_USE_BUFFER_AGE") != "0")
, m_supportsNativeFence(extensions.contains(QByteArrayLiteral("EGL_ANDROID_native_fence_sync")))
{
@@ -135,27 +136,7 @@ static bool checkExtension(const QByteArrayView extensions, const QByteArrayView
QString EglDisplay::renderNode() const
{
- const char *clientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
- if (checkExtension(clientExtensions, "EGL_EXT_device_query")) {
- EGLAttrib eglDeviceAttrib;
- if (eglQueryDisplayAttribEXT(m_handle, EGL_DEVICE_EXT, &eglDeviceAttrib)) {
- EGLDeviceEXT eglDevice = reinterpret_cast<EGLDeviceEXT>(eglDeviceAttrib);
-
- const char *deviceExtensions = eglQueryDeviceStringEXT(eglDevice, EGL_EXTENSIONS);
- if (checkExtension(deviceExtensions, "EGL_EXT_device_drm_render_node")) {
- if (const char *node = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_RENDER_NODE_FILE_EXT)) {
- return QString::fromLocal8Bit(node);
- }
- }
- if (checkExtension(deviceExtensions, "EGL_EXT_device_drm")) {
- // Fallback to display device.
- if (const char *node = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_DEVICE_FILE_EXT)) {
- return QString::fromLocal8Bit(node);
- }
- }
- }
- }
- return QString();
+ return m_renderNode;
}
bool EglDisplay::supportsBufferAge() const
@@ -328,6 +309,31 @@ QHash<uint32_t, EglDisplay::DrmFormatInfo> EglDisplay::queryImportFormats() cons
return ret;
}
+QString EglDisplay::getRenderNode() const
+{
+ const char *clientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (checkExtension(clientExtensions, "EGL_EXT_device_query")) {
+ EGLAttrib eglDeviceAttrib;
+ if (eglQueryDisplayAttribEXT(m_handle, EGL_DEVICE_EXT, &eglDeviceAttrib)) {
+ EGLDeviceEXT eglDevice = reinterpret_cast<EGLDeviceEXT>(eglDeviceAttrib);
+
+ const char *deviceExtensions = eglQueryDeviceStringEXT(eglDevice, EGL_EXTENSIONS);
+ if (checkExtension(deviceExtensions, "EGL_EXT_device_drm_render_node")) {
+ if (const char *node = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_RENDER_NODE_FILE_EXT)) {
+ return QString::fromLocal8Bit(node);
+ }
+ }
+ if (checkExtension(deviceExtensions, "EGL_EXT_device_drm")) {
+ // Fallback to display device.
+ if (const char *node = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_DEVICE_FILE_EXT)) {
+ return QString::fromLocal8Bit(node);
+ }
+ }
+ }
+ }
+ return QString();
+}
+
EGLImageKHR EglDisplay::createImage(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) const
{
Q_ASSERT(m_functions.createImageKHR);
diff --git a/src/opengl/egldisplay.h b/src/opengl/egldisplay.h
index c439f4ff3fc..d4858be5a71 100644
--- a/src/opengl/egldisplay.h
+++ b/src/opengl/egldisplay.h
@@ -59,10 +59,12 @@ public:
private:
QHash<uint32_t, DrmFormatInfo> queryImportFormats() const;
+ QString getRenderNode() const;
const ::EGLDisplay m_handle;
const QList<QByteArray> m_extensions;
const bool m_owning;
+ const QString m_renderNode;
const bool m_supportsBufferAge;
const bool m_supportsNativeFence;
--
GitLab

View File

@ -5,7 +5,7 @@
# group=kde-plasma
pkgname=kwin
pkgver=6.1.4
pkgrel=0
pkgrel=1
pkgdesc="An easy to use, but flexible, composited Window Manager"
# armhf blocked by qt6-qtdeclarative
arch="all !armhf"
@ -102,7 +102,9 @@ case "$pkgver" in
esac
_repo_url="https://invent.kde.org/plasma/kwin.git"
source="https://download.kde.org/stable/plasma/$_pkgver/kwin-$pkgver.tar.xz"
source="https://download.kde.org/stable/plasma/$_pkgver/kwin-$pkgver.tar.xz
0001-Fix-librem5.patch
"
# Broken, fails to setup due to missing or invalid XDG_RUNTIME_DIR?
options="!check"
@ -130,4 +132,5 @@ package() {
}
sha512sums="
f7d512e633ec153f19b2f76f781d67a6c5f9b97df81205cf6e3cca227185b2764ffa612f0d1c0a528a37964dfcf3c6ac060c062ae8d653997057555cfd477090 kwin-6.1.4.tar.xz
2052b547e0623d7a6aaeb449e584f2fdc7da9570759256a9ca91f30c79c5d36a13845d2dca29b090eecbfd4efa56580a67d33a3b9e3232c5e8c8d27841850e95 0001-Fix-librem5.patch
"