Message ID | 20211201142936.107405-4-jacopo@jmondi.org |
---|---|
State | Superseded |
Delegated to: | Jacopo Mondi |
Headers | show |
Series |
|
Related | show |
Hi Jacopo, Thank you for the patch. On Wed, Dec 01, 2021 at 03:29:28PM +0100, Jacopo Mondi wrote: > Introduce a Fence class which models a synchronization primitive that > allows to notify the availability of a resource. > > The Fence is modeled as a wrapper of a UniqueFD instance where > read events are used to signal the Fence. The class can be later > extended to support additional signalling mechanisms. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> > --- > include/libcamera/fence.h | 31 ++++++++++ > include/libcamera/meson.build | 1 + > src/libcamera/fence.cpp | 113 ++++++++++++++++++++++++++++++++++ > src/libcamera/meson.build | 1 + > 4 files changed, 146 insertions(+) > create mode 100644 include/libcamera/fence.h > create mode 100644 src/libcamera/fence.cpp > > diff --git a/include/libcamera/fence.h b/include/libcamera/fence.h > new file mode 100644 > index 000000000000..c0c916c264b4 > --- /dev/null > +++ b/include/libcamera/fence.h > @@ -0,0 +1,31 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2021, Google Inc. > + * > + * internal/fence.h - Synchronization fence > + */ > + > +#pragma once > + > +#include <libcamera/base/class.h> > +#include <libcamera/base/unique_fd.h> > + > +namespace libcamera { > + > +class Fence > +{ > +public: > + Fence(UniqueFD fd); > + > + bool isValid() const { return fd_.isValid(); } > + const UniqueFD &fd() const { return fd_; } > + > + UniqueFD release() { return std::move(fd_); } > + > +private: > + LIBCAMERA_DISABLE_COPY_AND_MOVE(Fence) > + > + UniqueFD fd_; > +}; > + > +} /* namespace libcamera */ > diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build > index 5f42977c034b..8c2cae00d877 100644 > --- a/include/libcamera/meson.build > +++ b/include/libcamera/meson.build > @@ -6,6 +6,7 @@ libcamera_public_headers = files([ > 'camera.h', > 'camera_manager.h', > 'controls.h', > + 'fence.h', > 'framebuffer.h', > 'framebuffer_allocator.h', > 'geometry.h', > diff --git a/src/libcamera/fence.cpp b/src/libcamera/fence.cpp > new file mode 100644 > index 000000000000..bd737e9848e1 > --- /dev/null > +++ b/src/libcamera/fence.cpp > @@ -0,0 +1,113 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2021, Google Inc. > + * > + * fence.cpp - Synchronization fence > + */ > + > +#include "libcamera/fence.h" > + > +namespace libcamera { > + > +/** > + * > + * \file libcamera/fence.h > + * \brief Synchronization fence > + */ > + > +/** > + * \class Fence > + * \brief Synchronization primitive to manage resources > + * > + * The Fence class models a synchronization primitive that can be used by > + * applications to explicitly synchronize resource usage, and can be shared by > + * multiple processes. > + * > + * Synchronization fences are most commonly used in association with frame > + * buffers. A FrameBuffer can be associated with a Fence so that the library can > + * wait for the Fence to be signalled before allowing the camera device to > + * actually access the memory area described by the FrameBuffer. > + * > + * \sa Request::addBuffer() > + * > + * By using synchronization fences, application can then synchronize between s/synchronization fences/fences/ (as explained in the review of v3) > + * frame buffer consumers and producers, as for example a display device and a > + * camera, to guarantee that new data transfers only happen once the existing > + * frames have been displayed. > + * > + * A Fence can be realized by different event notification primitives, the most > + * common of which is represented by waiting for read events to happen on a > + * kernel sync file. This is currently the only mechanism supported by You can move the * <a href="https://www.kernel.org/doc/html/latest/driver-api/sync_file.html">kernel sync file</a> from below here, inline in the text. > + * libcamera, but others can be implemented by extending or subclassing this > + * class and implementing opportune handling in the core library. > + * > + * <a href="https://www.kernel.org/doc/html/latest/driver-api/sync_file.html">kernel sync file</a> > + * > + * \internal > + * > + * The Fence class is a thin abstraction around a UniqueFD which simply allows > + * to access it as a const reference or to move its ownership to the caller. > + * > + * The usage of the Fence class allows to abstract the underlying > + * synchronization mechanism in use and implement an interface towards other > + * library components that will not change when new synchronization primitives > + * will be added as fences. > + * > + * A Fence is constructed with a UniqueFD whose ownership is moved in the Fence. > + * A FrameBuffer can be associated with a Fence by passing it to the > + * Request::addBuffer() function, which will move the Fence into the FrameBuffer > + * itself. Once a Request is queued to the Camera, a preparation phase > + * guarantees that before actually applying the Request to the hardware, all the > + * valid fences of the frame buffers in a Request are correctly signalled. Once > + * a Fence has completed, the library will release the FrameBuffer fence so that > + * application won't be allowed to access it. > + * > + * An optional timeout can be started while waiting for a fence to complete. If > + * waiting on a Fence fails for whatever reason, the FrameBuffer's fence is not > + * reset and is made available to application for them to handle it, by > + * releasing the Fence to correctly close the underlying UniqueFD. > + * > + * A failure in waiting for a Fence to complete will result in the Request to > + * complete in failed state. > + * > + * \sa Request::prepare() > + * \sa PipelineHandler::doQueueRequests() > + */ > + > +/** > + * \brief Create a synchronization fence > + * \param[in] fd The synchronization fence file descriptor s/synchronization fence/fence/ here too. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > + * > + * The file descriptor ownership is moved to the Fence. > + */ > +Fence::Fence(UniqueFD fd) > + : fd_(std::move(fd)) > +{ > +} > + > +/** > + * \fn Fence::isValid() > + * \brief Check if a Fence is valid > + * > + * A Fence is valid if the file descriptor it wraps is valid. > + * > + * \return True if the Fence is valid, false otherwise > + */ > + > +/** > + * \fn Fence::fd() > + * \brief Retrieve a constant reference to the file descriptor > + * \return A const reference to the fence file descriptor > + */ > + > +/** > + * \fn Fence::release() > + * \brief Release the ownership of the file descriptor > + * > + * Release the ownership of the wrapped file descriptor by returning it to the > + * caller. > + * > + * \return The wrapper UniqueFD > + */ > + > +} /* namespace libcamera */ > diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build > index b763110e74a6..b4882a2577f5 100644 > --- a/src/libcamera/meson.build > +++ b/src/libcamera/meson.build > @@ -14,6 +14,7 @@ libcamera_sources = files([ > 'delayed_controls.cpp', > 'device_enumerator.cpp', > 'device_enumerator_sysfs.cpp', > + 'fence.cpp', > 'formats.cpp', > 'framebuffer.cpp', > 'framebuffer_allocator.cpp',
diff --git a/include/libcamera/fence.h b/include/libcamera/fence.h new file mode 100644 index 000000000000..c0c916c264b4 --- /dev/null +++ b/include/libcamera/fence.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * internal/fence.h - Synchronization fence + */ + +#pragma once + +#include <libcamera/base/class.h> +#include <libcamera/base/unique_fd.h> + +namespace libcamera { + +class Fence +{ +public: + Fence(UniqueFD fd); + + bool isValid() const { return fd_.isValid(); } + const UniqueFD &fd() const { return fd_; } + + UniqueFD release() { return std::move(fd_); } + +private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(Fence) + + UniqueFD fd_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 5f42977c034b..8c2cae00d877 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -6,6 +6,7 @@ libcamera_public_headers = files([ 'camera.h', 'camera_manager.h', 'controls.h', + 'fence.h', 'framebuffer.h', 'framebuffer_allocator.h', 'geometry.h', diff --git a/src/libcamera/fence.cpp b/src/libcamera/fence.cpp new file mode 100644 index 000000000000..bd737e9848e1 --- /dev/null +++ b/src/libcamera/fence.cpp @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * fence.cpp - Synchronization fence + */ + +#include "libcamera/fence.h" + +namespace libcamera { + +/** + * + * \file libcamera/fence.h + * \brief Synchronization fence + */ + +/** + * \class Fence + * \brief Synchronization primitive to manage resources + * + * The Fence class models a synchronization primitive that can be used by + * applications to explicitly synchronize resource usage, and can be shared by + * multiple processes. + * + * Synchronization fences are most commonly used in association with frame + * buffers. A FrameBuffer can be associated with a Fence so that the library can + * wait for the Fence to be signalled before allowing the camera device to + * actually access the memory area described by the FrameBuffer. + * + * \sa Request::addBuffer() + * + * By using synchronization fences, application can then synchronize between + * frame buffer consumers and producers, as for example a display device and a + * camera, to guarantee that new data transfers only happen once the existing + * frames have been displayed. + * + * A Fence can be realized by different event notification primitives, the most + * common of which is represented by waiting for read events to happen on a + * kernel sync file. This is currently the only mechanism supported by + * libcamera, but others can be implemented by extending or subclassing this + * class and implementing opportune handling in the core library. + * + * <a href="https://www.kernel.org/doc/html/latest/driver-api/sync_file.html">kernel sync file</a> + * + * \internal + * + * The Fence class is a thin abstraction around a UniqueFD which simply allows + * to access it as a const reference or to move its ownership to the caller. + * + * The usage of the Fence class allows to abstract the underlying + * synchronization mechanism in use and implement an interface towards other + * library components that will not change when new synchronization primitives + * will be added as fences. + * + * A Fence is constructed with a UniqueFD whose ownership is moved in the Fence. + * A FrameBuffer can be associated with a Fence by passing it to the + * Request::addBuffer() function, which will move the Fence into the FrameBuffer + * itself. Once a Request is queued to the Camera, a preparation phase + * guarantees that before actually applying the Request to the hardware, all the + * valid fences of the frame buffers in a Request are correctly signalled. Once + * a Fence has completed, the library will release the FrameBuffer fence so that + * application won't be allowed to access it. + * + * An optional timeout can be started while waiting for a fence to complete. If + * waiting on a Fence fails for whatever reason, the FrameBuffer's fence is not + * reset and is made available to application for them to handle it, by + * releasing the Fence to correctly close the underlying UniqueFD. + * + * A failure in waiting for a Fence to complete will result in the Request to + * complete in failed state. + * + * \sa Request::prepare() + * \sa PipelineHandler::doQueueRequests() + */ + +/** + * \brief Create a synchronization fence + * \param[in] fd The synchronization fence file descriptor + * + * The file descriptor ownership is moved to the Fence. + */ +Fence::Fence(UniqueFD fd) + : fd_(std::move(fd)) +{ +} + +/** + * \fn Fence::isValid() + * \brief Check if a Fence is valid + * + * A Fence is valid if the file descriptor it wraps is valid. + * + * \return True if the Fence is valid, false otherwise + */ + +/** + * \fn Fence::fd() + * \brief Retrieve a constant reference to the file descriptor + * \return A const reference to the fence file descriptor + */ + +/** + * \fn Fence::release() + * \brief Release the ownership of the file descriptor + * + * Release the ownership of the wrapped file descriptor by returning it to the + * caller. + * + * \return The wrapper UniqueFD + */ + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index b763110e74a6..b4882a2577f5 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -14,6 +14,7 @@ libcamera_sources = files([ 'delayed_controls.cpp', 'device_enumerator.cpp', 'device_enumerator_sysfs.cpp', + 'fence.cpp', 'formats.cpp', 'framebuffer.cpp', 'framebuffer_allocator.cpp',
Introduce a Fence class which models a synchronization primitive that allows to notify the availability of a resource. The Fence is modeled as a wrapper of a UniqueFD instance where read events are used to signal the Fence. The class can be later extended to support additional signalling mechanisms. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> --- include/libcamera/fence.h | 31 ++++++++++ include/libcamera/meson.build | 1 + src/libcamera/fence.cpp | 113 ++++++++++++++++++++++++++++++++++ src/libcamera/meson.build | 1 + 4 files changed, 146 insertions(+) create mode 100644 include/libcamera/fence.h create mode 100644 src/libcamera/fence.cpp