dmabuf feedback: limit modifiers to those supported by egl

This commit is contained in:
Xaver Hugl 2021-12-30 17:55:39 +01:00
parent 5a6f1e42c1
commit 0ba2c35e1a
5 changed files with 41 additions and 23 deletions

View file

@ -27,6 +27,7 @@
#include "shadowbuffer.h"
#include "drm_pipeline.h"
#include "drm_abstract_output.h"
#include "egl_dmabuf.h"
// kwin libs
#include <kwinglplatform.h>
#include <kwineglimagetexture.h>
@ -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({});

View file

@ -398,4 +398,9 @@ bool AbstractEglBackend::prefer10bpc() const
return false;
}
EglDmabuf *AbstractEglBackend::dmabuf() const
{
return m_dmaBuf;
}
}

View file

@ -72,6 +72,7 @@ public:
dev_t deviceId() const;
virtual bool prefer10bpc() const;
EglDmabuf *dmabuf() const;
protected:
AbstractEglBackend(dev_t deviceId = 0);

View file

@ -440,28 +440,31 @@ void EglDmabuf::setSupportedFormatsAndModifiers()
filterFormatsWithMultiplePlanes(formats);
auto queryFormats = [&formats, &eglDisplay](int bpc) {
QHash<uint32_t, QSet<uint64_t>> 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<uint64_t> modifiers(count);
if (eglQueryDmaBufModifiersEXT(eglDisplay, format, count, modifiers.data(), nullptr, &count)) {
QSet<uint64_t> 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<uint64_t> modifiers(count);
if (eglQueryDmaBufModifiersEXT(eglDisplay, format, count, modifiers.data(), nullptr, &count)) {
QSet<uint64_t> modifiersSet;
for (const uint64_t &mod : qAsConst(modifiers)) {
modifiersSet.insert(mod);
}
m_supportedFormats.insert(format, modifiersSet);
continue;
}
}
set.insert(format, QSet<uint64_t>());
}
m_supportedFormats.insert(format, QSet<uint64_t>());
}
auto filterFormats = [this](int bpc) {
QHash<uint32_t, QSet<uint64_t>> 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);
}

View file

@ -67,6 +67,10 @@ public:
const QSize &size,
quint32 flags) override;
QHash<uint32_t, QSet<uint64_t>> supportedFormats() const {
return m_supportedFormats;
}
private:
EGLImage createImage(const QVector<KWaylandServer::LinuxDmaBufV1Plane> &planes,
uint32_t format,
@ -80,6 +84,7 @@ private:
void setSupportedFormatsAndModifiers();
AbstractEglBackend *m_backend;
QHash<uint32_t, QSet<uint64_t>> m_supportedFormats;
friend class EglDmabufBuffer;
};