From 0ba2c35e1a941edb7cffae8734dadf687d9c3a12 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Thu, 30 Dec 2021 17:55:39 +0100 Subject: [PATCH] dmabuf feedback: limit modifiers to those supported by egl --- src/backends/drm/egl_gbm_backend.cpp | 6 ++- .../scenes/opengl/abstract_egl_backend.cpp | 5 ++ .../scenes/opengl/abstract_egl_backend.h | 1 + .../scenes/opengl/egl_dmabuf.cpp | 47 ++++++++++--------- .../scenes/opengl/egl_dmabuf.h | 5 ++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/backends/drm/egl_gbm_backend.cpp b/src/backends/drm/egl_gbm_backend.cpp index 811b8863e6..d80da88a66 100644 --- a/src/backends/drm/egl_gbm_backend.cpp +++ b/src/backends/drm/egl_gbm_backend.cpp @@ -27,6 +27,7 @@ #include "shadowbuffer.h" #include "drm_pipeline.h" #include "drm_abstract_output.h" +#include "egl_dmabuf.h" // kwin libs #include #include @@ -659,8 +660,11 @@ bool EglGbmBackend::scanout(AbstractOutput *drmOutput, SurfaceItem *surfaceItem) // atm no format changes are sent as those might require a modeset // and thus require more elaborate feedback const auto &mods = drmOutput->pipeline()->supportedModifiers(output.current.format.drmFormat); + const auto &supportedModifiers = primaryBackend()->dmabuf()->supportedFormats()[output.current.format.drmFormat]; for (const auto &mod : mods) { - tranche.formatTable[output.current.format.drmFormat] << mod; + if (supportedModifiers.contains(mod)) { + tranche.formatTable[output.current.format.drmFormat] << mod; + } } if (tranche.formatTable.isEmpty()) { output.scanoutCandidate->dmabufFeedbackV1()->setTranches({}); diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index 5e4d3cbfdf..7ecbff2e18 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -398,4 +398,9 @@ bool AbstractEglBackend::prefer10bpc() const return false; } +EglDmabuf *AbstractEglBackend::dmabuf() const +{ + return m_dmaBuf; +} + } diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.h b/src/platformsupport/scenes/opengl/abstract_egl_backend.h index 08cd11211c..466cdce3b5 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.h +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.h @@ -72,6 +72,7 @@ public: dev_t deviceId() const; virtual bool prefer10bpc() const; + EglDmabuf *dmabuf() const; protected: AbstractEglBackend(dev_t deviceId = 0); diff --git a/src/platformsupport/scenes/opengl/egl_dmabuf.cpp b/src/platformsupport/scenes/opengl/egl_dmabuf.cpp index 50e4534dce..236c3ef663 100644 --- a/src/platformsupport/scenes/opengl/egl_dmabuf.cpp +++ b/src/platformsupport/scenes/opengl/egl_dmabuf.cpp @@ -440,28 +440,31 @@ void EglDmabuf::setSupportedFormatsAndModifiers() filterFormatsWithMultiplePlanes(formats); - auto queryFormats = [&formats, &eglDisplay](int bpc) { - QHash> set; - for (auto format : qAsConst(formats)) { - if (bpc != bpcForFormat(format)) { - continue; - } - if (eglQueryDmaBufModifiersEXT != nullptr) { - EGLint count = 0; - const EGLBoolean success = eglQueryDmaBufModifiersEXT(eglDisplay, format, 0, nullptr, nullptr, &count); - if (success && count > 0) { - QVector modifiers(count); - if (eglQueryDmaBufModifiersEXT(eglDisplay, format, count, modifiers.data(), nullptr, &count)) { - QSet modifiersSet; - for (const uint64_t &mod : qAsConst(modifiers)) { - modifiersSet.insert(mod); - } - set.insert(format, modifiersSet); - continue; + for (auto format : qAsConst(formats)) { + if (eglQueryDmaBufModifiersEXT != nullptr) { + EGLint count = 0; + const EGLBoolean success = eglQueryDmaBufModifiersEXT(eglDisplay, format, 0, nullptr, nullptr, &count); + if (success && count > 0) { + QVector modifiers(count); + if (eglQueryDmaBufModifiersEXT(eglDisplay, format, count, modifiers.data(), nullptr, &count)) { + QSet modifiersSet; + for (const uint64_t &mod : qAsConst(modifiers)) { + modifiersSet.insert(mod); } + m_supportedFormats.insert(format, modifiersSet); + continue; } } - set.insert(format, QSet()); + } + m_supportedFormats.insert(format, QSet()); + } + + auto filterFormats = [this](int bpc) { + QHash> set; + for (auto it = m_supportedFormats.constBegin(); it != m_supportedFormats.constEnd(); it++) { + if (bpcForFormat(it.key()) == bpc) { + set.insert(it.key(), it.value()); + } } return set; }; @@ -470,18 +473,18 @@ void EglDmabuf::setSupportedFormatsAndModifiers() tranches.append({ .device = m_backend->deviceId(), .flags = {}, - .formatTable = queryFormats(10), + .formatTable = filterFormats(10), }); } tranches.append({ .device = m_backend->deviceId(), .flags = {}, - .formatTable = queryFormats(8), + .formatTable = filterFormats(8), }); tranches.append({ .device = m_backend->deviceId(), .flags = {}, - .formatTable = queryFormats(-1), + .formatTable = filterFormats(-1), }); LinuxDmaBufV1RendererInterface::setSupportedFormatsAndModifiers(tranches); } diff --git a/src/platformsupport/scenes/opengl/egl_dmabuf.h b/src/platformsupport/scenes/opengl/egl_dmabuf.h index 9734cb34c6..b2b5733e2c 100644 --- a/src/platformsupport/scenes/opengl/egl_dmabuf.h +++ b/src/platformsupport/scenes/opengl/egl_dmabuf.h @@ -67,6 +67,10 @@ public: const QSize &size, quint32 flags) override; + QHash> supportedFormats() const { + return m_supportedFormats; + } + private: EGLImage createImage(const QVector &planes, uint32_t format, @@ -80,6 +84,7 @@ private: void setSupportedFormatsAndModifiers(); AbstractEglBackend *m_backend; + QHash> m_supportedFormats; friend class EglDmabufBuffer; };