From 9bbe0cc4acf846968540aa5b847a7e9d4c5c0168 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Mon, 5 Jun 2023 13:27:58 +0300 Subject: [PATCH] core: Allow GbmGraphicsBufferAllocator allocate dumb buffers The drm backend needs to allocate both dmabuf and dumb buffers, for example for multi-gpu import. Allowing GbmGraphicsBufferAllocator to allocate dumb buffers allows us to avoid using several buffer allocators in the drm backend. --- src/core/gbmgraphicsbufferallocator.cpp | 37 ++++++++++++++++++++++++- src/core/gbmgraphicsbufferallocator.h | 5 ++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/core/gbmgraphicsbufferallocator.cpp b/src/core/gbmgraphicsbufferallocator.cpp index 57a4ef6360..f2aaed852b 100644 --- a/src/core/gbmgraphicsbufferallocator.cpp +++ b/src/core/gbmgraphicsbufferallocator.cpp @@ -25,6 +25,20 @@ GbmGraphicsBufferAllocator::~GbmGraphicsBufferAllocator() GbmGraphicsBuffer *GbmGraphicsBufferAllocator::allocate(const GraphicsBufferOptions &options) { if (options.software) { + gbm_bo *bo = gbm_bo_create(m_gbmDevice, + options.size.width(), + options.size.height(), + options.format, + GBM_BO_USE_SCANOUT | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR); + if (bo) { + std::optional attributes = dmaBufAttributesForBo(bo); + if (!attributes.has_value()) { + gbm_bo_destroy(bo); + return nullptr; + } + attributes->modifier = DRM_FORMAT_MOD_LINEAR; + return new GbmGraphicsBuffer(std::move(attributes.value()), bo); + } return nullptr; } @@ -48,7 +62,7 @@ GbmGraphicsBuffer *GbmGraphicsBufferAllocator::allocate(const GraphicsBufferOpti uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; if (options.modifiers.size() == 1 && options.modifiers.first() == DRM_FORMAT_MOD_LINEAR) { flags |= GBM_BO_USE_LINEAR; - } else if (!modifiers.contains(DRM_FORMAT_MOD_INVALID)) { + } else if (!modifiers.isEmpty() && !modifiers.contains(DRM_FORMAT_MOD_INVALID)) { return nullptr; } @@ -84,6 +98,7 @@ GbmGraphicsBuffer::GbmGraphicsBuffer(DmaBufAttributes attributes, gbm_bo *handle GbmGraphicsBuffer::~GbmGraphicsBuffer() { + unmap(); gbm_bo_destroy(m_bo); } @@ -102,4 +117,24 @@ const DmaBufAttributes *GbmGraphicsBuffer::dmabufAttributes() const return &m_dmabufAttributes; } +void *GbmGraphicsBuffer::map() +{ + if (m_mapPtr) { + return m_mapPtr; + } + + uint32_t stride = 0; + m_mapPtr = gbm_bo_map(m_bo, 0, 0, m_dmabufAttributes.width, m_dmabufAttributes.height, GBM_BO_TRANSFER_READ_WRITE, &stride, &m_mapData); + return m_mapPtr; +} + +void GbmGraphicsBuffer::unmap() +{ + if (m_mapPtr) { + gbm_bo_unmap(m_bo, m_mapData); + m_mapPtr = nullptr; + m_mapData = nullptr; + } +} + } // namespace KWin diff --git a/src/core/gbmgraphicsbufferallocator.h b/src/core/gbmgraphicsbufferallocator.h index ae9091538f..0a37d58f80 100644 --- a/src/core/gbmgraphicsbufferallocator.h +++ b/src/core/gbmgraphicsbufferallocator.h @@ -27,8 +27,13 @@ public: bool hasAlphaChannel() const override; const DmaBufAttributes *dmabufAttributes() const override; + void *map() override; + void unmap() override; + private: gbm_bo *m_bo; + void *m_mapPtr = nullptr; + void *m_mapData = nullptr; DmaBufAttributes m_dmabufAttributes; QSize m_size; bool m_hasAlphaChannel;