From 5c93c4251b8d93add87384ec5c1cf0edda9b467e Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Fri, 26 Apr 2024 11:15:18 +0300 Subject: [PATCH] Fix scanout device information when running nested kwin Without it, there are issues with running Xwayland. --- src/backends/drm/drm_egl_backend.cpp | 3 +- .../scenes/opengl/abstract_egl_backend.cpp | 138 +++++++++--------- .../scenes/opengl/abstract_egl_backend.h | 4 +- 3 files changed, 69 insertions(+), 76 deletions(-) diff --git a/src/backends/drm/drm_egl_backend.cpp b/src/backends/drm/drm_egl_backend.cpp index 5665c68825..07cc3e7b15 100644 --- a/src/backends/drm/drm_egl_backend.cpp +++ b/src/backends/drm/drm_egl_backend.cpp @@ -28,8 +28,7 @@ namespace KWin { EglGbmBackend::EglGbmBackend(DrmBackend *drmBackend) - : AbstractEglBackend(drmBackend->primaryGpu()->drmDevice()->deviceId()) - , m_backend(drmBackend) + : m_backend(drmBackend) { drmBackend->setRenderBackend(this); connect(m_backend, &DrmBackend::gpuRemoved, this, [this](DrmGpu *gpu) { diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index 8ddad824c2..a60ba104d0 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -8,6 +8,7 @@ */ #include "platformsupport/scenes/opengl/abstract_egl_backend.h" #include "compositor.h" +#include "core/drmdevice.h" #include "core/outputbackend.h" #include "main.h" #include "opengl/egl_context_attribute_builder.h" @@ -34,8 +35,7 @@ namespace KWin static std::unique_ptr s_globalShareContext; -AbstractEglBackend::AbstractEglBackend(dev_t deviceId) - : m_deviceId(deviceId) +AbstractEglBackend::AbstractEglBackend() { connect(Compositor::self(), &Compositor::aboutToDestroy, this, &AbstractEglBackend::teardown); } @@ -100,11 +100,11 @@ void AbstractEglBackend::initWayland() return; } - if (m_deviceId) { + if (DrmDevice *scanoutDevice = drmDevice()) { QString renderNode = m_display->renderNode(); if (renderNode.isEmpty()) { ::drmDevice *device = nullptr; - if (drmGetDeviceFromDevId(deviceId(), 0, &device) != 0) { + if (drmGetDeviceFromDevId(scanoutDevice->deviceId(), 0, &device) != 0) { qCWarning(KWIN_OPENGL) << "drmGetDeviceFromDevId() failed:" << strerror(errno); } else { if (device->available_nodes & (1 << DRM_NODE_RENDER)) { @@ -122,81 +122,82 @@ void AbstractEglBackend::initWayland() } else { qCWarning(KWIN_OPENGL) << "No render node have been found, not initializing wl-drm"; } - } - const auto formats = m_display->allSupportedDrmFormats(); - auto filterFormats = [this, &formats](std::optional bpc, bool withExternalOnlyYUV) { - QHash> set; - for (auto it = formats.constBegin(); it != formats.constEnd(); it++) { - const auto info = FormatInfo::get(it.key()); - if (bpc && (!info || bpc != info->bitsPerColor)) { - continue; - } + const auto formats = m_display->allSupportedDrmFormats(); + auto filterFormats = [this, &formats](std::optional bpc, bool withExternalOnlyYUV) { + QHash> set; + for (auto it = formats.constBegin(); it != formats.constEnd(); it++) { + const auto info = FormatInfo::get(it.key()); + if (bpc && (!info || bpc != info->bitsPerColor)) { + continue; + } - const bool externalOnlySupported = withExternalOnlyYUV && info && info->yuvConversion(); - QList modifiers = externalOnlySupported ? it->allModifiers : it->nonExternalOnlyModifiers; + const bool externalOnlySupported = withExternalOnlyYUV && info && info->yuvConversion(); + QList modifiers = externalOnlySupported ? it->allModifiers : it->nonExternalOnlyModifiers; - if (externalOnlySupported && !modifiers.isEmpty()) { - if (auto yuv = info->yuvConversion()) { - for (auto plane : std::as_const(yuv->plane)) { - const auto planeModifiers = formats.value(plane.format).allModifiers; - modifiers.erase(std::remove_if(modifiers.begin(), modifiers.end(), [&planeModifiers](uint64_t mod) { - return !planeModifiers.contains(mod); - }), - modifiers.end()); + if (externalOnlySupported && !modifiers.isEmpty()) { + if (auto yuv = info->yuvConversion()) { + for (auto plane : std::as_const(yuv->plane)) { + const auto planeModifiers = formats.value(plane.format).allModifiers; + modifiers.erase(std::remove_if(modifiers.begin(), modifiers.end(), [&planeModifiers](uint64_t mod) { + return !planeModifiers.contains(mod); + }), + modifiers.end()); + } + } + } + for (const auto &tranche : std::as_const(m_tranches)) { + if (modifiers.isEmpty()) { + break; + } + const auto trancheModifiers = tranche.formatTable.value(it.key()); + for (auto trancheModifier : trancheModifiers) { + modifiers.removeAll(trancheModifier); } } - } - for (const auto &tranche : std::as_const(m_tranches)) { if (modifiers.isEmpty()) { - break; + continue; } - const auto trancheModifiers = tranche.formatTable.value(it.key()); - for (auto trancheModifier : trancheModifiers) { - modifiers.removeAll(trancheModifier); + set.insert(it.key(), modifiers); + } + return set; + }; + + auto includeShaderConversions = [](QHash> &&formats) -> QHash> { + for (auto format : s_drmConversions.keys()) { + auto &modifiers = formats[format]; + if (modifiers.isEmpty()) { + modifiers = {DRM_FORMAT_MOD_LINEAR}; } } - if (modifiers.isEmpty()) { - continue; - } - set.insert(it.key(), modifiers); - } - return set; - }; + return formats; + }; - auto includeShaderConversions = [](QHash> &&formats) -> QHash> { - for (auto format : s_drmConversions.keys()) { - auto &modifiers = formats[format]; - if (modifiers.isEmpty()) { - modifiers = {DRM_FORMAT_MOD_LINEAR}; - } - } - return formats; - }; + m_tranches.append({ + .device = scanoutDevice->deviceId(), + .flags = {}, + .formatTable = filterFormats(10, false), + }); + m_tranches.append({ + .device = scanoutDevice->deviceId(), + .flags = {}, + .formatTable = filterFormats(8, false), + }); + m_tranches.append({ + .device = scanoutDevice->deviceId(), + .flags = {}, + .formatTable = includeShaderConversions(filterFormats({}, true)), + }); - m_tranches.append({ - .device = deviceId(), - .flags = {}, - .formatTable = filterFormats(10, false), - }); - m_tranches.append({ - .device = deviceId(), - .flags = {}, - .formatTable = filterFormats(8, false), - }); - m_tranches.append({ - .device = deviceId(), - .flags = {}, - .formatTable = includeShaderConversions(filterFormats({}, true)), - }); + LinuxDmaBufV1ClientBufferIntegration *dmabuf = waylandServer()->linuxDmabuf(); + dmabuf->setRenderBackend(this); + dmabuf->setSupportedFormatsWithModifiers(m_tranches); + if (auto syncObj = waylandServer()->linuxSyncObj()) { + syncObj->setRenderBackend(this); + } + } waylandServer()->setRenderBackend(this); - LinuxDmaBufV1ClientBufferIntegration *dmabuf = waylandServer()->linuxDmabuf(); - dmabuf->setRenderBackend(this); - dmabuf->setSupportedFormatsWithModifiers(m_tranches); - if (auto syncObj = waylandServer()->linuxSyncObj()) { - syncObj->setRenderBackend(this); - } } void AbstractEglBackend::initClientExtensions() @@ -251,11 +252,6 @@ QList AbstractEglBackend::tranches() const return m_tranches; } -dev_t AbstractEglBackend::deviceId() const -{ - return m_deviceId; -} - EGLImageKHR AbstractEglBackend::importBufferAsImage(GraphicsBuffer *buffer, int plane, int format, const QSize &size) { std::pair key(buffer, plane); diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.h b/src/platformsupport/scenes/opengl/abstract_egl_backend.h index 43c63995d7..0d2760022b 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.h +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.h @@ -40,7 +40,6 @@ public: QHash> supportedFormats() const override; QList tranches() const; - dev_t deviceId() const; std::shared_ptr importDmaBufAsTexture(const DmaBufAttributes &attributes) const; EGLImageKHR importDmaBufAsImage(const DmaBufAttributes &attributes) const; @@ -49,7 +48,7 @@ public: EGLImageKHR importBufferAsImage(GraphicsBuffer *buffer, int plane, int format, const QSize &size); protected: - AbstractEglBackend(dev_t deviceId = 0); + AbstractEglBackend(); void cleanup(); virtual void cleanupSurfaces(); void setEglDisplay(EglDisplay *display); @@ -67,7 +66,6 @@ protected: EglDisplay *m_display = nullptr; std::shared_ptr m_context; QList m_clientExtensions; - const dev_t m_deviceId; QList m_tranches; QHash, EGLImageKHR> m_importedBuffers; };