[libcamera-devel] [PATCH 06/10] libcamera: framebuffer: Add synchronization Fence
Kieran Bingham
kieran.bingham at ideasonboard.com
Tue Nov 9 14:53:11 CET 2021
Quoting Jacopo Mondi (2021-10-28 12:15:16)
> Add an optional synchronization file descriptor to the FrameBuffer constuctor.
>
> The fence is handled by the FrameBuffer::Private class by constructing
> a Fence class instance to wrap the file descriptor. Once the Request the
> FrameBuffer is part of has completed, the fence file descriptor will read
> as -1 if successfully handled by the library; otherwise the file
> descriptor value is kept and applications are responsible for closing
> it.
>
> Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> ---
> include/libcamera/framebuffer.h | 5 ++-
> include/libcamera/internal/framebuffer.h | 7 +++-
> src/libcamera/framebuffer.cpp | 46 +++++++++++++++++++++---
> 3 files changed, 52 insertions(+), 6 deletions(-)
>
> diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h
> index 7f2f176af691..ac96790b76c0 100644
> --- a/include/libcamera/framebuffer.h
> +++ b/include/libcamera/framebuffer.h
> @@ -57,7 +57,8 @@ public:
> unsigned int length;
> };
>
> - FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie = 0);
> + FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie = 0,
> + int fence = -1);
Hrm, -1 seems a bit odd here, Perhaps we should be passing in a
FileDescriptor.
does this impact on the recent work to have an external
FrameBufferAllocator at all?
>
> const std::vector<Plane> &planes() const { return planes_; }
> Request *request() const;
> @@ -66,6 +67,8 @@ public:
> unsigned int cookie() const { return cookie_; }
> void setCookie(unsigned int cookie) { cookie_ = cookie; }
>
> + int fence() const;
> +
> void cancel() { metadata_.status = FrameMetadata::FrameCancelled; }
>
> private:
> diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h
> index cd33c295466e..db1a4bd72354 100644
> --- a/include/libcamera/internal/framebuffer.h
> +++ b/include/libcamera/internal/framebuffer.h
> @@ -11,6 +11,8 @@
>
> #include <libcamera/framebuffer.h>
>
> +#include <libcamera/internal/fence.h>
> +
> namespace libcamera {
>
> class FrameBuffer::Private : public Extensible::Private
> @@ -18,14 +20,17 @@ class FrameBuffer::Private : public Extensible::Private
> LIBCAMERA_DECLARE_PUBLIC(FrameBuffer)
>
> public:
> - Private();
> + Private(int fence);
>
> void setRequest(Request *request) { request_ = request; }
> bool isContiguous() const { return isContiguous_; }
> + const Fence &fence() const { return fence_; }
> + Fence &fence() { return fence_; }
>
> private:
> Request *request_;
> bool isContiguous_;
> + Fence fence_;
> };
>
> } /* namespace libcamera */
> diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp
> index d44a98babd05..c3e03896b184 100644
> --- a/src/libcamera/framebuffer.cpp
> +++ b/src/libcamera/framebuffer.cpp
> @@ -111,8 +111,12 @@ LOG_DEFINE_CATEGORY(Buffer)
> * pipeline handlers.
> */
>
> -FrameBuffer::Private::Private()
> - : request_(nullptr), isContiguous_(true)
> +/**
> + * \brief Construct a FrameBuffer::Private instance
> + * \param[in] fence The synchronization fence file descriptor
> + */
> +FrameBuffer::Private::Private(int fence)
> + : request_(nullptr), isContiguous_(true), fence_(fence)
> {
> }
>
> @@ -137,6 +141,18 @@ FrameBuffer::Private::Private()
> * \return True if the planes are stored contiguously in memory, false otherwise
> */
>
> +/**
> + * \fn const FrameBuffer::Private::fence() const
> + * \brief Return a const reference to the Fence
> + * \return A const reference to the frame buffer fence
> + */
> +
> +/**
> + * \fn FrameBuffer::Private::fence()
> + * \brief Return a reference to the Fence
> + * \return A reference to the frame buffer fence
> + */
> +
> /**
> * \class FrameBuffer
> * \brief Frame buffer data and its associated dynamic metadata
> @@ -211,9 +227,11 @@ FrameBuffer::Private::Private()
> * \brief Construct a FrameBuffer with an array of planes
> * \param[in] planes The frame memory planes
> * \param[in] cookie Cookie
> + * \param[in] fence Synchronization fence
> */
> -FrameBuffer::FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie)
> - : Extensible(std::make_unique<Private>()), planes_(planes),
> +FrameBuffer::FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie,
> + int fence)
> + : Extensible(std::make_unique<Private>(fence)), planes_(planes),
> cookie_(cookie)
> {
> metadata_.planes_.resize(planes_.size());
> @@ -305,6 +323,26 @@ Request *FrameBuffer::request() const
> * libcamera core never modifies the buffer cookie.
> */
>
> +/**
> + * \fn FrameBuffer::fence()
> + * \brief Return the synchronization fence file descriptor
> + *
> + * The fence file descriptor is set by applications at construction time.
> + *
> + * Once the Request is queued to the Camera the fence is handled by the
> + * library and if successfully notified the fence will read as -1 after the
> + * Request has completed.
Are fences always kept with the FrameBuffer allocations? Or is it a new
fence for everytime the FrameBuffer is queued?
> + *
> + * If waiting for fence fails, the fence is instead kept in the FrameBuffer
> + * after the Request has completed and it is responsibility of the
> + * application to correctly close it.
By simply closing the fd? Would this be automatic if it was constructed
into a FileDescriptor?
I don't think I've understood the underlying lifetime of the fence
mechanisms enough yet ...
I'll keep going and see if I get enlightenment from the following
patches.
> + */
> +int FrameBuffer::fence() const
> +{
> + const Fence &fence = _d()->fence();
> + return fence.fd();
> +}
> +
> /**
> * \fn FrameBuffer::cancel()
> * \brief Marks the buffer as cancelled
> --
> 2.33.1
>
More information about the libcamera-devel
mailing list