From b8d332cdcc130c27232f61369e7bab2d954e7ac6 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 12 Aug 2025 19:48:36 +0300 Subject: [PATCH] libcamera: framebuffer: Replace vector with span in constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FrameBuffer constructor takes a list of planes as an std::vector. The caller may stores the planes in a different type of container, resulting in the needless allocation of a temporary vector. Replace it with a span. Suggested-by: Daniel Rákos Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Barnabás Pőcze --- include/libcamera/framebuffer.h | 4 ++-- include/libcamera/internal/framebuffer.h | 3 ++- src/android/mm/cros_frame_buffer_allocator.cpp | 2 +- src/android/mm/generic_frame_buffer_allocator.cpp | 2 +- src/libcamera/framebuffer.cpp | 10 +++++----- src/libcamera/pipeline/ipu3/ipu3.cpp | 6 +++++- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 6 +++++- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 5 ++++- src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 6 ++++-- src/libcamera/pipeline/vimc/vimc.cpp | 5 ++++- src/libcamera/pipeline/virtual/virtual.cpp | 3 ++- src/libcamera/v4l2_videodevice.cpp | 6 +++--- 12 files changed, 38 insertions(+), 20 deletions(-) diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h index e83825b4..723525d0 100644 --- a/include/libcamera/framebuffer.h +++ b/include/libcamera/framebuffer.h @@ -58,11 +58,11 @@ public: unsigned int length; }; - FrameBuffer(const std::vector &planes, unsigned int cookie = 0); + FrameBuffer(Span planes, unsigned int cookie = 0); FrameBuffer(std::unique_ptr d); virtual ~FrameBuffer() {} - const std::vector &planes() const; + Span planes() const; Request *request() const; const FrameMetadata &metadata() const; diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h index 97b49d42..67b090fc 100644 --- a/include/libcamera/internal/framebuffer.h +++ b/include/libcamera/internal/framebuffer.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -23,7 +24,7 @@ class FrameBuffer::Private : public Extensible::Private LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) public: - Private(const std::vector &planes, uint64_t cookie = 0); + Private(Span planes, uint64_t cookie = 0); virtual ~Private(); void setRequest(Request *request) { request_ = request; } diff --git a/src/android/mm/cros_frame_buffer_allocator.cpp b/src/android/mm/cros_frame_buffer_allocator.cpp index 264c0d48..7ec116e1 100644 --- a/src/android/mm/cros_frame_buffer_allocator.cpp +++ b/src/android/mm/cros_frame_buffer_allocator.cpp @@ -29,7 +29,7 @@ class CrosFrameBufferData : public FrameBuffer::Private public: CrosFrameBufferData(cros::ScopedBufferHandle scopedHandle, - const std::vector &planes) + Span planes) : FrameBuffer::Private(planes), scopedHandle_(std::move(scopedHandle)) { } diff --git a/src/android/mm/generic_frame_buffer_allocator.cpp b/src/android/mm/generic_frame_buffer_allocator.cpp index 79625a9a..25ad6b03 100644 --- a/src/android/mm/generic_frame_buffer_allocator.cpp +++ b/src/android/mm/generic_frame_buffer_allocator.cpp @@ -35,7 +35,7 @@ class GenericFrameBufferData : public FrameBuffer::Private public: GenericFrameBufferData(struct alloc_device_t *allocDevice, buffer_handle_t handle, - const std::vector &planes) + Span planes) : FrameBuffer::Private(planes), allocDevice_(allocDevice), handle_(handle) { diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index 219db50d..765dab95 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -130,9 +130,9 @@ LOG_DEFINE_CATEGORY(Buffer) * \param[in] planes The frame memory planes * \param[in] cookie Cookie */ -FrameBuffer::Private::Private(const std::vector &planes, uint64_t cookie) - : planes_(planes), cookie_(cookie), request_(nullptr), - isContiguous_(true) +FrameBuffer::Private::Private(Span planes, uint64_t cookie) + : planes_(planes.begin(), planes.end()), cookie_(cookie), + request_(nullptr), isContiguous_(true) { metadata_.planes_.resize(planes_.size()); } @@ -315,7 +315,7 @@ ino_t fileDescriptorInode(const SharedFD &fd) * \param[in] planes The frame memory planes * \param[in] cookie Cookie */ -FrameBuffer::FrameBuffer(const std::vector &planes, unsigned int cookie) +FrameBuffer::FrameBuffer(Span planes, unsigned int cookie) : FrameBuffer(std::make_unique(planes, cookie)) { } @@ -365,7 +365,7 @@ FrameBuffer::FrameBuffer(std::unique_ptr d) * \brief Retrieve the static plane descriptors * \return Array of plane descriptors */ -const std::vector &FrameBuffer::planes() const +Span FrameBuffer::planes() const { return _d()->planes_; } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index bfbc80af..d6b7edcb 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -680,8 +680,12 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) auto pushBuffers = [&](const std::vector> &buffers) { for (const std::unique_ptr &buffer : buffers) { + Span planes = buffer->planes(); + buffer->setCookie(ipaBufferId++); - ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); + ipaBuffers_.emplace_back(buffer->cookie(), + std::vector{ planes.begin(), + planes.end() }); } }; diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 97996399..38bdc613 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1137,8 +1137,12 @@ int PipelineHandlerMaliC55::allocateBuffers(Camera *camera) std::queue &queue, std::vector &ipaBuffers) { for (const std::unique_ptr &buffer : buffers) { + Span planes = buffer->planes(); + buffer->setCookie(ipaBufferId++); - ipaBuffers.emplace_back(buffer->cookie(), buffer->planes()); + ipaBuffers.emplace_back(buffer->cookie(), + std::vector{ planes.begin(), + planes.end() }); queue.push(buffer.get()); } }; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 291f9683..cfcbb3b2 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1031,9 +1031,12 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) auto pushBuffers = [&](const std::vector> &buffers, std::queue &queue) { for (const std::unique_ptr &buffer : buffers) { + Span planes = buffer->planes(); + buffer->setCookie(ipaBufferId++); data->ipaBuffers_.emplace_back(buffer->cookie(), - buffer->planes()); + std::vector{ planes.begin(), + planes.end() }); queue.push(buffer.get()); } }; diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 09d30f34..c209aa59 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -883,8 +883,10 @@ void PipelineHandlerBase::mapBuffers(Camera *camera, const BufferMap &buffers, u * handler and the IPA. */ for (auto const &[id, buffer] : buffers) { - bufferIds.push_back(IPABuffer(mask | id, - buffer.buffer->planes())); + Span planes = buffer.buffer->planes(); + + bufferIds.emplace_back(mask | id, + std::vector{ planes.begin(), planes.end() }); data->bufferIds_.insert(mask | id); } diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 07273bd2..50221015 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -363,8 +363,11 @@ int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] const ControlLis /* Map the mock IPA buffers to VIMC IPA to exercise IPC code paths. */ std::vector ipaBuffers; for (auto [i, buffer] : utils::enumerate(data->mockIPABufs_)) { + Span planes = buffer->planes(); + buffer->setCookie(i + 1); - ipaBuffers.emplace_back(buffer->cookie(), buffer->planes()); + ipaBuffers.emplace_back(buffer->cookie(), + std::vector{ planes.begin(), planes.end() }); } data->ipa_->mapBuffers(ipaBuffers); diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 049ebcba..f9538129 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -315,7 +315,8 @@ int PipelineHandlerVirtual::queueRequestDevice([[maybe_unused]] Camera *camera, fmd.sequence = streamConfig.seq++; fmd.timestamp = timestamp; - for (const auto [i, p] : utils::enumerate(buffer->planes())) + Span planes = buffer->planes(); + for (const auto [i, p] : utils::enumerate(planes)) fmd.planes()[i].bytesused = p.length; found = true; diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index ba1889a9..7b48d911 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -288,7 +288,7 @@ V4L2BufferCache::Entry::Entry(bool free, uint64_t lastUsed, const FrameBuffer &b bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const { - const std::vector &planes = buffer.planes(); + Span planes = buffer.planes(); if (planes_.size() != planes.size()) return false; @@ -1676,7 +1676,7 @@ int V4L2VideoDevice::queueBuffer(FrameBuffer *buffer) buf.field = V4L2_FIELD_NONE; bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type); - const std::vector &planes = buffer->planes(); + Span planes = buffer->planes(); const unsigned int numV4l2Planes = format_.planesCount; /* @@ -1909,7 +1909,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer() } metadata.sequence -= firstFrame_.value(); - const std::vector &framebufferPlanes = buffer->planes(); + Span framebufferPlanes = buffer->planes(); unsigned int numV4l2Planes = multiPlanar ? buf.length : 1; if (numV4l2Planes != framebufferPlanes.size()) {