From a645898af50396a4ae1b32e418c21011c8b3f99d Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Tue, 16 Nov 2021 14:29:02 +0100 Subject: libcamera: request: Add Fence to Request::addBuffer() Add an optional fence parameter to Request::addBuffer() to allow associating a Fence with a FrameBuffer. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/request.cpp | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 69220247..6c9d67be 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -294,6 +295,7 @@ void Request::reuse(ReuseFlag flags) * \brief Add a FrameBuffer with its associated Stream to the Request * \param[in] stream The stream the buffer belongs to * \param[in] buffer The FrameBuffer to add to the request + * \param[in] fence The optional fence * * A reference to the buffer is stored in the request. The caller is responsible * for ensuring that the buffer will remain valid until the request complete @@ -302,11 +304,27 @@ void Request::reuse(ReuseFlag flags) * A request can only contain one buffer per stream. If a buffer has already * been added to the request for the same stream, this function returns -EEXIST. * + * A Fence can be optionally associated with the \a buffer. + * + * When a valid Fence is provided to this function, \a fence is moved to \a + * buffer and this Request will only be queued to the device once the + * fences of all its buffers have been correctly signalled. + * + * If the \a fence associated with \a buffer isn't signalled, the request will + * fail after a timeout. The buffer will still contain the fence, which + * applications must retrieve with FrameBuffer::releaseFence() before the buffer + * can be reused in another request. Attempting to add a buffer that still + * contains a fence to a request will result in this function returning -EEXIST. + * + * \sa FrameBuffer::releaseFence() + * * \return 0 on success or a negative error code otherwise * \retval -EEXIST The request already contains a buffer for the stream + * or the buffer still references a fence * \retval -EINVAL The buffer does not reference a valid Stream */ -int Request::addBuffer(const Stream *stream, FrameBuffer *buffer) +int Request::addBuffer(const Stream *stream, FrameBuffer *buffer, + std::unique_ptr fence) { if (!stream) { LOG(Request, Error) << "Invalid stream reference"; @@ -323,6 +341,18 @@ int Request::addBuffer(const Stream *stream, FrameBuffer *buffer) _d()->pending_.insert(buffer); bufferMap_[stream] = buffer; + /* + * Make sure the fence has been extracted from the buffer + * to avoid waiting on a stale fence. + */ + if (buffer->_d()->fence()) { + LOG(Request, Error) << "Can't add buffer that still references a fence"; + return -EEXIST; + } + + if (fence && fence->isValid()) + buffer->_d()->setFence(std::move(fence)); + return 0; } -- cgit v1.2.1