From 006ab40e4423d945d14a4f7114a8688cb155fe48 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sat, 20 May 2023 13:05:05 +0300 Subject: [PATCH] wayland: Make LinuxDmaBufV1ClientBuffer private dmabuf related code can rely on DmaBufAttributes instead, so let's make LinuxDmaBufV1ClientBuffer private to make graphics buffer handling generic. --- src/backends/drm/drm_buffer_gbm.cpp | 9 ++--- src/backends/drm/drm_buffer_gbm.h | 9 ++--- src/backends/drm/drm_dmabuf_feedback.cpp | 5 +-- src/backends/drm/drm_dmabuf_feedback.h | 1 - src/backends/drm/drm_egl_backend.cpp | 1 - src/backends/drm/drm_egl_layer.cpp | 6 ++-- src/backends/drm/drm_egl_layer_surface.cpp | 1 - src/backends/drm/drm_egl_layer_surface.h | 6 ---- src/backends/drm/drm_virtual_egl_layer.cpp | 5 ++- src/core/renderbackend.cpp | 2 +- src/core/renderbackend.h | 8 ++--- .../scenes/opengl/abstract_egl_backend.cpp | 5 +-- .../scenes/opengl/abstract_egl_backend.h | 6 ++-- .../opengl/basiceglsurfacetexture_wayland.cpp | 13 ++++--- .../opengl/basiceglsurfacetexture_wayland.h | 6 ++-- src/wayland/display.cpp | 2 +- src/wayland/linuxdmabufv1clientbuffer.h | 34 ------------------- src/wayland/linuxdmabufv1clientbuffer_p.h | 27 +++++++++++++++ 18 files changed, 60 insertions(+), 86 deletions(-) diff --git a/src/backends/drm/drm_buffer_gbm.cpp b/src/backends/drm/drm_buffer_gbm.cpp index c135529938..df25ddcf68 100644 --- a/src/backends/drm/drm_buffer_gbm.cpp +++ b/src/backends/drm/drm_buffer_gbm.cpp @@ -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 #include @@ -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::importBuffer(DrmGpu *gpu, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer) +std::shared_ptr GbmBuffer::importBuffer(DrmGpu *gpu, GraphicsBuffer *clientBuffer) { const auto *attrs = clientBuffer->dmabufAttributes(); gbm_bo *bo; diff --git a/src/backends/drm/drm_buffer_gbm.h b/src/backends/drm/drm_buffer_gbm.h index 3014d51c09..40fcc8aa49 100644 --- a/src/backends/drm/drm_buffer_gbm.h +++ b/src/backends/drm/drm_buffer_gbm.h @@ -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 &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 importBuffer(DrmGpu *gpu, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer); + static std::shared_ptr importBuffer(DrmGpu *gpu, GraphicsBuffer *clientBuffer); static std::shared_ptr importBuffer(DrmGpu *gpu, GbmBuffer *buffer, uint32_t flags = GBM_BO_USE_SCANOUT); private: diff --git a/src/backends/drm/drm_dmabuf_feedback.cpp b/src/backends/drm/drm_dmabuf_feedback.cpp index a87a3f3038..b000e228d3 100644 --- a/src/backends/drm/drm_dmabuf_feedback.cpp +++ b/src/backends/drm/drm_dmabuf_feedback.cpp @@ -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(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 scanoutTranches; diff --git a/src/backends/drm/drm_dmabuf_feedback.h b/src/backends/drm/drm_dmabuf_feedback.h index a4590e5e76..1b63a6210c 100644 --- a/src/backends/drm/drm_dmabuf_feedback.h +++ b/src/backends/drm/drm_dmabuf_feedback.h @@ -15,7 +15,6 @@ namespace KWaylandServer { class SurfaceInterface; -class LinuxDmaBufV1ClientBuffer; } namespace KWin diff --git a/src/backends/drm/drm_egl_backend.cpp b/src/backends/drm/drm_egl_backend.cpp index ef44a84e2a..61efa5c596 100644 --- a/src/backends/drm/drm_egl_backend.cpp +++ b/src/backends/drm/drm_egl_backend.cpp @@ -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" diff --git a/src/backends/drm/drm_egl_layer.cpp b/src/backends/drm/drm_egl_layer.cpp index dd38e06cb5..f675f2a118 100644 --- a/src/backends/drm/drm_egl_layer.cpp +++ b/src/backends/drm/drm_egl_layer.cpp @@ -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 @@ -113,12 +112,15 @@ bool EglGbmLayer::scanout(SurfaceItem *surfaceItem) if (surface->bufferTransform() != m_pipeline->output()->transform()) { return false; } - const auto buffer = qobject_cast(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)) { diff --git a/src/backends/drm/drm_egl_layer_surface.cpp b/src/backends/drm/drm_egl_layer_surface.cpp index 71b1887e0e..dd46169957 100644 --- a/src/backends/drm/drm_egl_layer_surface.cpp +++ b/src/backends/drm/drm_egl_layer_surface.cpp @@ -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 diff --git a/src/backends/drm/drm_egl_layer_surface.h b/src/backends/drm/drm_egl_layer_surface.h index 32d6a62462..eee2b241d9 100644 --- a/src/backends/drm/drm_egl_layer_surface.h +++ b/src/backends/drm/drm_egl_layer_surface.h @@ -18,12 +18,6 @@ #include "drm_plane.h" #include "libkwineffects/kwingltexture.h" -namespace KWaylandServer -{ -class SurfaceInterface; -class LinuxDmaBufV1ClientBuffer; -} - struct gbm_bo; namespace KWin diff --git a/src/backends/drm/drm_virtual_egl_layer.cpp b/src/backends/drm/drm_virtual_egl_layer.cpp index 17d1acf872..abdedf61b3 100644 --- a/src/backends/drm/drm_virtual_egl_layer.cpp +++ b/src/backends/drm/drm_virtual_egl_layer.cpp @@ -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 @@ -149,8 +148,8 @@ bool VirtualEglGbmLayer::scanout(SurfaceItem *surfaceItem) if (!item || !item->surface()) { return false; } - const auto buffer = qobject_cast(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); diff --git a/src/core/renderbackend.cpp b/src/core/renderbackend.cpp index 9e7866420f..db81a60707 100644 --- a/src/core/renderbackend.cpp +++ b/src/core/renderbackend.cpp @@ -32,7 +32,7 @@ bool RenderBackend::checkGraphicsReset() return false; } -bool RenderBackend::testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) +bool RenderBackend::testImportBuffer(GraphicsBuffer *buffer) { return false; } diff --git a/src/core/renderbackend.h b/src/core/renderbackend.h index 37ced87281..f782e35ff0 100644 --- a/src/core/renderbackend.h +++ b/src/core/renderbackend.h @@ -13,14 +13,10 @@ #include -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> supportedFormats() const; virtual std::unique_ptr createSurfaceTextureInternal(SurfacePixmapInternal *pixmap); diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index 1faa8215c3..6fa62de1b2 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -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 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; } diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.h b/src/platformsupport/scenes/opengl/abstract_egl_backend.h index a3fe8dbb57..89663e0718 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.h +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.h @@ -39,7 +39,7 @@ public: EglDisplay *eglDisplayObject() const; EglContext *contextObject(); - bool testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) override; + bool testImportBuffer(GraphicsBuffer *buffer) override; QHash> supportedFormats() const override; QVector tranches() const; @@ -48,7 +48,7 @@ public: std::shared_ptr 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 m_clientExtensions; const dev_t m_deviceId; QVector m_tranches; - QHash m_importedBuffers; + QHash m_importedBuffers; }; } diff --git a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp index 8eb2e97c10..b303b8c77f 100644 --- a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp +++ b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp @@ -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 @@ -35,8 +34,8 @@ AbstractEglBackend *BasicEGLSurfaceTextureWayland::backend() const bool BasicEGLSurfaceTextureWayland::create() { - if (auto buffer = qobject_cast(m_pixmap->buffer())) { - return loadDmabufTexture(buffer); + if (m_pixmap->buffer()->dmabufAttributes()) { + return loadDmabufTexture(m_pixmap->buffer()); } else if (auto buffer = qobject_cast(m_pixmap->buffer())) { return loadShmTexture(buffer); } else { @@ -52,8 +51,8 @@ void BasicEGLSurfaceTextureWayland::destroy() void BasicEGLSurfaceTextureWayland::update(const QRegion ®ion) { - if (auto buffer = qobject_cast(m_pixmap->buffer())) { - updateDmabufTexture(buffer); + if (m_pixmap->buffer()->dmabufAttributes()) { + updateDmabufTexture(m_pixmap->buffer()); } else if (auto buffer = qobject_cast(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(); diff --git a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.h b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.h index 779b154916..2897f9def4 100644 --- a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.h +++ b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.h @@ -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 ®ion); - bool loadDmabufTexture(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer); - void updateDmabufTexture(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer); + bool loadDmabufTexture(GraphicsBuffer *buffer); + void updateDmabufTexture(GraphicsBuffer *buffer); void destroy(); enum class BufferType { diff --git a/src/wayland/display.cpp b/src/wayland/display.cpp index bef455fdbb..a58243a72b 100644 --- a/src/wayland/display.cpp +++ b/src/wayland/display.cpp @@ -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" diff --git a/src/wayland/linuxdmabufv1clientbuffer.h b/src/wayland/linuxdmabufv1clientbuffer.h index 47a68d735d..ba240bd62c 100644 --- a/src/wayland/linuxdmabufv1clientbuffer.h +++ b/src/wayland/linuxdmabufv1clientbuffer.h @@ -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 diff --git a/src/wayland/linuxdmabufv1clientbuffer_p.h b/src/wayland/linuxdmabufv1clientbuffer_p.h index 17dc5d7e7c..1316466fc7 100644 --- a/src/wayland/linuxdmabufv1clientbuffer_p.h +++ b/src/wayland/linuxdmabufv1clientbuffer_p.h @@ -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: