platformsupport/scenes/opengl: move egl dmabuf format queries to KWinEglDisplay
This commit is contained in:
parent
94ac8d235b
commit
7bb56eb363
4 changed files with 92 additions and 68 deletions
|
@ -177,78 +177,37 @@ void AbstractEglBackend::initWayland()
|
|||
}
|
||||
}
|
||||
|
||||
if (hasExtension(QByteArrayLiteral("EGL_EXT_image_dma_buf_import")) && hasExtension(QByteArrayLiteral("EGL_EXT_image_dma_buf_import_modifiers"))) {
|
||||
eglQueryDmaBufFormatsEXT = (eglQueryDmaBufFormatsEXT_func)eglGetProcAddress("eglQueryDmaBufFormatsEXT");
|
||||
eglQueryDmaBufModifiersEXT = (eglQueryDmaBufModifiersEXT_func)eglGetProcAddress("eglQueryDmaBufModifiersEXT");
|
||||
|
||||
EGLint count = 0;
|
||||
EGLBoolean success = eglQueryDmaBufFormatsEXT(m_display, 0, nullptr, &count);
|
||||
|
||||
if (!success || count == 0) {
|
||||
qCCritical(KWIN_OPENGL) << "eglQueryDmaBufFormatsEXT failed:" << getEglErrorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<uint32_t> formats(count);
|
||||
if (!eglQueryDmaBufFormatsEXT(m_display, count, (EGLint *)formats.data(), &count)) {
|
||||
qCCritical(KWIN_OPENGL) << "eglQueryDmaBufFormatsEXT with count" << count << "failed:" << getEglErrorString();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto format : std::as_const(formats)) {
|
||||
EGLint count = 0;
|
||||
const EGLBoolean success = eglQueryDmaBufModifiersEXT(m_display, format, 0, nullptr, nullptr, &count);
|
||||
if (success && count > 0) {
|
||||
QVector<uint64_t> modifiers(count);
|
||||
QVector<EGLBoolean> externalOnly(count);
|
||||
if (eglQueryDmaBufModifiersEXT(m_display, format, count, modifiers.data(), externalOnly.data(), &count)) {
|
||||
for (int i = modifiers.size() - 1; i >= 0; i--) {
|
||||
if (externalOnly[i]) {
|
||||
modifiers.remove(i);
|
||||
externalOnly.remove(i);
|
||||
}
|
||||
}
|
||||
if (!modifiers.empty()) {
|
||||
m_supportedFormats.insert(format, modifiers);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
auto filterFormats = [this](int bpc) {
|
||||
const auto formats = m_display->supportedDrmFormats();
|
||||
QHash<uint32_t, QVector<uint64_t>> set;
|
||||
for (auto it = formats.constBegin(); it != formats.constEnd(); it++) {
|
||||
if (bpcForFormat(it.key()) == bpc) {
|
||||
set.insert(it.key(), it.value());
|
||||
}
|
||||
m_supportedFormats.insert(format, {DRM_FORMAT_MOD_INVALID});
|
||||
}
|
||||
qCDebug(KWIN_OPENGL) << "EGL driver advertises" << m_supportedFormats.count() << "supported dmabuf formats";
|
||||
|
||||
auto filterFormats = [this](int bpc) {
|
||||
QHash<uint32_t, QVector<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;
|
||||
};
|
||||
if (prefer10bpc()) {
|
||||
m_tranches.append({
|
||||
.device = deviceId(),
|
||||
.flags = {},
|
||||
.formatTable = filterFormats(10),
|
||||
});
|
||||
}
|
||||
return set;
|
||||
};
|
||||
if (prefer10bpc()) {
|
||||
m_tranches.append({
|
||||
.device = deviceId(),
|
||||
.flags = {},
|
||||
.formatTable = filterFormats(8),
|
||||
.formatTable = filterFormats(10),
|
||||
});
|
||||
m_tranches.append({
|
||||
.device = deviceId(),
|
||||
.flags = {},
|
||||
.formatTable = filterFormats(-1),
|
||||
});
|
||||
|
||||
KWaylandServer::LinuxDmaBufV1ClientBufferIntegration *dmabuf = waylandServer()->linuxDmabuf();
|
||||
dmabuf->setRenderBackend(this);
|
||||
dmabuf->setSupportedFormatsWithModifiers(m_tranches);
|
||||
}
|
||||
m_tranches.append({
|
||||
.device = deviceId(),
|
||||
.flags = {},
|
||||
.formatTable = filterFormats(8),
|
||||
});
|
||||
m_tranches.append({
|
||||
.device = deviceId(),
|
||||
.flags = {},
|
||||
.formatTable = filterFormats(-1),
|
||||
});
|
||||
|
||||
KWaylandServer::LinuxDmaBufV1ClientBufferIntegration *dmabuf = waylandServer()->linuxDmabuf();
|
||||
dmabuf->setRenderBackend(this);
|
||||
dmabuf->setSupportedFormatsWithModifiers(m_tranches);
|
||||
}
|
||||
|
||||
void AbstractEglBackend::initClientExtensions()
|
||||
|
@ -353,7 +312,7 @@ bool AbstractEglBackend::testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuf
|
|||
|
||||
QHash<uint32_t, QVector<uint64_t>> AbstractEglBackend::supportedFormats() const
|
||||
{
|
||||
return m_supportedFormats;
|
||||
return m_display->supportedDrmFormats();
|
||||
}
|
||||
|
||||
::EGLDisplay AbstractEglBackend::eglDisplay() const
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
{
|
||||
return &m_functions;
|
||||
}
|
||||
EGLDisplay eglDisplay() const;
|
||||
::EGLDisplay eglDisplay() const;
|
||||
::EGLContext context() const;
|
||||
EGLSurface surface() const;
|
||||
EGLConfig config() const;
|
||||
|
@ -92,7 +92,6 @@ private:
|
|||
QList<QByteArray> m_clientExtensions;
|
||||
const dev_t m_deviceId;
|
||||
QVector<KWaylandServer::LinuxDmaBufV1Feedback::Tranche> m_tranches;
|
||||
QHash<uint32_t, QVector<uint64_t>> m_supportedFormats;
|
||||
QHash<KWaylandServer::LinuxDmaBufV1ClientBuffer *, EGLImageKHR> m_importedBuffers;
|
||||
};
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ EglDisplay::EglDisplay(::EGLDisplay display, const QList<QByteArray> &extensions
|
|||
, m_supportsBufferAge(extensions.contains(QByteArrayLiteral("EGL_EXT_buffer_age")) && qgetenv("KWIN_USE_BUFFER_AGE") != "0")
|
||||
, m_supportsSwapBuffersWithDamage(extensions.contains(QByteArrayLiteral("EGL_EXT_swap_buffers_with_damage")))
|
||||
, m_supportsNativeFence(extensions.contains(QByteArrayLiteral("EGL_ANDROID_native_fence_sync")))
|
||||
, m_importFormats(queryImportFormats())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -167,4 +168,64 @@ EGLImageKHR EglDisplay::importDmaBufAsImage(const DmaBufAttributes &dmabuf) cons
|
|||
|
||||
return eglCreateImageKHR(m_handle, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
|
||||
}
|
||||
|
||||
QHash<uint32_t, QList<uint64_t>> EglDisplay::supportedDrmFormats() const
|
||||
{
|
||||
return m_importFormats;
|
||||
}
|
||||
|
||||
QHash<uint32_t, QList<uint64_t>> EglDisplay::queryImportFormats() const
|
||||
{
|
||||
if (!hasExtension(QByteArrayLiteral("EGL_EXT_image_dma_buf_import")) || !hasExtension(QByteArrayLiteral("EGL_EXT_image_dma_buf_import_modifiers"))) {
|
||||
return {};
|
||||
}
|
||||
|
||||
typedef EGLBoolean (*eglQueryDmaBufFormatsEXT_func)(EGLDisplay dpy, EGLint max_formats, EGLint * formats, EGLint * num_formats);
|
||||
typedef EGLBoolean (*eglQueryDmaBufModifiersEXT_func)(EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR * modifiers, EGLBoolean * external_only, EGLint * num_modifiers);
|
||||
eglQueryDmaBufFormatsEXT_func eglQueryDmaBufFormatsEXT = nullptr;
|
||||
eglQueryDmaBufModifiersEXT_func eglQueryDmaBufModifiersEXT = nullptr;
|
||||
eglQueryDmaBufFormatsEXT = (eglQueryDmaBufFormatsEXT_func)eglGetProcAddress("eglQueryDmaBufFormatsEXT");
|
||||
eglQueryDmaBufModifiersEXT = (eglQueryDmaBufModifiersEXT_func)eglGetProcAddress("eglQueryDmaBufModifiersEXT");
|
||||
if (eglQueryDmaBufFormatsEXT == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
EGLint count = 0;
|
||||
EGLBoolean success = eglQueryDmaBufFormatsEXT(m_handle, 0, nullptr, &count);
|
||||
if (!success || count == 0) {
|
||||
qCCritical(KWIN_OPENGL) << "eglQueryDmaBufFormatsEXT failed!" << getEglErrorString();
|
||||
return {};
|
||||
}
|
||||
QVector<uint32_t> formats(count);
|
||||
if (!eglQueryDmaBufFormatsEXT(m_handle, count, (EGLint *)formats.data(), &count)) {
|
||||
qCCritical(KWIN_OPENGL) << "eglQueryDmaBufFormatsEXT with count" << count << "failed!" << getEglErrorString();
|
||||
return {};
|
||||
}
|
||||
QHash<uint32_t, QVector<uint64_t>> ret;
|
||||
for (const auto format : std::as_const(formats)) {
|
||||
if (eglQueryDmaBufModifiersEXT != nullptr) {
|
||||
EGLint count = 0;
|
||||
const EGLBoolean success = eglQueryDmaBufModifiersEXT(m_handle, format, 0, nullptr, nullptr, &count);
|
||||
if (success && count > 0) {
|
||||
QVector<uint64_t> modifiers(count);
|
||||
QVector<EGLBoolean> externalOnly(count);
|
||||
if (eglQueryDmaBufModifiersEXT(m_handle, format, count, modifiers.data(), nullptr, &count)) {
|
||||
for (int i = modifiers.size() - 1; i >= 0; i--) {
|
||||
if (externalOnly[i]) {
|
||||
modifiers.remove(i);
|
||||
externalOnly.remove(i);
|
||||
}
|
||||
}
|
||||
if (!modifiers.empty()) {
|
||||
ret.insert(format, modifiers);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.insert(format, {DRM_FORMAT_MOD_INVALID});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "kwin_export.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
|
@ -33,12 +34,15 @@ public:
|
|||
bool supportsBufferAge() const;
|
||||
bool supportsSwapBuffersWithDamage() const;
|
||||
bool supportsNativeFence() const;
|
||||
QHash<uint32_t, QList<uint64_t>> supportedDrmFormats() const;
|
||||
|
||||
EGLImageKHR importDmaBufAsImage(const DmaBufAttributes &dmabuf) const;
|
||||
|
||||
static std::unique_ptr<EglDisplay> create(::EGLDisplay display, bool owning = true);
|
||||
|
||||
private:
|
||||
QHash<uint32_t, QList<uint64_t>> queryImportFormats() const;
|
||||
|
||||
const ::EGLDisplay m_handle;
|
||||
const QList<QByteArray> m_extensions;
|
||||
const bool m_owning;
|
||||
|
@ -46,6 +50,7 @@ private:
|
|||
const bool m_supportsBufferAge;
|
||||
const bool m_supportsSwapBuffersWithDamage;
|
||||
const bool m_supportsNativeFence;
|
||||
const QHash<uint32_t, QList<uint64_t>> m_importFormats;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue