From patchwork Tue Nov 30 23:36:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 14917 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 12B96C324F for ; Tue, 30 Nov 2021 23:35:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8976060732; Wed, 1 Dec 2021 00:35:52 +0100 (CET) Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DF62160710 for ; Wed, 1 Dec 2021 00:35:50 +0100 (CET) Received: (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 1AA821BF207; Tue, 30 Nov 2021 23:35:49 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 1 Dec 2021 00:36:26 +0100 Message-Id: <20211130233634.34173-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211130233634.34173-1-jacopo@jmondi.org> References: <20211130233634.34173-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 03/11] libcamera: fence: Introduce Fence X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- include/libcamera/fence.h | 31 ++++++++++ include/libcamera/meson.build | 1 + src/libcamera/fence.cpp | 108 ++++++++++++++++++++++++++++++++++ src/libcamera/meson.build | 1 + 4 files changed, 141 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..95f2dd07f10b --- /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 +#include + +namespace libcamera { + +class Fence +{ +public: + Fence(UniqueFD fd); + + bool isValid() const { return fd_.isValid(); } + const UniqueFD *fd() const { return &fd_; } + + UniqueFD reset() { 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..2bab8d7de76a --- /dev/null +++ b/src/libcamera/fence.cpp @@ -0,0 +1,108 @@ +/* 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 fence class + * + * The Fence class is a thin abstraction around a UniqueFD which simply allows + * to access it as a const pointer or to move its ownership to the caller. + * + * Synchronization fences are most commonly used in association with frame + * buffers. A FrameBuffer can be associated with a Fence (\sa + * Request::addBuffer()) 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. + * + * By using synchronization fences, application can then synchronize between + * frame buffer consumers and produces, as in example a video output device and + * camera, to gurantee that new data transfers only happen once the existing + * frames have been displayed. + * + * The Fence class only abstracts the underlying mechanism used by libcamera to + * implement synchronization primitives and allow to wait until an event is + * signalled, but does not implement event notification itself which is instead + * implemented by the core library. + * + * \sa Request::prepare() + * + * 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 + * file descriptor. 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. + * + * 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 contructed with a UniqueFD whose ownship 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 gurantees + * 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 reset 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 + * resetting 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. + */ + +/** + * \brief Create a synchronization fence + * \param[in] fd The synchronization fence unique file descriptor + * + * The unique file descriptor ownership is moved to the Fence. + */ +Fence::Fence(UniqueFD fd) + : fd_(std::move(fd)) +{ +} + +/** + * \fn Fence::isValid() + * \brief Retrieve if a Fence is valid + * + * A Fence is valid if the UniqueFD it wraps is valid + * + * \return True if the Fence is valid, false otherwise + */ + +/** + * \fn Fence::fd() + * \brief Retrieve a constant pointer to the UniqueFD + * \return A const pointer to the UniqueFD + */ + +/** + * \fn Fence::reset() + * \brief Reset the Fence by moving the UniqueFD ownership to the caller + * + * Reset the Fence by releasing the wrapped UniqueFD. Ownership of the UniqueFD + * is moved to the caller. + * + * \return The 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',