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.
This commit is contained in:
Xaver Hugl 2023-08-11 15:49:18 +02:00 committed by Vlad Zahorodnii
parent 36960d8572
commit 56aab75a57
8 changed files with 48 additions and 14 deletions

View file

@ -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;
}

View file

@ -16,6 +16,7 @@
#include "window.h"
#include <QPainter>
#include <libdrm/drm_fourcc.h>
namespace KWin
{
@ -41,7 +42,11 @@ void BackingStore::resize(const QSize &size, const QRegion &staticContents)
void BackingStore::beginPaint(const QRegion &region)
{
Window *platformWindow = static_cast<Window *>(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();

View file

@ -84,7 +84,7 @@ bool EGLPlatformContext::makeCurrent(QPlatformSurface *surface)
QOpenGLContextPrivate::setCurrentContext(context());
Window *window = static_cast<Window *>(surface);
Swapchain *swapchain = window->swapchain();
Swapchain *swapchain = window->swapchain(m_eglDisplay->supportedDrmFormats());
GraphicsBuffer *buffer = swapchain->acquire();
if (!buffer) {

View file

@ -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<uint64_t> Swapchain::modifiers() const
{
return m_allocationOptions.modifiers;
}
}
}

View file

@ -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<uint64_t> modifiers() const;
private:
GraphicsBufferAllocator *m_allocator;

View file

@ -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<uint32_t, QVector<uint64_t>> &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<Swapchain>(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<Swapchain>(allocator, options, buffer);
break;
}
}
}
return m_swapchain.get();
}

View file

@ -37,7 +37,7 @@ public:
void requestActivateWindow() override;
InternalWindow *internalWindow() const;
Swapchain *swapchain();
Swapchain *swapchain(const QHash<uint32_t, QVector<uint64_t>> &formats);
private:
void map();

View file

@ -7,8 +7,8 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <drm_fourcc.h>
#include <epoxy/gl.h>
#include <libdrm/drm_fourcc.h>
#include <optional>
#include <stdint.h>