{core,backends/wayland}: Refactor gbm buffer allocator
This commit is contained in:
parent
3ac4f8a7dc
commit
103d8d8abe
7 changed files with 252 additions and 48 deletions
|
@ -42,7 +42,9 @@ target_sources(kwin PRIVATE
|
|||
core/colorlut.cpp
|
||||
core/colorpipelinestage.cpp
|
||||
core/colortransformation.cpp
|
||||
core/gbmgraphicsbufferallocator.cpp
|
||||
core/graphicsbuffer.cpp
|
||||
core/graphicsbufferallocator.cpp
|
||||
core/inputbackend.cpp
|
||||
core/inputdevice.cpp
|
||||
core/output.cpp
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
#include "wayland_egl_backend.h"
|
||||
#include "../drm/gbm_dmabuf.h"
|
||||
#include "core/gbmgraphicsbufferallocator.h"
|
||||
#include "platformsupport/scenes/opengl/basiceglsurfacetexture_internal.h"
|
||||
#include "platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.h"
|
||||
|
||||
|
@ -44,34 +44,10 @@ namespace KWin
|
|||
namespace Wayland
|
||||
{
|
||||
|
||||
WaylandEglLayerBuffer::WaylandEglLayerBuffer(const QSize &size, uint32_t format, const QVector<uint64_t> &modifiers, WaylandEglBackend *backend)
|
||||
: m_backend(backend)
|
||||
WaylandEglLayerBuffer::WaylandEglLayerBuffer(GbmGraphicsBuffer *buffer, WaylandEglBackend *backend)
|
||||
: m_graphicsBuffer(buffer)
|
||||
{
|
||||
gbm_device *gbmDevice = backend->backend()->gbmDevice();
|
||||
|
||||
if (!modifiers.isEmpty()) {
|
||||
m_bo = gbm_bo_create_with_modifiers(gbmDevice,
|
||||
size.width(),
|
||||
size.height(),
|
||||
format,
|
||||
modifiers.constData(),
|
||||
modifiers.size());
|
||||
}
|
||||
|
||||
if (!m_bo) {
|
||||
m_bo = gbm_bo_create(gbmDevice,
|
||||
size.width(),
|
||||
size.height(),
|
||||
format,
|
||||
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
||||
}
|
||||
|
||||
if (!m_bo) {
|
||||
qCCritical(KWIN_WAYLAND_BACKEND) << "Failed to allocate a buffer for an output layer";
|
||||
return;
|
||||
}
|
||||
|
||||
DmaBufAttributes attributes = dmaBufAttributesForBo(m_bo);
|
||||
const DmaBufAttributes &attributes = buffer->dmabufAttributes();
|
||||
|
||||
zwp_linux_buffer_params_v1 *params = zwp_linux_dmabuf_v1_create_params(backend->backend()->display()->linuxDmabuf()->handle());
|
||||
for (int i = 0; i < attributes.planeCount; ++i) {
|
||||
|
@ -84,10 +60,10 @@ WaylandEglLayerBuffer::WaylandEglLayerBuffer(const QSize &size, uint32_t format,
|
|||
attributes.modifier & 0xffffffff);
|
||||
}
|
||||
|
||||
m_buffer = zwp_linux_buffer_params_v1_create_immed(params, size.width(), size.height(), format, 0);
|
||||
m_buffer = zwp_linux_buffer_params_v1_create_immed(params, attributes.width, attributes.height, attributes.format, 0);
|
||||
zwp_linux_buffer_params_v1_destroy(params);
|
||||
|
||||
m_texture = backend->importDmaBufAsTexture(std::move(attributes));
|
||||
m_texture = backend->importDmaBufAsTexture(attributes);
|
||||
m_framebuffer = std::make_unique<GLFramebuffer>(m_texture.get());
|
||||
}
|
||||
|
||||
|
@ -96,12 +72,13 @@ WaylandEglLayerBuffer::~WaylandEglLayerBuffer()
|
|||
m_texture.reset();
|
||||
m_framebuffer.reset();
|
||||
|
||||
if (m_buffer) {
|
||||
wl_buffer_destroy(m_buffer);
|
||||
}
|
||||
if (m_bo) {
|
||||
gbm_bo_destroy(m_bo);
|
||||
}
|
||||
m_graphicsBuffer->drop();
|
||||
}
|
||||
|
||||
GbmGraphicsBuffer *WaylandEglLayerBuffer::graphicsBuffer() const
|
||||
{
|
||||
return m_graphicsBuffer;
|
||||
}
|
||||
|
||||
wl_buffer *WaylandEglLayerBuffer::buffer() const
|
||||
|
@ -124,17 +101,19 @@ int WaylandEglLayerBuffer::age() const
|
|||
return m_age;
|
||||
}
|
||||
|
||||
gbm_bo *WaylandEglLayerBuffer::bo() const
|
||||
{
|
||||
return m_bo;
|
||||
}
|
||||
|
||||
WaylandEglLayerSwapchain::WaylandEglLayerSwapchain(const QSize &size, uint32_t format, const QVector<uint64_t> &modifiers, WaylandEglBackend *backend)
|
||||
: m_backend(backend)
|
||||
, m_size(size)
|
||||
{
|
||||
GbmGraphicsBufferAllocator allocator(backend->backend()->gbmDevice());
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
m_buffers.append(std::make_shared<WaylandEglLayerBuffer>(size, format, modifiers, backend));
|
||||
GbmGraphicsBuffer *buffer = allocator.allocate(size, format, modifiers);
|
||||
if (!buffer) {
|
||||
qCWarning(KWIN_WAYLAND_BACKEND) << "Failed to allocate layer swapchain buffer";
|
||||
continue;
|
||||
}
|
||||
m_buffers.append(std::make_shared<WaylandEglLayerBuffer>(buffer, backend));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,12 +269,12 @@ bool WaylandEglCursorLayer::endFrame(const QRegion &renderedRegion, const QRegio
|
|||
|
||||
quint32 WaylandEglCursorLayer::format() const
|
||||
{
|
||||
return gbm_bo_get_format(m_buffer->bo());
|
||||
return m_buffer->graphicsBuffer()->dmabufAttributes().format;
|
||||
}
|
||||
|
||||
quint32 WaylandEglPrimaryLayer::format() const
|
||||
{
|
||||
return gbm_bo_get_format(m_buffer->bo());
|
||||
return m_buffer->graphicsBuffer()->dmabufAttributes().format;
|
||||
}
|
||||
|
||||
WaylandEglBackend::WaylandEglBackend(WaylandBackend *b)
|
||||
|
|
|
@ -25,6 +25,7 @@ struct gbm_bo;
|
|||
namespace KWin
|
||||
{
|
||||
class GLFramebuffer;
|
||||
class GbmGraphicsBuffer;
|
||||
|
||||
namespace Wayland
|
||||
{
|
||||
|
@ -35,19 +36,18 @@ class WaylandEglBackend;
|
|||
class WaylandEglLayerBuffer
|
||||
{
|
||||
public:
|
||||
WaylandEglLayerBuffer(const QSize &size, uint32_t format, const QVector<uint64_t> &modifiers, WaylandEglBackend *backend);
|
||||
WaylandEglLayerBuffer(GbmGraphicsBuffer *buffer, WaylandEglBackend *backend);
|
||||
~WaylandEglLayerBuffer();
|
||||
|
||||
GbmGraphicsBuffer *graphicsBuffer() const;
|
||||
wl_buffer *buffer() const;
|
||||
GLFramebuffer *framebuffer() const;
|
||||
std::shared_ptr<GLTexture> texture() const;
|
||||
int age() const;
|
||||
gbm_bo *bo() const;
|
||||
|
||||
private:
|
||||
WaylandEglBackend *m_backend;
|
||||
GbmGraphicsBuffer *m_graphicsBuffer;
|
||||
wl_buffer *m_buffer = nullptr;
|
||||
gbm_bo *m_bo = nullptr;
|
||||
std::unique_ptr<GLFramebuffer> m_framebuffer;
|
||||
std::shared_ptr<GLTexture> m_texture;
|
||||
int m_age = 0;
|
||||
|
|
123
src/core/gbmgraphicsbufferallocator.cpp
Normal file
123
src/core/gbmgraphicsbufferallocator.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "core/gbmgraphicsbufferallocator.h"
|
||||
#include "backends/drm/gbm_dmabuf.h" // FIXME: move dmaBufAttributesForBo() elsewhere
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
#include <gbm.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
GbmGraphicsBufferAllocator::GbmGraphicsBufferAllocator(gbm_device *device)
|
||||
: m_gbmDevice(device)
|
||||
{
|
||||
}
|
||||
|
||||
GbmGraphicsBufferAllocator::~GbmGraphicsBufferAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
GbmGraphicsBuffer *GbmGraphicsBufferAllocator::allocate(const QSize &size, uint32_t format, const QVector<uint64_t> &modifiers)
|
||||
{
|
||||
gbm_bo *bo = nullptr;
|
||||
|
||||
if (!modifiers.isEmpty() && !(modifiers.size() == 1 && modifiers.first() == DRM_FORMAT_MOD_INVALID)) {
|
||||
bo = gbm_bo_create_with_modifiers(m_gbmDevice,
|
||||
size.width(),
|
||||
size.height(),
|
||||
format,
|
||||
modifiers.constData(),
|
||||
modifiers.size());
|
||||
}
|
||||
|
||||
if (!bo) {
|
||||
bo = gbm_bo_create(m_gbmDevice,
|
||||
size.width(),
|
||||
size.height(),
|
||||
format,
|
||||
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
||||
}
|
||||
|
||||
if (!bo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new GbmGraphicsBuffer(bo, size, format);
|
||||
}
|
||||
|
||||
static bool alphaChannelFromDrmFormat(uint32_t drmFormat)
|
||||
{
|
||||
switch (drmFormat) {
|
||||
case DRM_FORMAT_ARGB4444:
|
||||
case DRM_FORMAT_ABGR4444:
|
||||
case DRM_FORMAT_RGBA4444:
|
||||
case DRM_FORMAT_BGRA4444:
|
||||
|
||||
case DRM_FORMAT_ARGB1555:
|
||||
case DRM_FORMAT_ABGR1555:
|
||||
case DRM_FORMAT_RGBA5551:
|
||||
case DRM_FORMAT_BGRA5551:
|
||||
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
case DRM_FORMAT_ABGR8888:
|
||||
case DRM_FORMAT_RGBA8888:
|
||||
case DRM_FORMAT_BGRA8888:
|
||||
|
||||
case DRM_FORMAT_ARGB2101010:
|
||||
case DRM_FORMAT_ABGR2101010:
|
||||
case DRM_FORMAT_RGBA1010102:
|
||||
case DRM_FORMAT_BGRA1010102:
|
||||
|
||||
case DRM_FORMAT_XRGB8888_A8:
|
||||
case DRM_FORMAT_XBGR8888_A8:
|
||||
case DRM_FORMAT_RGBX8888_A8:
|
||||
case DRM_FORMAT_BGRX8888_A8:
|
||||
case DRM_FORMAT_RGB888_A8:
|
||||
case DRM_FORMAT_BGR888_A8:
|
||||
case DRM_FORMAT_RGB565_A8:
|
||||
case DRM_FORMAT_BGR565_A8:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GbmGraphicsBuffer::GbmGraphicsBuffer(gbm_bo *handle, const QSize &size, uint32_t format)
|
||||
: m_bo(handle)
|
||||
, m_dmabufAttributes(dmaBufAttributesForBo(handle))
|
||||
, m_size(size)
|
||||
, m_hasAlphaChannel(alphaChannelFromDrmFormat(format))
|
||||
{
|
||||
}
|
||||
|
||||
GbmGraphicsBuffer::~GbmGraphicsBuffer()
|
||||
{
|
||||
gbm_bo_destroy(m_bo);
|
||||
}
|
||||
|
||||
QSize GbmGraphicsBuffer::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
bool GbmGraphicsBuffer::hasAlphaChannel() const
|
||||
{
|
||||
return m_hasAlphaChannel;
|
||||
}
|
||||
|
||||
GraphicsBuffer::Origin GbmGraphicsBuffer::origin() const
|
||||
{
|
||||
return Origin::TopLeft;
|
||||
}
|
||||
|
||||
const DmaBufAttributes &GbmGraphicsBuffer::dmabufAttributes() const
|
||||
{
|
||||
return m_dmabufAttributes;
|
||||
}
|
||||
|
||||
} // namespace KWin
|
52
src/core/gbmgraphicsbufferallocator.h
Normal file
52
src/core/gbmgraphicsbufferallocator.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/dmabufattributes.h"
|
||||
#include "core/graphicsbuffer.h"
|
||||
#include "core/graphicsbufferallocator.h"
|
||||
|
||||
struct gbm_bo;
|
||||
struct gbm_device;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class KWIN_EXPORT GbmGraphicsBuffer : public GraphicsBuffer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GbmGraphicsBuffer(gbm_bo *handle, const QSize &size, uint32_t format);
|
||||
~GbmGraphicsBuffer() override;
|
||||
|
||||
QSize size() const override;
|
||||
bool hasAlphaChannel() const override;
|
||||
Origin origin() const override;
|
||||
|
||||
const DmaBufAttributes &dmabufAttributes() const;
|
||||
|
||||
private:
|
||||
gbm_bo *m_bo;
|
||||
DmaBufAttributes m_dmabufAttributes;
|
||||
QSize m_size;
|
||||
bool m_hasAlphaChannel;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT GbmGraphicsBufferAllocator : public GraphicsBufferAllocator
|
||||
{
|
||||
public:
|
||||
explicit GbmGraphicsBufferAllocator(gbm_device *device);
|
||||
~GbmGraphicsBufferAllocator() override;
|
||||
|
||||
GbmGraphicsBuffer *allocate(const QSize &size, uint32_t format, const QVector<uint64_t> &modifiers = {}) override;
|
||||
|
||||
private:
|
||||
gbm_device *m_gbmDevice;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
20
src/core/graphicsbufferallocator.cpp
Normal file
20
src/core/graphicsbufferallocator.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "core/graphicsbufferallocator.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
GraphicsBufferAllocator::GraphicsBufferAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
GraphicsBufferAllocator::~GraphicsBufferAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace KWin
|
28
src/core/graphicsbufferallocator.h
Normal file
28
src/core/graphicsbufferallocator.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kwin_export.h"
|
||||
|
||||
#include <QSize>
|
||||
#include <QVector>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class GraphicsBuffer;
|
||||
|
||||
class KWIN_EXPORT GraphicsBufferAllocator
|
||||
{
|
||||
public:
|
||||
GraphicsBufferAllocator();
|
||||
virtual ~GraphicsBufferAllocator();
|
||||
|
||||
virtual GraphicsBuffer *allocate(const QSize &size, uint32_t format, const QVector<uint64_t> &modifiers = {}) = 0;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
Loading…
Reference in a new issue