diff --git a/src/backends/drm/drm_backend.cpp b/src/backends/drm/drm_backend.cpp index b00d72f21c..429ea41855 100644 --- a/src/backends/drm/drm_backend.cpp +++ b/src/backends/drm/drm_backend.cpp @@ -658,16 +658,13 @@ std::shared_ptr DrmBackend::createDmaBufTexture(const QSize &size } // The bo will be kept around until the last fd is closed. - const DmaBufAttributes attributes = dmaBufAttributesForBo(bo); + DmaBufAttributes attributes = dmaBufAttributesForBo(bo); gbm_bo_destroy(bo); const auto eglBackend = static_cast(m_renderBackend); eglBackend->makeCurrent(); if (auto texture = eglBackend->importDmaBufAsTexture(attributes)) { - return std::make_shared(texture, attributes); + return std::make_shared(texture, std::move(attributes)); } else { - for (int i = 0; i < attributes.planeCount; ++i) { - ::close(attributes.fd[i]); - } return nullptr; } } diff --git a/src/backends/drm/drm_buffer_gbm.cpp b/src/backends/drm/drm_buffer_gbm.cpp index 272afe7684..d4e73f86ae 100644 --- a/src/backends/drm/drm_buffer_gbm.cpp +++ b/src/backends/drm/drm_buffer_gbm.cpp @@ -152,7 +152,7 @@ void GbmBuffer::createFds() std::shared_ptr GbmBuffer::importBuffer(DrmGpu *gpu, KWaylandServer::LinuxDmaBufV1ClientBuffer *clientBuffer) { - const auto attrs = clientBuffer->attributes(); + const auto &attrs = clientBuffer->attributes(); gbm_bo *bo; if (attrs.modifier != DRM_FORMAT_MOD_INVALID || attrs.offset[0] > 0 || attrs.planeCount > 1) { gbm_import_fd_modifier_data data = {}; @@ -162,14 +162,14 @@ std::shared_ptr GbmBuffer::importBuffer(DrmGpu *gpu, KWaylandServer:: data.num_fds = attrs.planeCount; data.modifier = attrs.modifier; for (int i = 0; i < attrs.planeCount; i++) { - data.fds[i] = attrs.fd[i]; + data.fds[i] = attrs.fd[i].get(); data.offsets[i] = attrs.offset[i]; data.strides[i] = attrs.pitch[i]; } bo = gbm_bo_import(gpu->gbmDevice(), GBM_BO_IMPORT_FD_MODIFIER, &data, GBM_BO_USE_SCANOUT); } else { gbm_import_fd_data data = {}; - data.fd = attrs.fd[0]; + data.fd = attrs.fd[0].get(); data.width = static_cast(attrs.width); data.height = static_cast(attrs.height); data.stride = attrs.pitch[0]; diff --git a/src/backends/drm/drm_dmabuf_feedback.cpp b/src/backends/drm/drm_dmabuf_feedback.cpp index d34cc3ff78..2914badce9 100644 --- a/src/backends/drm/drm_dmabuf_feedback.cpp +++ b/src/backends/drm/drm_dmabuf_feedback.cpp @@ -58,7 +58,7 @@ void DmabufFeedback::scanoutFailed(KWaylandServer::SurfaceInterface *surface, co if (const auto &feedback = m_surface->dmabufFeedbackV1()) { const auto buffer = qobject_cast(surface->buffer()); Q_ASSERT(buffer); - const DmaBufAttributes dmabufAttrs = buffer->attributes(); + const DmaBufAttributes &dmabufAttrs = buffer->attributes(); if (!m_attemptedFormats[dmabufAttrs.format].contains(dmabufAttrs.modifier)) { m_attemptedFormats[dmabufAttrs.format] << dmabufAttrs.modifier; QVector scanoutTranches; diff --git a/src/backends/drm/drm_egl_backend.cpp b/src/backends/drm/drm_egl_backend.cpp index 3f9e0a7814..bb55e86f50 100644 --- a/src/backends/drm/drm_egl_backend.cpp +++ b/src/backends/drm/drm_egl_backend.cpp @@ -263,14 +263,7 @@ bool operator==(const GbmFormat &lhs, const GbmFormat &rhs) EGLImageKHR EglGbmBackend::importBufferObjectAsImage(gbm_bo *bo) { - const DmaBufAttributes dmabuf = dmaBufAttributesForBo(bo); - EGLImage image = importDmaBufAsImage(dmabuf); - - for (int i = 0; i < dmabuf.planeCount; ++i) { - close(dmabuf.fd[i]); - } - - return image; + return importDmaBufAsImage(dmaBufAttributesForBo(bo)); } std::shared_ptr EglGbmBackend::importBufferObjectAsTexture(gbm_bo *bo) diff --git a/src/backends/drm/gbm_dmabuf.h b/src/backends/drm/gbm_dmabuf.h index cf64ad98f4..d6cbcf3e5f 100644 --- a/src/backends/drm/gbm_dmabuf.h +++ b/src/backends/drm/gbm_dmabuf.h @@ -26,7 +26,7 @@ inline DmaBufAttributes dmaBufAttributesForBo(gbm_bo *bo) #if HAVE_GBM_BO_GET_FD_FOR_PLANE for (int i = 0; i < attributes.planeCount; ++i) { - attributes.fd[i] = gbm_bo_get_fd_for_plane(bo, i); + attributes.fd[i] = FileDescriptor{gbm_bo_get_fd_for_plane(bo, i)}; attributes.offset[i] = gbm_bo_get_offset(bo, i); attributes.pitch[i] = gbm_bo_get_stride_for_plane(bo, i); } diff --git a/src/backends/wayland/wayland_backend.cpp b/src/backends/wayland/wayland_backend.cpp index ce07689aba..7e47c24bd2 100644 --- a/src/backends/wayland/wayland_backend.cpp +++ b/src/backends/wayland/wayland_backend.cpp @@ -1008,10 +1008,10 @@ std::shared_ptr WaylandBackend::createDmaBufTexture(const QSize & } // The bo will be kept around until the last fd is closed. - const DmaBufAttributes attributes = dmaBufAttributesForBo(bo); + DmaBufAttributes attributes = dmaBufAttributesForBo(bo); gbm_bo_destroy(bo); m_eglBackend->makeCurrent(); - return std::make_shared(m_eglBackend->importDmaBufAsTexture(attributes), attributes); + return std::make_shared(m_eglBackend->importDmaBufAsTexture(attributes), std::move(attributes)); } } diff --git a/src/dmabufattributes.h b/src/dmabufattributes.h index 86d4cc876e..ea2a85b93b 100644 --- a/src/dmabufattributes.h +++ b/src/dmabufattributes.h @@ -6,6 +6,7 @@ #pragma once +#include "utils/filedescriptor.h" #include namespace KWin @@ -28,7 +29,7 @@ struct DmaBufAttributes uint32_t format = 0; uint64_t modifier = 0; - int fd[4] = {-1, -1, -1, -1}; + FileDescriptor fd[4]; int offset[4] = {0, 0, 0, 0}; int pitch[4] = {0, 0, 0, 0}; }; diff --git a/src/dmabuftexture.cpp b/src/dmabuftexture.cpp index 6e916630ff..572748b95c 100644 --- a/src/dmabuftexture.cpp +++ b/src/dmabuftexture.cpp @@ -13,21 +13,15 @@ namespace KWin { -DmaBufTexture::DmaBufTexture(std::shared_ptr texture, const DmaBufAttributes &attributes) +DmaBufTexture::DmaBufTexture(std::shared_ptr texture, DmaBufAttributes &&attributes) : m_texture(texture) , m_framebuffer(std::make_unique(texture.get())) - , m_attributes(attributes) + , m_attributes(std::move(attributes)) { } +DmaBufTexture::~DmaBufTexture() = default; -DmaBufTexture::~DmaBufTexture() -{ - for (int i = 0; i < m_attributes.planeCount; ++i) { - ::close(m_attributes.fd[i]); - } -} - -DmaBufAttributes DmaBufTexture::attributes() const +const DmaBufAttributes &DmaBufTexture::attributes() const { return m_attributes; } diff --git a/src/dmabuftexture.h b/src/dmabuftexture.h index 1fa0e8e2ee..fab641c5cc 100644 --- a/src/dmabuftexture.h +++ b/src/dmabuftexture.h @@ -20,10 +20,10 @@ class GLTexture; class KWIN_EXPORT DmaBufTexture { public: - explicit DmaBufTexture(std::shared_ptr texture, const DmaBufAttributes &attributes); + explicit DmaBufTexture(std::shared_ptr texture, DmaBufAttributes &&attributes); virtual ~DmaBufTexture(); - DmaBufAttributes attributes() const; + const DmaBufAttributes &attributes() const; GLTexture *texture() const; GLFramebuffer *framebuffer() const; diff --git a/src/linux_dmabuf.cpp b/src/linux_dmabuf.cpp index bf7415311b..f02d9c8f29 100644 --- a/src/linux_dmabuf.cpp +++ b/src/linux_dmabuf.cpp @@ -13,8 +13,8 @@ namespace KWin { -LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(const DmaBufAttributes &attrs, quint32 flags) - : KWaylandServer::LinuxDmaBufV1ClientBuffer(attrs, flags) +LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(DmaBufAttributes &&attrs, quint32 flags) + : KWaylandServer::LinuxDmaBufV1ClientBuffer(std::move(attrs), flags) { waylandServer()->addLinuxDmabufBuffer(this); } @@ -37,7 +37,7 @@ LinuxDmaBufV1RendererInterface::~LinuxDmaBufV1RendererInterface() waylandServer()->linuxDmabuf()->setRendererInterface(nullptr); } -KWaylandServer::LinuxDmaBufV1ClientBuffer *LinuxDmaBufV1RendererInterface::importBuffer(const DmaBufAttributes &attrs, quint32 flags) +KWaylandServer::LinuxDmaBufV1ClientBuffer *LinuxDmaBufV1RendererInterface::importBuffer(DmaBufAttributes &&attrs, quint32 flags) { Q_UNUSED(attrs) Q_UNUSED(flags) diff --git a/src/linux_dmabuf.h b/src/linux_dmabuf.h index 6f49ddd8fa..2ffd84ecab 100644 --- a/src/linux_dmabuf.h +++ b/src/linux_dmabuf.h @@ -18,7 +18,7 @@ namespace KWin class KWIN_EXPORT LinuxDmaBufV1ClientBuffer : public KWaylandServer::LinuxDmaBufV1ClientBuffer { public: - LinuxDmaBufV1ClientBuffer(const DmaBufAttributes &attrs, quint32 flags); + LinuxDmaBufV1ClientBuffer(DmaBufAttributes &&attrs, quint32 flags); ~LinuxDmaBufV1ClientBuffer() override; }; @@ -28,7 +28,7 @@ public: explicit LinuxDmaBufV1RendererInterface(); ~LinuxDmaBufV1RendererInterface() override; - KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(const DmaBufAttributes &attrs, quint32 flags) override; + KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(DmaBufAttributes &&attrs, quint32 flags) override; protected: void setSupportedFormatsAndModifiers(const QVector &tranches); diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index 7292e59b01..41d69a595a 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -407,7 +407,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab << EGL_LINUX_DRM_FOURCC_EXT << dmabuf.format; attribs - << EGL_DMA_BUF_PLANE0_FD_EXT << dmabuf.fd[0] + << EGL_DMA_BUF_PLANE0_FD_EXT << dmabuf.fd[0].get() << EGL_DMA_BUF_PLANE0_OFFSET_EXT << dmabuf.offset[0] << EGL_DMA_BUF_PLANE0_PITCH_EXT << dmabuf.pitch[0]; if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) { @@ -418,7 +418,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab if (dmabuf.planeCount > 1) { attribs - << EGL_DMA_BUF_PLANE1_FD_EXT << dmabuf.fd[1] + << EGL_DMA_BUF_PLANE1_FD_EXT << dmabuf.fd[1].get() << EGL_DMA_BUF_PLANE1_OFFSET_EXT << dmabuf.offset[1] << EGL_DMA_BUF_PLANE1_PITCH_EXT << dmabuf.pitch[1]; if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) { @@ -430,7 +430,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab if (dmabuf.planeCount > 2) { attribs - << EGL_DMA_BUF_PLANE2_FD_EXT << dmabuf.fd[2] + << EGL_DMA_BUF_PLANE2_FD_EXT << dmabuf.fd[2].get() << EGL_DMA_BUF_PLANE2_OFFSET_EXT << dmabuf.offset[2] << EGL_DMA_BUF_PLANE2_PITCH_EXT << dmabuf.pitch[2]; if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) { @@ -442,7 +442,7 @@ EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmab if (dmabuf.planeCount > 3) { attribs - << EGL_DMA_BUF_PLANE3_FD_EXT << dmabuf.fd[3] + << EGL_DMA_BUF_PLANE3_FD_EXT << dmabuf.fd[3].get() << EGL_DMA_BUF_PLANE3_OFFSET_EXT << dmabuf.offset[3] << EGL_DMA_BUF_PLANE3_PITCH_EXT << dmabuf.pitch[3]; if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) { diff --git a/src/platformsupport/scenes/opengl/egl_dmabuf.cpp b/src/platformsupport/scenes/opengl/egl_dmabuf.cpp index 7345236bd9..d240d54c50 100644 --- a/src/platformsupport/scenes/opengl/egl_dmabuf.cpp +++ b/src/platformsupport/scenes/opengl/egl_dmabuf.cpp @@ -91,22 +91,23 @@ YuvFormat yuvFormats[] = { 2}}}}; EglDmabufBuffer::EglDmabufBuffer(EGLImage image, - const DmaBufAttributes &attrs, + DmaBufAttributes &&attrs, quint32 flags, EglDmabuf *interfaceImpl) - : EglDmabufBuffer(attrs, flags, interfaceImpl) + : EglDmabufBuffer(QVector{image}, std::move(attrs), flags, interfaceImpl) { m_importType = ImportType::Direct; - addImage(image); } -EglDmabufBuffer::EglDmabufBuffer(const DmaBufAttributes &attrs, +EglDmabufBuffer::EglDmabufBuffer(const QVector &images, + DmaBufAttributes &&attrs, quint32 flags, EglDmabuf *interfaceImpl) - : LinuxDmaBufV1ClientBuffer(attrs, flags) + : LinuxDmaBufV1ClientBuffer(std::move(attrs), flags) + , m_images(images) , m_interfaceImpl(interfaceImpl) + , m_importType(ImportType::Conversion) { - m_importType = ImportType::Conversion; } EglDmabufBuffer::~EglDmabufBuffer() @@ -119,9 +120,9 @@ void EglDmabufBuffer::setInterfaceImplementation(EglDmabuf *interfaceImpl) m_interfaceImpl = interfaceImpl; } -void EglDmabufBuffer::addImage(EGLImage image) +void EglDmabufBuffer::setImages(const QVector &images) { - m_images << image; + m_images = images; } void EglDmabufBuffer::removeImages() @@ -132,13 +133,13 @@ void EglDmabufBuffer::removeImages() m_images.clear(); } -KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::importBuffer(const DmaBufAttributes &attrs, quint32 flags) +KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::importBuffer(DmaBufAttributes &&attrs, quint32 flags) { Q_ASSERT(attrs.planeCount > 0); // Try first to import as a single image if (auto *img = m_backend->importDmaBufAsImage(attrs)) { - return new EglDmabufBuffer(img, attrs, flags, this); + return new EglDmabufBuffer(img, std::move(attrs), flags, this); } // TODO: to enable this we must be able to store multiple textures per window pixmap @@ -149,7 +150,7 @@ KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::importBuffer(const DmaBufA return nullptr; } -KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::yuvImport(const DmaBufAttributes &attrs, quint32 flags) +KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::yuvImport(DmaBufAttributes &&attrs, quint32 flags) { YuvFormat yuvFormat; for (YuvFormat f : yuvFormats) { @@ -165,29 +166,27 @@ KWaylandServer::LinuxDmaBufV1ClientBuffer *EglDmabuf::yuvImport(const DmaBufAttr return nullptr; } - auto *buf = new EglDmabufBuffer(attrs, flags, this); - + QVector images; for (int i = 0; i < yuvFormat.outputPlanes; i++) { const int planeIndex = yuvFormat.planes[i].planeIndex; - const DmaBufAttributes planeAttrs { + const DmaBufAttributes planeAttrs{ .planeCount = 1, .width = attrs.width / yuvFormat.planes[i].widthDivisor, .height = attrs.height / yuvFormat.planes[i].heightDivisor, .format = yuvFormat.planes[i].format, .modifier = attrs.modifier, - .fd = {attrs.fd[planeIndex], -1, -1, -1}, + .fd = {attrs.fd[planeIndex].duplicate()}, .offset = {attrs.offset[planeIndex], 0, 0, 0}, .pitch = {attrs.pitch[planeIndex], 0, 0, 0}, }; auto *image = m_backend->importDmaBufAsImage(planeAttrs); if (!image) { - delete buf; return nullptr; } - buf->addImage(image); + images.push_back(image); } - // TODO: add buf import properties - return buf; + + return new EglDmabufBuffer(images, std::move(attrs), flags, this); } EglDmabuf *EglDmabuf::factory(AbstractEglBackend *backend) @@ -215,7 +214,7 @@ EglDmabuf::EglDmabuf(AbstractEglBackend *backend) for (auto *buffer : prevBuffersSet) { auto *buf = static_cast(buffer); buf->setInterfaceImplementation(this); - buf->addImage(m_backend->importDmaBufAsImage(buf->attributes())); + buf->setImages({m_backend->importDmaBufAsImage(buf->attributes())}); } setSupportedFormatsAndModifiers(); } diff --git a/src/platformsupport/scenes/opengl/egl_dmabuf.h b/src/platformsupport/scenes/opengl/egl_dmabuf.h index 22c1fb7aa4..e3b21ae7e4 100644 --- a/src/platformsupport/scenes/opengl/egl_dmabuf.h +++ b/src/platformsupport/scenes/opengl/egl_dmabuf.h @@ -28,18 +28,19 @@ public: }; EglDmabufBuffer(EGLImage image, - const DmaBufAttributes &attrs, + DmaBufAttributes &&attrs, quint32 flags, EglDmabuf *interfaceImpl); - EglDmabufBuffer(const DmaBufAttributes &attrs, + EglDmabufBuffer(const QVector &images, + DmaBufAttributes &&attrs, quint32 flags, EglDmabuf *interfaceImpl); ~EglDmabufBuffer() override; void setInterfaceImplementation(EglDmabuf *interfaceImpl); - void addImage(EGLImage image); + void setImages(const QVector &images); void removeImages(); QVector images() const @@ -61,7 +62,7 @@ public: explicit EglDmabuf(AbstractEglBackend *backend); ~EglDmabuf() override; - KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(const DmaBufAttributes &attrs, quint32 flags) override; + KWaylandServer::LinuxDmaBufV1ClientBuffer *importBuffer(DmaBufAttributes &&attrs, quint32 flags) override; QVector tranches() const { @@ -69,7 +70,7 @@ public: } private: - KWaylandServer::LinuxDmaBufV1ClientBuffer *yuvImport(const DmaBufAttributes &attrs, quint32 flags); + KWaylandServer::LinuxDmaBufV1ClientBuffer *yuvImport(DmaBufAttributes &&attrs, quint32 flags); void setSupportedFormatsAndModifiers(); diff --git a/src/plugins/screencast/screencaststream.cpp b/src/plugins/screencast/screencaststream.cpp index 787ca1e266..2bf9330cdd 100644 --- a/src/plugins/screencast/screencaststream.cpp +++ b/src/plugins/screencast/screencaststream.cpp @@ -192,11 +192,11 @@ void ScreenCastStream::onStreamAddBuffer(void *data, pw_buffer *buffer) if (dmabuff) { spa_data->maxsize = dmabuff->attributes().pitch[0] * stream->m_resolution.height(); - const DmaBufAttributes dmabufAttribs = dmabuff->attributes(); + const DmaBufAttributes &dmabufAttribs = dmabuff->attributes(); Q_ASSERT(buffer->buffer->n_datas >= uint(dmabufAttribs.planeCount)); for (int i = 0; i < dmabufAttribs.planeCount; ++i) { buffer->buffer->datas[i].type = SPA_DATA_DmaBuf; - buffer->buffer->datas[i].fd = dmabufAttribs.fd[i]; + buffer->buffer->datas[i].fd = dmabufAttribs.fd[i].get(); buffer->buffer->datas[i].data = nullptr; } stream->m_dmabufDataForPwBuffer.insert(buffer, dmabuff); @@ -450,7 +450,7 @@ void ScreenCastStream::recordFrame(const QRegion &damagedRegion) auto &buf = m_dmabufDataForPwBuffer[buffer]; Q_ASSERT(buf); - const DmaBufAttributes dmabufAttribs = buf->attributes(); + const DmaBufAttributes &dmabufAttribs = buf->attributes(); Q_ASSERT(buffer->buffer->n_datas >= uint(dmabufAttribs.planeCount)); for (int i = 0; i < dmabufAttribs.planeCount; ++i) { buffer->buffer->datas[i].chunk->stride = dmabufAttribs.pitch[i]; diff --git a/src/utils/filedescriptor.cpp b/src/utils/filedescriptor.cpp index fbffecd132..b854e80cef 100644 --- a/src/utils/filedescriptor.cpp +++ b/src/utils/filedescriptor.cpp @@ -40,7 +40,7 @@ FileDescriptor::~FileDescriptor() } } -FileDescriptor::operator bool() const +bool FileDescriptor::isValid() const { return m_fd != -1; } diff --git a/src/utils/filedescriptor.h b/src/utils/filedescriptor.h index 0522e70087..308f5e0b67 100644 --- a/src/utils/filedescriptor.h +++ b/src/utils/filedescriptor.h @@ -22,7 +22,7 @@ public: FileDescriptor &operator=(FileDescriptor &&); ~FileDescriptor(); - explicit operator bool() const; + bool isValid() const; int get() const; FileDescriptor duplicate() const; diff --git a/src/wayland/linuxdmabufv1clientbuffer.cpp b/src/wayland/linuxdmabufv1clientbuffer.cpp index d905bae394..006f3c66ce 100644 --- a/src/wayland/linuxdmabufv1clientbuffer.cpp +++ b/src/wayland/linuxdmabufv1clientbuffer.cpp @@ -90,15 +90,6 @@ LinuxDmaBufParamsV1::LinuxDmaBufParamsV1(LinuxDmaBufV1ClientBufferIntegration *i { } -LinuxDmaBufParamsV1::~LinuxDmaBufParamsV1() -{ - for (int i = 0; i < m_attrs.planeCount; ++i) { - if (m_attrs.fd[i] != -1) { - close(m_attrs.fd[i]); - } - } -} - void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_destroy_resource(Resource *resource) { Q_UNUSED(resource) @@ -130,13 +121,12 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_add(Resource *resource, return; } - if (Q_UNLIKELY(m_attrs.fd[plane_idx] != -1)) { + if (Q_UNLIKELY(m_attrs.fd[plane_idx].isValid())) { wl_resource_post_error(resource->handle, error_plane_set, "the plane index %d was already set", plane_idx); close(fd); return; } - - m_attrs.fd[plane_idx] = fd; + m_attrs.fd[plane_idx] = KWin::FileDescriptor{fd}; m_attrs.offset[plane_idx] = offset; m_attrs.pitch[plane_idx] = stride; m_attrs.modifier = (quint64(modifier_hi) << 32) | modifier_lo; @@ -160,14 +150,12 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_create(Resource *resource, m_attrs.height = height; m_attrs.format = format; - LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(m_attrs, flags); + LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(std::move(m_attrs), flags); if (!clientBuffer) { send_failed(resource->handle); return; } - m_attrs = KWin::DmaBufAttributes{}; // the ownership of file descriptors has been moved to the buffer - wl_resource *bufferResource = wl_resource_create(resource->client(), &wl_buffer_interface, 1, 0); if (!bufferResource) { delete clientBuffer; @@ -204,14 +192,12 @@ void LinuxDmaBufParamsV1::zwp_linux_buffer_params_v1_create_immed(Resource *reso m_attrs.height = height; m_attrs.format = format; - LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(m_attrs, flags); + LinuxDmaBufV1ClientBuffer *clientBuffer = m_integration->rendererInterface()->importBuffer(std::move(m_attrs), flags); if (!clientBuffer) { wl_resource_post_error(resource->handle, error_invalid_wl_buffer, "importing the supplied dmabufs failed"); return; } - m_attrs = KWin::DmaBufAttributes{}; // the ownership of file descriptors has been moved to the buffer - wl_resource *bufferResource = wl_resource_create(resource->client(), &wl_buffer_interface, 1, buffer_id); if (!bufferResource) { delete clientBuffer; @@ -234,7 +220,7 @@ bool LinuxDmaBufParamsV1::test(Resource *resource, uint32_t width, uint32_t heig // Check for holes in the dmabuf set (e.g. [0, 1, 3]). for (int i = 0; i < m_attrs.planeCount; ++i) { - if (m_attrs.fd[i] == -1) { + if (!m_attrs.fd[i].isValid()) { wl_resource_post_error(resource->handle, error_incomplete, "no dmabuf has been added for plane %d", i); return false; } @@ -259,7 +245,7 @@ bool LinuxDmaBufParamsV1::test(Resource *resource, uint32_t width, uint32_t heig // Don't report an error as it might be caused by the kernel not supporting // seeking on dmabuf. - const off_t size = lseek(m_attrs.fd[i], 0, SEEK_END); + const off_t size = lseek(m_attrs.fd[i].get(), 0, SEEK_END); if (size == -1) { continue; } @@ -366,25 +352,16 @@ void LinuxDmaBufV1ClientBufferPrivate::buffer_destroy(Resource *resource) wl_resource_destroy(resource->handle); } -LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(const KWin::DmaBufAttributes &attrs, quint32 flags) +LinuxDmaBufV1ClientBuffer::LinuxDmaBufV1ClientBuffer(KWin::DmaBufAttributes &&attrs, quint32 flags) : ClientBuffer(*new LinuxDmaBufV1ClientBufferPrivate) { Q_D(LinuxDmaBufV1ClientBuffer); - d->attrs = attrs; + d->attrs = std::move(attrs); d->flags = flags; d->hasAlphaChannel = testAlphaChannel(attrs.format); } -LinuxDmaBufV1ClientBuffer::~LinuxDmaBufV1ClientBuffer() -{ - Q_D(LinuxDmaBufV1ClientBuffer); - for (int i = 0; i < d->attrs.planeCount; ++i) { - if (d->attrs.fd[i] != -1) { - close(d->attrs.fd[i]); - d->attrs.fd[i] = -1; - } - } -} +LinuxDmaBufV1ClientBuffer::~LinuxDmaBufV1ClientBuffer() = default; void LinuxDmaBufV1ClientBuffer::initialize(wl_resource *resource) { @@ -405,7 +382,7 @@ quint32 LinuxDmaBufV1ClientBuffer::flags() const return d->flags; } -KWin::DmaBufAttributes LinuxDmaBufV1ClientBuffer::attributes() const +const KWin::DmaBufAttributes &LinuxDmaBufV1ClientBuffer::attributes() const { Q_D(const LinuxDmaBufV1ClientBuffer); return d->attrs; @@ -463,7 +440,7 @@ LinuxDmaBufV1FeedbackPrivate::LinuxDmaBufV1FeedbackPrivate(LinuxDmaBufV1ClientBu void LinuxDmaBufV1FeedbackPrivate::send(Resource *resource) { - send_format_table(resource->handle, m_bufferintegration->table->fd, m_bufferintegration->table->size); + send_format_table(resource->handle, m_bufferintegration->table->fd.get(), m_bufferintegration->table->size); QByteArray bytes; bytes.append(reinterpret_cast(&m_bufferintegration->mainDevice), sizeof(dev_t)); send_main_device(resource->handle, bytes); @@ -529,8 +506,8 @@ LinuxDmaBufV1FormatTable::LinuxDmaBufV1FormatTable(const QHasherrorString(); return; } - fd = open(tmp->fileName().toUtf8().constData(), O_RDONLY | O_CLOEXEC); - if (fd < 0) { + fd = KWin::FileDescriptor(open(tmp->fileName().toUtf8().constData(), O_RDONLY | O_CLOEXEC)); + if (!fd.isValid()) { qCWarning(KWIN_CORE) << "Could not create readonly shm fd!" << strerror(errno); return; } @@ -547,11 +524,4 @@ LinuxDmaBufV1FormatTable::LinuxDmaBufV1FormatTable(const QHash> &supportedModifiers); - ~LinuxDmaBufV1FormatTable(); - int fd = -1; + KWin::FileDescriptor fd; int size; QMap, uint16_t> indices; };