wayland: Make LinuxDmaBufV1ClientBuffer private

dmabuf related code can rely on DmaBufAttributes instead, so let's make
LinuxDmaBufV1ClientBuffer private to make graphics buffer handling
generic.
This commit is contained in:
Vlad Zahorodnii 2023-05-20 13:05:05 +03:00
parent 6b2f46ca1f
commit 006ab40e44
18 changed files with 60 additions and 86 deletions

View file

@ -8,14 +8,15 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_buffer_gbm.h"
#include "drm_gbm_swapchain.h"
#include "config-kwin.h"
#include "core/graphicsbuffer.h"
#include "drm_gbm_swapchain.h"
#include "drm_backend.h"
#include "drm_gpu.h"
#include "drm_logging.h"
#include "kwineglutils_p.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
#include <cerrno>
#include <drm_fourcc.h>
@ -82,7 +83,7 @@ GbmBuffer::GbmBuffer(DrmGpu *gpu, gbm_bo *bo, uint32_t flags)
{
}
GbmBuffer::GbmBuffer(DrmGpu *gpu, gbm_bo *bo, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer, uint32_t flags)
GbmBuffer::GbmBuffer(DrmGpu *gpu, gbm_bo *bo, GraphicsBuffer *clientBuffer, uint32_t flags)
: DrmGpuBuffer(gpu, QSize(gbm_bo_get_width(bo), gbm_bo_get_height(bo)), gbm_bo_get_format(bo), gbm_bo_get_modifier(bo), getHandles(bo), getStrides(bo), getOffsets(bo), gbm_bo_get_plane_count(bo))
, m_bo(bo)
, m_clientBuffer(clientBuffer)
@ -155,7 +156,7 @@ void GbmBuffer::createFds()
#endif
}
std::shared_ptr<GbmBuffer> GbmBuffer::importBuffer(DrmGpu *gpu, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer)
std::shared_ptr<GbmBuffer> GbmBuffer::importBuffer(DrmGpu *gpu, GraphicsBuffer *clientBuffer)
{
const auto *attrs = clientBuffer->dmabufAttributes();
gbm_bo *bo;

View file

@ -17,11 +17,6 @@
struct gbm_bo;
namespace KWaylandServer
{
class LinuxDmaBufV1ClientBuffer;
}
namespace KWin
{
@ -35,7 +30,7 @@ class GbmBuffer : public DrmGpuBuffer
public:
GbmBuffer(DrmGpu *gpu, gbm_bo *bo, uint32_t flags);
GbmBuffer(gbm_bo *bo, const std::shared_ptr<GbmSwapchain> &swapchain);
GbmBuffer(DrmGpu *gpu, gbm_bo *bo, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer, uint32_t flags);
GbmBuffer(DrmGpu *gpu, gbm_bo *bo, GraphicsBuffer *clientBuffer, uint32_t flags);
~GbmBuffer() override;
gbm_bo *bo() const;
@ -45,7 +40,7 @@ public:
bool map(uint32_t flags);
static std::shared_ptr<GbmBuffer> importBuffer(DrmGpu *gpu, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer);
static std::shared_ptr<GbmBuffer> importBuffer(DrmGpu *gpu, GraphicsBuffer *clientBuffer);
static std::shared_ptr<GbmBuffer> importBuffer(DrmGpu *gpu, GbmBuffer *buffer, uint32_t flags = GBM_BO_USE_SCANOUT);
private:

View file

@ -10,7 +10,6 @@
#include "drm_egl_backend.h"
#include "drm_gpu.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
#include "wayland/surface_interface.h"
namespace KWin
@ -55,9 +54,7 @@ void DmabufFeedback::scanoutFailed(KWaylandServer::SurfaceInterface *surface, co
m_surface = surface;
}
if (const auto &feedback = m_surface->dmabufFeedbackV1()) {
const auto buffer = qobject_cast<KWaylandServer::LinuxDmaBufV1ClientBuffer *>(surface->buffer());
Q_ASSERT(buffer);
const DmaBufAttributes *dmabufAttrs = buffer->dmabufAttributes();
const DmaBufAttributes *dmabufAttrs = surface->buffer()->dmabufAttributes();
if (!m_attemptedFormats[dmabufAttrs->format].contains(dmabufAttrs->modifier)) {
m_attemptedFormats[dmabufAttrs->format] << dmabufAttrs->modifier;
QVector<KWaylandServer::LinuxDmaBufV1Feedback::Tranche> scanoutTranches;

View file

@ -15,7 +15,6 @@
namespace KWaylandServer
{
class SurfaceInterface;
class LinuxDmaBufV1ClientBuffer;
}
namespace KWin

View file

@ -28,7 +28,6 @@
#include "options.h"
#include "scene/surfaceitem_wayland.h"
#include "wayland/clientconnection.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
#include "wayland/surface_interface.h"
// kwin libs
#include "libkwineffects/kwineglimagetexture.h"

View file

@ -16,7 +16,6 @@
#include "drm_output.h"
#include "drm_pipeline.h"
#include "scene/surfaceitem_wayland.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
#include "wayland/surface_interface.h"
#include <QRegion>
@ -113,12 +112,15 @@ bool EglGbmLayer::scanout(SurfaceItem *surfaceItem)
if (surface->bufferTransform() != m_pipeline->output()->transform()) {
return false;
}
const auto buffer = qobject_cast<KWaylandServer::LinuxDmaBufV1ClientBuffer *>(surface->buffer());
const auto buffer = surface->buffer();
if (!buffer) {
return false;
}
const DmaBufAttributes *dmabufAttributes = buffer->dmabufAttributes();
if (!dmabufAttributes) {
return false;
}
const auto formats = m_pipeline->formats();
if (!formats.contains(dmabufAttributes->format)) {

View file

@ -21,7 +21,6 @@
#include "kwineglutils_p.h"
#include "libkwineffects/kwinglplatform.h"
#include "scene/surfaceitem_wayland.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
#include "wayland/surface_interface.h"
#include <drm_fourcc.h>

View file

@ -18,12 +18,6 @@
#include "drm_plane.h"
#include "libkwineffects/kwingltexture.h"
namespace KWaylandServer
{
class SurfaceInterface;
class LinuxDmaBufV1ClientBuffer;
}
struct gbm_bo;
namespace KWin

View file

@ -20,7 +20,6 @@
#include "gbm_dmabuf.h"
#include "kwineglutils_p.h"
#include "scene/surfaceitem_wayland.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
#include "wayland/surface_interface.h"
#include <QRegion>
@ -149,8 +148,8 @@ bool VirtualEglGbmLayer::scanout(SurfaceItem *surfaceItem)
if (!item || !item->surface()) {
return false;
}
const auto buffer = qobject_cast<KWaylandServer::LinuxDmaBufV1ClientBuffer *>(item->surface()->buffer());
if (!buffer || buffer->size() != m_output->modeSize()) {
const auto buffer = item->surface()->buffer();
if (!buffer || !buffer->dmabufAttributes() || buffer->size() != m_output->modeSize()) {
return false;
}
const auto scanoutBuffer = GbmBuffer::importBuffer(m_output->gpu(), buffer);

View file

@ -32,7 +32,7 @@ bool RenderBackend::checkGraphicsReset()
return false;
}
bool RenderBackend::testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer)
bool RenderBackend::testImportBuffer(GraphicsBuffer *buffer)
{
return false;
}

View file

@ -13,14 +13,10 @@
#include <memory>
namespace KWaylandServer
{
class LinuxDmaBufV1ClientBuffer;
}
namespace KWin
{
class GraphicsBuffer;
class Output;
class OverlayWindow;
class OutputLayer;
@ -48,7 +44,7 @@ public:
virtual OutputLayer *cursorLayer(Output *output);
virtual void present(Output *output) = 0;
virtual bool testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer);
virtual bool testImportBuffer(GraphicsBuffer *buffer);
virtual QHash<uint32_t, QVector<uint64_t>> supportedFormats() const;
virtual std::unique_ptr<SurfaceTexture> createSurfaceTextureInternal(SurfacePixmapInternal *pixmap);

View file

@ -280,13 +280,14 @@ bool AbstractEglBackend::prefer10bpc() const
return false;
}
EGLImageKHR AbstractEglBackend::importBufferAsImage(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer)
EGLImageKHR AbstractEglBackend::importBufferAsImage(GraphicsBuffer *buffer)
{
auto it = m_importedBuffers.constFind(buffer);
if (Q_LIKELY(it != m_importedBuffers.constEnd())) {
return *it;
}
Q_ASSERT(buffer->dmabufAttributes());
EGLImageKHR image = importDmaBufAsImage(*buffer->dmabufAttributes());
if (image != EGL_NO_IMAGE_KHR) {
m_importedBuffers[buffer] = image;
@ -308,7 +309,7 @@ std::shared_ptr<GLTexture> AbstractEglBackend::importDmaBufAsTexture(const DmaBu
return m_context->importDmaBufAsTexture(attributes);
}
bool AbstractEglBackend::testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer)
bool AbstractEglBackend::testImportBuffer(GraphicsBuffer *buffer)
{
return importBufferAsImage(buffer) != EGL_NO_IMAGE_KHR;
}

View file

@ -39,7 +39,7 @@ public:
EglDisplay *eglDisplayObject() const;
EglContext *contextObject();
bool testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) override;
bool testImportBuffer(GraphicsBuffer *buffer) override;
QHash<uint32_t, QVector<uint64_t>> supportedFormats() const override;
QVector<KWaylandServer::LinuxDmaBufV1Feedback::Tranche> tranches() const;
@ -48,7 +48,7 @@ public:
std::shared_ptr<GLTexture> importDmaBufAsTexture(const DmaBufAttributes &attributes) const;
EGLImageKHR importDmaBufAsImage(const DmaBufAttributes &attributes) const;
EGLImageKHR importBufferAsImage(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer);
EGLImageKHR importBufferAsImage(GraphicsBuffer *buffer);
protected:
AbstractEglBackend(dev_t deviceId = 0);
@ -76,7 +76,7 @@ private:
QList<QByteArray> m_clientExtensions;
const dev_t m_deviceId;
QVector<KWaylandServer::LinuxDmaBufV1Feedback::Tranche> m_tranches;
QHash<KWaylandServer::LinuxDmaBufV1ClientBuffer *, EGLImageKHR> m_importedBuffers;
QHash<GraphicsBuffer *, EGLImageKHR> m_importedBuffers;
};
}

View file

@ -9,7 +9,6 @@
#include "platformsupport/scenes/opengl/abstract_egl_backend.h"
#include "scene/surfaceitem_wayland.h"
#include "utils/common.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
#include "wayland/shmclientbuffer.h"
#include <epoxy/egl.h>
@ -35,8 +34,8 @@ AbstractEglBackend *BasicEGLSurfaceTextureWayland::backend() const
bool BasicEGLSurfaceTextureWayland::create()
{
if (auto buffer = qobject_cast<KWaylandServer::LinuxDmaBufV1ClientBuffer *>(m_pixmap->buffer())) {
return loadDmabufTexture(buffer);
if (m_pixmap->buffer()->dmabufAttributes()) {
return loadDmabufTexture(m_pixmap->buffer());
} else if (auto buffer = qobject_cast<KWaylandServer::ShmClientBuffer *>(m_pixmap->buffer())) {
return loadShmTexture(buffer);
} else {
@ -52,8 +51,8 @@ void BasicEGLSurfaceTextureWayland::destroy()
void BasicEGLSurfaceTextureWayland::update(const QRegion &region)
{
if (auto buffer = qobject_cast<KWaylandServer::LinuxDmaBufV1ClientBuffer *>(m_pixmap->buffer())) {
updateDmabufTexture(buffer);
if (m_pixmap->buffer()->dmabufAttributes()) {
updateDmabufTexture(m_pixmap->buffer());
} else if (auto buffer = qobject_cast<KWaylandServer::ShmClientBuffer *>(m_pixmap->buffer())) {
updateShmTexture(buffer, region);
}
@ -94,7 +93,7 @@ void BasicEGLSurfaceTextureWayland::updateShmTexture(KWaylandServer::ShmClientBu
}
}
bool BasicEGLSurfaceTextureWayland::loadDmabufTexture(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer)
bool BasicEGLSurfaceTextureWayland::loadDmabufTexture(GraphicsBuffer *buffer)
{
EGLImageKHR image = backend()->importBufferAsImage(buffer);
if (Q_UNLIKELY(image == EGL_NO_IMAGE_KHR)) {
@ -116,7 +115,7 @@ bool BasicEGLSurfaceTextureWayland::loadDmabufTexture(KWaylandServer::LinuxDmaBu
return true;
}
void BasicEGLSurfaceTextureWayland::updateDmabufTexture(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer)
void BasicEGLSurfaceTextureWayland::updateDmabufTexture(GraphicsBuffer *buffer)
{
if (Q_UNLIKELY(m_bufferType != BufferType::DmaBuf)) {
destroy();

View file

@ -11,13 +11,13 @@
namespace KWaylandServer
{
class ShmClientBuffer;
class LinuxDmaBufV1ClientBuffer;
}
namespace KWin
{
class AbstractEglBackend;
class GraphicsBuffer;
class KWIN_EXPORT BasicEGLSurfaceTextureWayland : public OpenGLSurfaceTextureWayland
{
@ -33,8 +33,8 @@ public:
private:
bool loadShmTexture(KWaylandServer::ShmClientBuffer *buffer);
void updateShmTexture(KWaylandServer::ShmClientBuffer *buffer, const QRegion &region);
bool loadDmabufTexture(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer);
void updateDmabufTexture(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer);
bool loadDmabufTexture(GraphicsBuffer *buffer);
void updateDmabufTexture(GraphicsBuffer *buffer);
void destroy();
enum class BufferType {

View file

@ -6,7 +6,7 @@
*/
#include "display.h"
#include "display_p.h"
#include "linuxdmabufv1clientbuffer.h"
#include "linuxdmabufv1clientbuffer_p.h"
#include "output_interface.h"
#include "shmclientbuffer.h"
#include "utils/common.h"

View file

@ -24,43 +24,9 @@ namespace KWaylandServer
{
class Display;
class LinuxDmaBufV1ClientBufferPrivate;
class LinuxDmaBufV1ClientBufferIntegrationPrivate;
class LinuxDmaBufV1FeedbackPrivate;
/**
* The LinuxDmaBufV1ClientBuffer class represents a linux dma-buf client buffer.
*
* The LinuxDmaBufV1ClientBuffer can be used even after the underlying wl_buffer object
* is destroyed by the client.
*/
class KWIN_EXPORT LinuxDmaBufV1ClientBuffer : public KWin::GraphicsBuffer
{
Q_OBJECT
public:
LinuxDmaBufV1ClientBuffer(KWin::DmaBufAttributes &&attrs);
QSize size() const override;
bool hasAlphaChannel() const override;
const KWin::DmaBufAttributes *dmabufAttributes() const override;
static LinuxDmaBufV1ClientBuffer *get(wl_resource *resource);
private:
void initialize(wl_resource *resource);
static void buffer_destroy_resource(wl_resource *resource);
static void buffer_destroy(wl_client *client, wl_resource *resource);
static const struct wl_buffer_interface implementation;
wl_resource *m_resource = nullptr;
KWin::DmaBufAttributes m_attrs;
bool m_hasAlphaChannel = false;
friend class LinuxDmaBufParamsV1;
};
class KWIN_EXPORT LinuxDmaBufV1Feedback : public QObject
{
Q_OBJECT

View file

@ -75,6 +75,33 @@ private:
bool m_isUsed = false;
};
class LinuxDmaBufV1ClientBuffer : public KWin::GraphicsBuffer
{
Q_OBJECT
public:
LinuxDmaBufV1ClientBuffer(KWin::DmaBufAttributes &&attrs);
QSize size() const override;
bool hasAlphaChannel() const override;
const KWin::DmaBufAttributes *dmabufAttributes() const override;
static LinuxDmaBufV1ClientBuffer *get(wl_resource *resource);
private:
void initialize(wl_resource *resource);
static void buffer_destroy_resource(wl_resource *resource);
static void buffer_destroy(wl_client *client, wl_resource *resource);
static const struct wl_buffer_interface implementation;
wl_resource *m_resource = nullptr;
KWin::DmaBufAttributes m_attrs;
bool m_hasAlphaChannel = false;
friend class LinuxDmaBufParamsV1;
};
class LinuxDmaBufV1FormatTable
{
public: