From ecf26a14682d06729dfb68f516172bb09b326646 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Fri, 31 Jan 2025 10:04:40 +0100 Subject: [PATCH] core: make SDMABUFAttrs use CFileDescriptor change SDMABUFAttrs use CFileDescriptor for its fd, change to use const references to the attrs, and its related usage. requires compositor patch. --- include/aquamarine/allocator/DRMDumb.hpp | 2 +- include/aquamarine/allocator/GBM.hpp | 3 ++- include/aquamarine/buffer/Buffer.hpp | 22 ++++++++++++---------- src/allocator/DRMDumb.cpp | 5 +++-- src/allocator/GBM.cpp | 17 +++++++---------- src/backend/Wayland.cpp | 8 ++++---- src/backend/drm/DRM.cpp | 16 ++++++++-------- src/backend/drm/Renderer.cpp | 12 ++++++------ src/backend/drm/impl/Legacy.cpp | 8 ++++---- src/buffer/Buffer.cpp | 4 ++-- 10 files changed, 49 insertions(+), 48 deletions(-) diff --git a/include/aquamarine/allocator/DRMDumb.hpp b/include/aquamarine/allocator/DRMDumb.hpp index a5eca2c..d087b66 100644 --- a/include/aquamarine/allocator/DRMDumb.hpp +++ b/include/aquamarine/allocator/DRMDumb.hpp @@ -16,7 +16,7 @@ namespace Aquamarine { virtual void update(const Hyprutils::Math::CRegion& damage); virtual bool isSynchronous(); virtual bool good(); - virtual SDMABUFAttrs dmabuf(); + virtual const SDMABUFAttrs& dmabuf() const; virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); diff --git a/include/aquamarine/allocator/GBM.hpp b/include/aquamarine/allocator/GBM.hpp index 09e6cb9..1452064 100644 --- a/include/aquamarine/allocator/GBM.hpp +++ b/include/aquamarine/allocator/GBM.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include "Allocator.hpp" struct gbm_device; @@ -19,7 +20,7 @@ namespace Aquamarine { virtual void update(const Hyprutils::Math::CRegion& damage); virtual bool isSynchronous(); virtual bool good(); - virtual SDMABUFAttrs dmabuf(); + virtual const SDMABUFAttrs& dmabuf() const; virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); diff --git a/include/aquamarine/buffer/Buffer.hpp b/include/aquamarine/buffer/Buffer.hpp index a96008f..0b52b6f 100644 --- a/include/aquamarine/buffer/Buffer.hpp +++ b/include/aquamarine/buffer/Buffer.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "../misc/Attachment.hpp" namespace Aquamarine { @@ -19,15 +20,15 @@ namespace Aquamarine { }; struct SDMABUFAttrs { - bool success = false; - Hyprutils::Math::Vector2D size; - uint32_t format = 0; // fourcc - uint64_t modifier = 0; + bool success = false; + Hyprutils::Math::Vector2D size; + uint32_t format = 0; // fourcc + uint64_t modifier = 0; - int planes = 1; - std::array offsets = {0}; - std::array strides = {0}; - std::array fds = {-1, -1, -1, -1}; + int planes = 1; + std::array offsets = {0}; + std::array strides = {0}; + std::array fds; }; struct SSHMAttrs { @@ -50,7 +51,7 @@ namespace Aquamarine { virtual void update(const Hyprutils::Math::CRegion& damage) = 0; virtual bool isSynchronous() = 0; // whether the updates to this buffer are synchronous, aka happen over cpu virtual bool good() = 0; - virtual SDMABUFAttrs dmabuf(); + virtual const SDMABUFAttrs& dmabuf() const; virtual SSHMAttrs shm(); virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); @@ -71,7 +72,8 @@ namespace Aquamarine { } events; private: - int locks = 0; + SDMABUFAttrs m_attrs{}; + int locks = 0; }; }; diff --git a/src/allocator/DRMDumb.cpp b/src/allocator/DRMDumb.cpp index ca4d911..7fbad36 100644 --- a/src/allocator/DRMDumb.cpp +++ b/src/allocator/DRMDumb.cpp @@ -14,6 +14,7 @@ using namespace Aquamarine; using namespace Hyprutils::Memory; +using namespace Hyprutils::OS; #define SP CSharedPointer #define WP CWeakPointer @@ -53,7 +54,7 @@ Aquamarine::CDRMDumbBuffer::CDRMDumbBuffer(const SAllocatorBufferParams& params, return; } - attrs.fds.at(0) = primeFD; + attrs.fds.at(0) = CFileDescriptor{primeFD}; attrs.success = true; @@ -94,7 +95,7 @@ bool Aquamarine::CDRMDumbBuffer::good() { return attrs.success && data; } -SDMABUFAttrs Aquamarine::CDRMDumbBuffer::dmabuf() { +const SDMABUFAttrs& Aquamarine::CDRMDumbBuffer::dmabuf() const { return attrs; } diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index d5f69db..fa53bc8 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -12,6 +12,7 @@ using namespace Aquamarine; using namespace Hyprutils::Memory; +using namespace Hyprutils::OS; #define SP CSharedPointer static SDRMFormat guessFormatFrom(std::vector formats, bool cursor, bool scanout) { @@ -195,13 +196,13 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti for (size_t i = 0; i < (size_t)attrs.planes; ++i) { attrs.strides.at(i) = gbm_bo_get_stride_for_plane(bo, i); attrs.offsets.at(i) = gbm_bo_get_offset(bo, i); - attrs.fds.at(i) = gbm_bo_get_fd_for_plane(bo, i); + attrs.fds.at(i) = CFileDescriptor{gbm_bo_get_fd_for_plane(bo, i)}; - if (attrs.fds.at(i) < 0) { + if (!attrs.fds.at(i).isValid()) { allocator->backend->log(AQ_LOG_ERROR, std::format("GBM: Failed to query fd for plane {}", i)); - for (size_t j = 0; j < i; ++j) { - close(attrs.fds.at(j)); - } + for (size_t j = 0; j < i; ++j) + attrs.fds.at(j).reset(); + attrs.planes = 0; return; } @@ -226,10 +227,6 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti } Aquamarine::CGBMBuffer::~CGBMBuffer() { - for (size_t i = 0; i < (size_t)attrs.planes; i++) { - close(attrs.fds.at(i)); - } - events.destroy.emit(); if (bo) { if (gboMapping) @@ -258,7 +255,7 @@ bool Aquamarine::CGBMBuffer::good() { return bo; } -SDMABUFAttrs Aquamarine::CGBMBuffer::dmabuf() { +const SDMABUFAttrs& Aquamarine::CGBMBuffer::dmabuf() const { return attrs; } diff --git a/src/backend/Wayland.cpp b/src/backend/Wayland.cpp index f7648cc..c8f2790 100644 --- a/src/backend/Wayland.cpp +++ b/src/backend/Wayland.cpp @@ -709,11 +709,11 @@ bool Aquamarine::CWaylandOutput::setCursor(Hyprutils::Memory::CSharedPointerdmabuf(); attrs.success) { + } else if (const auto& attrs = buffer->dmabuf(); attrs.success) { auto params = makeShared(backend->waylandState.dmabuf->sendCreateParams()); for (int i = 0; i < attrs.planes; ++i) { - params->sendAdd(attrs.fds.at(i), i, attrs.offsets.at(i), attrs.strides.at(i), attrs.modifier >> 32, attrs.modifier & 0xFFFFFFFF); + params->sendAdd(attrs.fds.at(i).get(), i, attrs.offsets.at(i), attrs.strides.at(i), attrs.modifier >> 32, attrs.modifier & 0xFFFFFFFF); } cursorState.cursorWlBuffer = makeShared(params->sendCreateImmed(attrs.size.x, attrs.size.y, attrs.format, (zwpLinuxBufferParamsV1Flags)0)); @@ -781,10 +781,10 @@ Aquamarine::CWaylandBuffer::CWaylandBuffer(SP buffer_, Hyprutils::Memor return; } - auto attrs = buffer->dmabuf(); + const auto& attrs = buffer->dmabuf(); for (int i = 0; i < attrs.planes; ++i) { - params->sendAdd(attrs.fds.at(i), i, attrs.offsets.at(i), attrs.strides.at(i), attrs.modifier >> 32, attrs.modifier & 0xFFFFFFFF); + params->sendAdd(attrs.fds.at(i).get(), i, attrs.offsets.at(i), attrs.strides.at(i), attrs.modifier >> 32, attrs.modifier & 0xFFFFFFFF); } waylandState.buffer = makeShared(params->sendCreateImmed(attrs.size.x, attrs.size.y, attrs.format, (zwpLinuxBufferParamsV1Flags)0)); diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index b7b123b..ddf6790 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -1650,9 +1650,9 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) { mgpu.swapchain = CSwapchain::create(backend->rendererState.allocator, backend.lock()); } - auto OPTIONS = swapchain->currentOptions(); - auto bufDma = STATE.buffer->dmabuf(); - OPTIONS.size = STATE.buffer->size; + auto OPTIONS = swapchain->currentOptions(); + const auto& bufDma = STATE.buffer->dmabuf(); + OPTIONS.size = STATE.buffer->size; if (OPTIONS.format == DRM_FORMAT_INVALID) OPTIONS.format = bufDma.format; OPTIONS.multigpu = false; // this is not a shared swapchain, and additionally, don't make it linear, nvidia would be mad @@ -1699,7 +1699,7 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) { // sometimes, our consumer could f up the swapchain format and change it without the state changing bool formatMismatch = false; if (data.mainFB) { - if (const auto params = data.mainFB->buffer->dmabuf(); params.success && params.format != STATE.drmFormat) { + if (const auto& params = data.mainFB->buffer->dmabuf(); params.success && params.format != STATE.drmFormat) { // formats mismatch. Update the state format and roll with it backend->backend->log(AQ_LOG_WARNING, std::format("drm: Formats mismatch in commit, buffer is {} but output is set to {}. Modesetting to {}", fourccToName(params.format), @@ -1988,7 +1988,7 @@ Aquamarine::CDRMFB::CDRMFB(SP buffer_, Hyprutils::Memory::CWeakPointer< } void Aquamarine::CDRMFB::import() { - auto attrs = buffer->dmabuf(); + const auto& attrs = buffer->dmabuf(); if (!attrs.success) { backend->backend->log(AQ_LOG_ERROR, "drm: Buffer submitted has no dmabuf or a drm handle"); return; @@ -2001,14 +2001,14 @@ void Aquamarine::CDRMFB::import() { // TODO: check format for (int i = 0; i < attrs.planes; ++i) { - int ret = drmPrimeFDToHandle(backend->gpu->fd, attrs.fds.at(i), &boHandles[i]); + int ret = drmPrimeFDToHandle(backend->gpu->fd, attrs.fds.at(i).get(), &boHandles[i]); if (ret) { backend->backend->log(AQ_LOG_ERROR, "drm: drmPrimeFDToHandle failed"); drop(); return; } - TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("drm: CDRMFB: plane {} has fd {}, got handle {}", i, attrs.fds.at(i), boHandles.at(i)))); + TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("drm: CDRMFB: plane {} has fd {}, got handle {}", i, attrs.fds.at(i).get(), boHandles.at(i)))); } id = submitBuffer(); @@ -2101,7 +2101,7 @@ uint32_t Aquamarine::CDRMFB::submitBuffer() { if (!buffer->dmabuf().success) return 0; - auto attrs = buffer->dmabuf(); + const auto& attrs = buffer->dmabuf(); std::array mods = {0, 0, 0, 0}; for (int i = 0; i < attrs.planes; ++i) { mods[i] = attrs.modifier; diff --git a/src/backend/drm/Renderer.cpp b/src/backend/drm/Renderer.cpp index b0c7203..c74d409 100644 --- a/src/backend/drm/Renderer.cpp +++ b/src/backend/drm/Renderer.cpp @@ -637,7 +637,7 @@ EGLImageKHR CDRMRenderer::createEGLImage(const SDMABUFAttrs& attrs) { for (int i = 0; i < attrs.planes; i++) { attribs.push_back(attrNames[i].fd); - attribs.push_back(attrs.fds[i]); + attribs.push_back(attrs.fds[i].get()); attribs.push_back(attrNames[i].offset); attribs.push_back(attrs.offsets[i]); attribs.push_back(attrNames[i].pitch); @@ -665,9 +665,9 @@ EGLImageKHR CDRMRenderer::createEGLImage(const SDMABUFAttrs& attrs) { } SGLTex CDRMRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { - SGLTex tex; + SGLTex tex; - const auto dma = buffa->dmabuf(); + const auto& dma = buffa->dmabuf(); tex.image = createEGLImage(dma); if (tex.image == EGL_NO_IMAGE_KHR) { @@ -785,8 +785,8 @@ int CDRMRenderer::recreateBlitSync() { void CDRMRenderer::clearBuffer(IBuffer* buf) { setEGL(); - auto dmabuf = buf->dmabuf(); - GLuint rboID = 0, fboID = 0; + const auto& dmabuf = buf->dmabuf(); + GLuint rboID = 0, fboID = 0; if (!dmabuf.success) { backend->log(AQ_LOG_ERROR, "EGL (clear): cannot clear a non-dmabuf"); @@ -874,7 +874,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, i EGLImageKHR rboImage = nullptr; GLuint rboID = 0, fboID = 0; - auto toDma = to->dmabuf(); + const auto& toDma = to->dmabuf(); if (!verifyDestinationDMABUF(toDma)) { backend->log(AQ_LOG_ERROR, "EGL (blit): failed to blit: destination dmabuf unsupported"); diff --git a/src/backend/drm/impl/Legacy.cpp b/src/backend/drm/impl/Legacy.cpp index e9ac9a2..d51e24f 100644 --- a/src/backend/drm/impl/Legacy.cpp +++ b/src/backend/drm/impl/Legacy.cpp @@ -87,17 +87,17 @@ bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointe if (data.cursorFB && connector->crtc->cursor && connector->output->cursorVisible && enable && (STATE.committed & COutputState::AQ_OUTPUT_STATE_CURSOR_SHAPE || STATE.committed & COutputState::AQ_OUTPUT_STATE_CURSOR_POS)) { - uint32_t boHandle = 0; - auto attrs = data.cursorFB->buffer->dmabuf(); + uint32_t boHandle = 0; + const auto& attrs = data.cursorFB->buffer->dmabuf(); - if (int ret = drmPrimeFDToHandle(connector->backend->gpu->fd, attrs.fds.at(0), &boHandle); ret) { + if (int ret = drmPrimeFDToHandle(connector->backend->gpu->fd, attrs.fds.at(0).get(), &boHandle); ret) { connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: drmPrimeFDToHandle failed: {}", strerror(-ret))); return false; } connector->backend->backend->log(AQ_LOG_DEBUG, std::format("legacy drm: cursor fb: {} with bo handle {} from fd {}, size {}", connector->backend->gpu->fd, boHandle, - data.cursorFB->buffer->dmabuf().fds.at(0), data.cursorFB->buffer->size)); + data.cursorFB->buffer->dmabuf().fds.at(0).get(), data.cursorFB->buffer->size)); Vector2D cursorPos = connector->output->cursorPos; diff --git a/src/buffer/Buffer.cpp b/src/buffer/Buffer.cpp index 8197742..6d9b725 100644 --- a/src/buffer/Buffer.cpp +++ b/src/buffer/Buffer.cpp @@ -3,8 +3,8 @@ using namespace Aquamarine; -SDMABUFAttrs Aquamarine::IBuffer::dmabuf() { - return SDMABUFAttrs{}; +const SDMABUFAttrs& Aquamarine::IBuffer::dmabuf() const { + return m_attrs; } SSHMAttrs Aquamarine::IBuffer::shm() {