From 56aab75a57cf3c18d8a2e3a116c2bf64d8865307 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Fri, 11 Aug 2023 15:49:18 +0200 Subject: [PATCH] plugins/qpa: handle modifiers more correctly Instead of hardcoding ARGB8888 and using implicit modifiers, look through the list of available formats and modifiers and pick a match that egl will actually accept. --- src/core/shmgraphicsbufferallocator.cpp | 2 +- src/plugins/qpa/backingstore.cpp | 7 +++++- src/plugins/qpa/eglplatformcontext.cpp | 2 +- src/plugins/qpa/swapchain.cpp | 12 +++++++++- src/plugins/qpa/swapchain.h | 4 +++- src/plugins/qpa/window.cpp | 31 +++++++++++++++++++------ src/plugins/qpa/window.h | 2 +- src/utils/drm_format_helper.h | 2 +- 8 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/core/shmgraphicsbufferallocator.cpp b/src/core/shmgraphicsbufferallocator.cpp index 1c4df66d41..f01680316f 100644 --- a/src/core/shmgraphicsbufferallocator.cpp +++ b/src/core/shmgraphicsbufferallocator.cpp @@ -81,7 +81,7 @@ GraphicsBuffer *ShmGraphicsBufferAllocator::allocate(const GraphicsBufferOptions if (!options.software) { return nullptr; } - if (!options.modifiers.isEmpty()) { + if (!options.modifiers.isEmpty() && !options.modifiers.contains(DRM_FORMAT_MOD_LINEAR)) { return nullptr; } diff --git a/src/plugins/qpa/backingstore.cpp b/src/plugins/qpa/backingstore.cpp index 3c60a6c62d..f83386680b 100644 --- a/src/plugins/qpa/backingstore.cpp +++ b/src/plugins/qpa/backingstore.cpp @@ -16,6 +16,7 @@ #include "window.h" #include +#include namespace KWin { @@ -41,7 +42,11 @@ void BackingStore::resize(const QSize &size, const QRegion &staticContents) void BackingStore::beginPaint(const QRegion ®ion) { Window *platformWindow = static_cast(window()->handle()); - Swapchain *swapchain = platformWindow->swapchain(); + Swapchain *swapchain = platformWindow->swapchain({{DRM_FORMAT_ARGB8888, {DRM_FORMAT_MOD_LINEAR}}}); + if (!swapchain) { + qCCritical(KWIN_QPA, "Failed to ceate a swapchain for the backing store!"); + return; + } const auto oldBuffer = m_buffer; m_buffer = swapchain->acquire(); diff --git a/src/plugins/qpa/eglplatformcontext.cpp b/src/plugins/qpa/eglplatformcontext.cpp index 5de338823d..c6bea72a7f 100644 --- a/src/plugins/qpa/eglplatformcontext.cpp +++ b/src/plugins/qpa/eglplatformcontext.cpp @@ -84,7 +84,7 @@ bool EGLPlatformContext::makeCurrent(QPlatformSurface *surface) QOpenGLContextPrivate::setCurrentContext(context()); Window *window = static_cast(surface); - Swapchain *swapchain = window->swapchain(); + Swapchain *swapchain = window->swapchain(m_eglDisplay->supportedDrmFormats()); GraphicsBuffer *buffer = swapchain->acquire(); if (!buffer) { diff --git a/src/plugins/qpa/swapchain.cpp b/src/plugins/qpa/swapchain.cpp index c5b1731fb4..f74ad3783e 100644 --- a/src/plugins/qpa/swapchain.cpp +++ b/src/plugins/qpa/swapchain.cpp @@ -11,10 +11,11 @@ namespace KWin namespace QPA { -Swapchain::Swapchain(GraphicsBufferAllocator *allocator, const GraphicsBufferOptions &options) +Swapchain::Swapchain(GraphicsBufferAllocator *allocator, const GraphicsBufferOptions &options, GraphicsBuffer *initialBuffer) : m_allocator(allocator) , m_allocationOptions(options) { + m_buffers.push_back(initialBuffer); } Swapchain::~Swapchain() @@ -46,5 +47,14 @@ GraphicsBuffer *Swapchain::acquire() return buffer; } +uint32_t Swapchain::format() const +{ + return m_allocationOptions.format; +} + +QVector Swapchain::modifiers() const +{ + return m_allocationOptions.modifiers; +} } } diff --git a/src/plugins/qpa/swapchain.h b/src/plugins/qpa/swapchain.h index 336c0af1ad..7cd57cfd8a 100644 --- a/src/plugins/qpa/swapchain.h +++ b/src/plugins/qpa/swapchain.h @@ -18,12 +18,14 @@ namespace QPA class Swapchain { public: - Swapchain(GraphicsBufferAllocator *allocator, const GraphicsBufferOptions &options); + Swapchain(GraphicsBufferAllocator *allocator, const GraphicsBufferOptions &options, GraphicsBuffer *initialBuffer); ~Swapchain(); QSize size() const; GraphicsBuffer *acquire(); + uint32_t format() const; + QVector modifiers() const; private: GraphicsBufferAllocator *m_allocator; diff --git a/src/plugins/qpa/window.cpp b/src/plugins/qpa/window.cpp index b8135adc2c..44339cd18b 100644 --- a/src/plugins/qpa/window.cpp +++ b/src/plugins/qpa/window.cpp @@ -7,6 +7,10 @@ SPDX-License-Identifier: GPL-2.0-or-later */ +// this needs to be on top, epoxy has an error if you include it after GL/gl.h, +// which Qt does include +#include "utils/drm_format_helper.h" + #include "window.h" #include "composite.h" #include "core/renderbackend.h" @@ -38,10 +42,12 @@ Window::~Window() unmap(); } -Swapchain *Window::swapchain() +Swapchain *Window::swapchain(const QHash> &formats) { const QSize nativeSize = geometry().size() * devicePixelRatio(); - if (!m_swapchain || m_swapchain->size() != nativeSize) { + if (!m_swapchain || m_swapchain->size() != nativeSize + || !formats.contains(m_swapchain->format()) + || m_swapchain->modifiers() != formats[m_swapchain->format()]) { const bool software = window()->surfaceType() == QSurface::RasterSurface; // RasterGLSurface is unsupported by us GraphicsBufferAllocator *allocator; @@ -52,11 +58,22 @@ Swapchain *Window::swapchain() allocator = Compositor::self()->backend()->graphicsBufferAllocator(); } - m_swapchain = std::make_unique(allocator, GraphicsBufferOptions{ - .size = nativeSize, - .format = DRM_FORMAT_ARGB8888, - .software = software, - }); + for (auto it = formats.begin(); it != formats.end(); it++) { + if (auto info = formatInfo(it.key()); info && info->bitsPerColor == 8 && info->alphaBits == 8) { + const auto options = GraphicsBufferOptions{ + .size = nativeSize, + .format = it.key(), + .modifiers = it.value(), + .software = software, + }; + auto buffer = allocator->allocate(options); + if (!buffer) { + continue; + } + m_swapchain = std::make_unique(allocator, options, buffer); + break; + } + } } return m_swapchain.get(); } diff --git a/src/plugins/qpa/window.h b/src/plugins/qpa/window.h index 0f2ae67708..5bbb2e666f 100644 --- a/src/plugins/qpa/window.h +++ b/src/plugins/qpa/window.h @@ -37,7 +37,7 @@ public: void requestActivateWindow() override; InternalWindow *internalWindow() const; - Swapchain *swapchain(); + Swapchain *swapchain(const QHash> &formats); private: void map(); diff --git a/src/utils/drm_format_helper.h b/src/utils/drm_format_helper.h index 62d383dc5c..7f004ac671 100644 --- a/src/utils/drm_format_helper.h +++ b/src/utils/drm_format_helper.h @@ -7,8 +7,8 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once -#include #include +#include #include #include