summaryrefslogtreecommitdiff
path: root/include/libcamera/base
AgeCommit message (Collapse)Author
2022-11-11libcamera: base: semaphore: Apply clang thread safety annotationHirokazu Honda
This annotates member functions and variables of Semaphore by clang thread safety annotations. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2022-10-20libcamera: base: log: Fix LogCategory creation issuesTomi Valkeinen
Each declaration of a LogCategory will create a new LogCategory, and will be stored in an unordered_set Logger::categories_. This means that when a plugin .so is unloaded and loaded, as happens when destructing and creating a CamereManager, we'll get duplicate categories. The Logger::registerCategory docs say "Log categories must have unique names. If a category with the same name already exists this function performs no operation.". The code does not comply with this. We solve the issue with two changes: Change the unordered_set to a vector for simplicity, as there's no need for an unordered_set. Instead of using the LogCategory constructor to create new categories in _LOG_CATEGORY() macro, use a factory method. The factory method will return either an existing LogCategory if one exists with the given name, or a newly created one. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-20libcamera: base: log: Fix use of freed nameTomi Valkeinen
LogCategory just stores the char * that was given to it in the constructor, i.e. it refers to memory "outside" LogCategory. If the LogCategory is defined in a .so that is unloaded, then it leads to the LogCategory pointing to freed memory, causing a crash. Fix this by taking a copy of the name by using a std::string instead of just storing the pointer. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2022-10-10libcamera: base: utils: Drop defoptLaurent Pinchart
utils::defopt causes compilation issues on gcc 8.0.0 to gcc 8.3.0, likely due to bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521 that was fixed in gcc 8.4.0. gcc 8.3.0 may be considered old (libcamera requires gcc-8 or newer), but it is shipped by Debian 10 that has LTS support until mid-2024. As no workaround has been found to fix compilation on gcc 8.3.0 while still retaining the functionality of utils::defopt, remove it from the libcamera base library. This change could be reverted once support for gcc-8 will be dropped. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-08-31libcamera: base: signal: Disable connect() for functor if args mismatchLaurent Pinchart
If a pointer-to-member is passed to the Signal::connect() function with arguments that don't match the Signal type, the pointer-to-member version of connect() will not match during template argument resolution, but the functor version will. This results in a compilation error in the BoundMethodFunctor class, due to the pointer-to-member not being a functor and thus not being callable directly. The error messages are quite cryptic. With the following error applied, diff --git a/test/signal.cpp b/test/signal.cpp index 5c6b304dac0b..6dd11ac45313 100644 --- a/test/signal.cpp +++ b/test/signal.cpp @@ -107,6 +107,7 @@ protected: /* Test signal emission and reception. */ called_ = false; signalVoid_.connect(this, &SignalTest::slotVoid); + signalVoid_.connect(this, &SignalTest::slotInteger1); signalVoid_.emit(); if (!called_) { gcc outputs ../../include/libcamera/base/bound_method.h: In instantiation of ‘R libcamera::BoundMethodFunctor<T, R, Func, Args>::activate(Args ..., bool) [with T = SignalTest; R = void; Func = void (SignalTest::*)(int); Args = {}]’: ../../include/libcamera/base/bound_method.h:143:4: required from here ../../include/libcamera/base/bound_method.h:146:37: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((libcamera::BoundMethodFunctor<SignalTest, void, void (SignalTest::*)(int)>*)this)->libcamera::BoundMethodFunctor<SignalTest, void, void (SignalTest::*)(int)>::func_ (...)’, e.g. ‘(... ->* ((libcamera::BoundMethodFunctor<SignalTest, void, void (SignalTes t::*)(int)>*)this)->libcamera::BoundMethodFunctor<SignalTest, void, void (SignalTest::*)(int)>::func_) (...)’ 146 | return func_(args...); | ~~~~~^~~~~~~~~ and clang isn't much better: ../../include/libcamera/base/bound_method.h:146:11: error: called object type 'void (SignalTest::*)(int)' is not a function or function pointer return func_(args...); ^~~~~ ../../include/libcamera/base/bound_method.h:137:2: note: in instantiation of member function 'libcamera::BoundMethodFunctor<SignalTest, void, void (SignalTest::*)(int)>::activate' requested here BoundMethodFunctor(T *obj, Object *object, Func func, ^ ../../include/libcamera/base/signal.h:80:27: note: in instantiation of member function 'libcamera::BoundMethodFunctor<SignalTest, void, void (SignalTest::*)(int)>::BoundMethodFunctor' requested here SignalBase::connect(new BoundMethodFunctor<T, void, Func, Args...>(obj, nullptr, func)); ^ ../../test/signal.cpp:110:15: note: in instantiation of function template specialization 'libcamera::Signal<>::connect<SignalTest, void (SignalTest::*)(int), nullptr>' requested here signalVoid_.connect(this, &SignalTest::slotInteger1); ^ Improve error reporting by disabling the functor version of connect() when the Func argument isn't invocable with the Signal arguments. gcc will then complain with ../../test/signal.cpp:110:36: error: no matching function for call to ‘libcamera::Signal<>::connect(SignalTest*, void (SignalTest::*)(int))’ 110 | signalVoid_.connect(this, &SignalTest::slotInteger1); | ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and clang with ../../test/signal.cpp:110:15: error: no matching member function for call to 'connect' signalVoid_.connect(this, &SignalTest::slotInteger1); ~~~~~~~~~~~~^~~~~~~ which are more readable. This change requires usage of std::is_invocable<>, which is only available starting in C++17. This is fine for usage of the Signal class within libcamera, as the project is compiled with C++17, but we try to keep the public API compatible C++14. Condition the additional checks based on the C++ version. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-08-26utils: Satisfy LegacyInputIterator with StringSplitter::iteratorLaurent Pinchart
The StringSplitter::iterator is used with the utils::split() function to iterate over components of a split string. Add the necessary member types expected by std::iterator_trait in order to satisfy the LegacyInputIterator requirement and make the iterator usable in constructors for various containers. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2022-08-16libcamera: base: Make message.h and mutex.h privateLaurent Pinchart
The message.h and mutex.h headers are not used in the libcamera public API. Make them private to avoid there usage in applications, and to prevent having to maintain them with a stable ABI. As mutex.h is used by libcamerasrc, the GStreamer element must switch from the libcamera_public to the libcamera_private dependency. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-07-28libcamera: Drop unnecessary typename keyword used with std::enable_if_tLaurent Pinchart
Usage of the std::enable_if_t type doesn't need to be prefixed by typename. Drop the unnecessary keyword. Reported-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2022-07-28libcamera: base: utils: Provide defopt to simplify std::optional::value_or() ↵Laurent Pinchart
usage The std::optional<T>::value_or(U &&default_value) function returns the contained value if available, or default_value if the std::optional has no value. If the desired default value is a default-constructed T, the obvious option is to call std::optional<T>::value_or(T{}). This approach has two drawbacks: - The \a default_value T{} is constructed even if the std::optional instance has a value, which impacts efficiency. - The T{} default constructor needs to be spelled out explicitly in the value_or() call, leading to long lines if the type is complex. Introduce a defopt variable that solves these issues by providing a value that can be passed to std::optional<T>::value_or() and get implicitly converted to a default-constructed T. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2022-06-06libcamera: base: log: Color the log prefixLaurent Pinchart
Add coloring to the log prefix to increase log readability. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-04-07libcamera: base: utils: Add missing constructor for DurationLaurent Pinchart
The Duration class is missing the equivalent to the std::chrono::duration constructor that takes a number of ticks expressed as a scalar. Fix it, which allows initializing a Duration instance to 0 or 0.0. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-03-25libcamera: base: timer: Drop start() overload with int argumentLaurent Pinchart
The start(unsigned int msec) overload is error-prone, as the argument unit can easily be mistaken in callers. Drop it and update all callers to use the start(std::chrono::milliseconds) overload instead. The callers now need to use std::chrono_literals. The using statement could be added to timer.h for convenience, but "using" is discouraged in header files to avoid namespace pollution. Update the callers instead, and while at it, sort the "using" statements alphabetically in tests. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-12-07libcamera: base: utils: Add abs_diff() utility functionLaurent Pinchart
The abs_diff() function computes the absolute difference of two elements. This may seem trivial at first, but can lead to unexpected results when operating on unsigned operands. A common implementation of the absolute difference of two unsigned int (used through the libcamera code base) is std::abs(static_cast<int>(a - b)) but doesn't return the expected result when either a or b is larger than UINT_MAX / 2 due to overflows. The abs_diff() function offers a safe alternative. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-12-04libcamera: base: shared_fd: Add comparison operatorsLaurent Pinchart
Add == and != comparison operators between two SharedFD instances, and use them to replace manuel get() calls. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-12-04libcamera: base: shared_fd: Rename fd() to get()Laurent Pinchart
For consistency with UniqueFD, rename the fd() function to get(). Renaming UniqueFD::get() to fd() would have been another option, but was rejected to keep as close as possible to the std::shared_ptr<> and std::unique_ptr<> APIs. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-12-04libcamera: base: Rename FileDescriptor to SharedFDLaurent Pinchart
Now that we have a UniqueFD class, the name FileDescriptor is ambiguous. Rename it to SharedFD. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-12-04libcamera: file: Manage fd by UniqueFDHirokazu Honda
Manages the file descriptor owned by File by UniqueFD. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-12-04libcamera: event_dispatcher_poll: Manage fd by UniqueFDHirokazu Honda
Manages the event file descriptor owned by EventDispatcherPoll by UniqueFD. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-12-03libcamera: base: file_descriptor: Return UniqueFD from dup()Laurent Pinchart
The dup() function returns a duplicate of the file descriptor. Wrapping it in a FileDescriptor isn't wrong as such, but it prevents from using it in contexts where a UniqueFD is needed. As the duplicate is guaranteed to have a single owner when created, return it as a UniqueFD instead. A FileDescriptor can easily be created from the UniqueFD if desired. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-12-03libcamera: base: file_descriptor: Add constructor from UniqueFDHirokazu Honda
Add a FileDescriptor constructor that takes a UniqueFD, transfering ownership of the file descriptor to the FileDescriptor. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-12-03libcamera: base: Introduce UniqueFDHirokazu Honda
This introduces UniqueFD. It acts like unique_ptr to a file descriptor. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-12-03libcamera: base: file_descriptor: Move inode() function to frame_buffer.cppLaurent Pinchart
The inode() function has always been a bit of an outcast in the FileDescriptor class, as it's not related to the core feature provided by FileDescriptor, a shared ownership wrapper around file descriptors. As it's only used in the FrameBuffer implementation, move it to frame_buffer.cpp as a static function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-12-03libcamera: Move file_descriptor.h to base/Laurent Pinchart
The FileDescriptor class is a generic helper that matches the criteria for the base library. Move it there. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-12-03libcamera: Move compiler.h to base/Laurent Pinchart
In preparation for usage of __nodiscard in the base API, move the compiler.h header to base. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-12-01libcamera: Correct include headers for Mutex classesHirokazu Honda
Mutex classes are defined in mutex.h. This replaces thread.h include for the Mutex classes with mutex.h. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-12-01libcamera: base: Add mutex classes with thread safety annotationsHirokazu Honda
This replaces Mutex and MutexLocker with our own defined classes. The classes are annotated by clang thread safety annotations. So we can add annotation to code where the classes are used. v4l2 code needs to be annotated, which violates Mutex capability. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-12-01libcamera: base: Add thread safety annotation macrosHirokazu Honda
Clang compiler is able to do a thread safety analysis with annotations [1]. This introduces the thread safety annotation macros and also enable the analysis by adding -Wthread-safety if a clang compiler is used. [1] https://clang.llvm.org/docs/ThreadSafetyAnalysis.html. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-12-01libcamera: base: Introduce ConditionVariableHirokazu Honda
ConditionVariable is alias to std::condition_variable. This replaces std::condition_variable with the ConditionVariable. It enables replacing ConditionVariable implementation easily in the following patches. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-11-24libcamera: object: Avoid argument copies in invokeMethod()Laurent Pinchart
Template argument deduction results in the lvalue and lvalue reference arguments to the invokeMethod() function causing deduction of the Args template type to a non-reference type. This results in the argument being passed by value and copied. Fix this by using a cv-unqualified rvalue reference parameter type. The type is then deduced to an lvalue reference when the argument is an lvalue or lvalue reference, due to a combination of the special template argument deduction rule for rvalue reference parameter types: If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction. (https://en.cppreference.com/w/cpp/language/template_argument_deduction) and the reference collapsing rule (https://en.cppreference.com/w/cpp/language/reference#Reference_collapsing). Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-11-24libcamera: base: Convert to pragma onceKieran Bingham
Remove the verbose #ifndef/#define/#endif pattern for maintaining header idempotency, and replace it with a simple #pragma once. This simplifies the headers, and prevents redundant changes when header files get moved. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
2021-10-15libcamera: base: backtrace: Fallback to libunwind for symbolic namesLaurent Pinchart
libunwind has an API to provide symbolic names for functions. It's less optimal than using backtrace_symbols() or libdw, as it doesn't allow deferring the symbolic names lookup, but it can be usefull as a fallback if no other option is available. A sample backtrace when falling back to libunwind looks like libcamera::VimcCameraData::init()+0xbd libcamera::PipelineHandlerVimc::match(libcamera::DeviceEnumerator*)+0x3e0 libcamera::CameraManager::Private::createPipelineHandlers()+0x1a7 libcamera::CameraManager::Private::init()+0x98 libcamera::CameraManager::Private::run()+0x9f libcamera::Thread::startThread()+0xee decltype(*(std::__1::forward<libcamera::Thread*>(fp0)).*fp()) std::__1::__invoke<void (libcamera::Thread::*)(), libcamera::Thread*, void>(void (libcamera::Thread::*&&)(), libcamera::Thread*&&)+0x77 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*>&, std::__1::__tuple_indices<2ul>)+0x3e void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*> >(void*)+0x62 start_thread+0xde ??? Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15libcamera: base: backtrace: Use libunwind when availableLaurent Pinchart
libunwind is an alternative to glibc's backtrace() to extract a backtrace. Use it when available to extend backtrace support to more platforms. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15libcamera: base: Add Backtrace classLaurent Pinchart
Create a new class to abstract generation and access to call stack backtraces. The current implementation depends on the glibc backtrace() implementation and is copied from the logger. Future development will bring support for libunwind, transparently for the users of the class. The logger backtrace implementation is dropped, replaced by usage of the new Backtrace class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-09-07libcamera: base: utils: Use size_t for index in utils::enumerate()Laurent Pinchart
The index generated by utils::enumerate() is an iteration counter, which should thus be positive. Use std::size_t instead of the difference_type of the container. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-02libcamera: Drop emitter object pointer from signal argumentsLaurent Pinchart
Many signals used in internal and public APIs carry the emitter pointer as a signal argument. This was done to allow slots connected to multiple signal instances to differentiate between emitters. While starting from a good intention of facilitating the implementation of slots, it turned out to be a bad API design as the signal isn't meant to know what it will be connected to, and thus shouldn't carry parameters that are solely meant to support a use case specific to the connected slot. These pointers turn out to be unused in all slots but one. In the only case where it is needed, it can be obtained by wrapping the slot in a lambda function when connecting the signal. Do so, and drop the emitter pointer from all signals. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-02libcamera: base: signal: Support connecting signals to functorsLaurent Pinchart
It can be useful to connect a signal to a functor, and in particular a lambda function, while still operating in the context of a receiver object (to support both object-based disconnection and queued connections to Object instances). Add a BoundMethodFunctor class to bind a functor, and a corresponding Signal::connect() function. There is no corresponding disconnect() function, as a lambda passed to connect() can't be later passed to disconnect(). Disconnection typically uses disconnect(T *object), which will cover the vast majority of use cases. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-02libcamera: base: bound_method: Remove BoundMethodArgs specializationLaurent Pinchart
The BoundMethodArgs specialization for the void return type is only needed to avoid accessing the ret_ member variable that is lacking from the corresponding BoundMethodPack specialization. As the member variable is only accessed in the invokePack() function, instead of specializing the whole class we can use SFINAE to select between two different implementations of the function. SFINAE can only depend on the function template parameters, not the parameters of the class template in which the function is defined: "Only the failures in the types and expressions in the immediate context of the function type or its template parameter types are SFINAE errors." We thus can't use the type R in an std::enable_if expression for the invokePack() function. To work around this, we have to add a type T to the function template definition, which defaults to R, and use T with std::enable_if. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-02libcamera: base: bound_method: Remove BoundMethodMember specializationLaurent Pinchart
The BoundMethodMember specialization for the void return type is only needed to avoid accessing the ret_ member variable that is lacking from the corresponding BoundMethodPack specialization. By adding a BoundMethodPack::returnValue() function to read the member variable, we can remove the complete BoundMethodMember specialization. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-08-27base: class: Remove undesired semi-colon from LIBCAMERA_O_PTRKieran Bingham
The LIBCAMERA_O_PTR() define adds the ';' at the end of the templated call to _o(). While this works for the only current user in camera_manager.cpp, even the statement there adds another semi-colon following it. The addition of the semi-colon in the define unnecessarily prohibits the macro from being used in places other than the end of a statement. Remove it. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-16libcamera: base: extensible: Pass private pointer as unique_ptr<>Laurent Pinchart
The Extensible constructor takes a pointer to a Private instance, whose lifetime it then manages. Make this explicit in the API by passing the pointer as a std::unique_ptr<Private>. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-03libcamera: base: class: Don't pass Extensible pointer to Private constructorLaurent Pinchart
The Extensible and Extensible::Private classes contain pointers to each other. These pointers are initialized in the respective class's constructor, by passing a pointer to the other class to each constructor. This particular construct reduces the flexibility of the Extensible pattern, as the Private class instance has to be allocated and constructed in the members initializer list of the Extensible class's constructor. It is thus impossible to perform any operation on the Private class between its construction and the construction of the Extensible class, or to subclass the Private class without subclassing the Extensible class. To make the design pattern more flexible, don't pass the pointer to the Extensible class to the Private class's constructor, but initialize the pointer manually in the Extensible class's constructor. This requires a const_cast as the o_ member of the Private class is const. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-03libcamera: base: class: Document Extensible::_d() functionsLaurent Pinchart
The Extensible::_d() functions are meant to be called by users of the class. Document them. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-03libcamera: file: Turn MapFlag and OpenModeFlag into enum classLaurent Pinchart
Add type safety by turning the MapFlag and OpenModeFlag enum into enum class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-03libcamera: file: Use Flags<> class for open flagsLaurent Pinchart
Use the newly introduced Flags<> class to store a bitfield of File::OpenMode in a type-safe way. The existing File::OpenMode enum is renamed to File::OpenModeFlag to free the File::OpenMode for the Flags<> type alias. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-03libcamera: file: Use Flags<> class for map flagsLaurent Pinchart
Use the newly introduced Flags<> class to store a bitfield of File::MapFlag in a type-safe way. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-03libcamera: flags: Add type-safe enum-based flagsLaurent Pinchart
Add a Flags template class that provide type-safe bitwise operators on enum values. This allows using enum types for bit fields, without giving away type-safety as usually done when storing combined flags in integer variables. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-07-12libcamera: Drop the LIBCAMERA_D_PTR macro in favour of the _d() functionLaurent Pinchart
Now that all Extensible classes expose a _d() function that performs appropriate casts, the LIBCAMERA_D_PTR brings no real additional value. Replace it with direct calls to the _d() function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-07-12libcamera: base: class: Expose Extensible private data to other classesLaurent Pinchart
Despite sharing the same name, the private data class created by the Extensible design pattern and the C++ private access specifier have different goals. The latter specifies class members private to the class, while the former stores data not visible to the application. There are use cases for accessing the private data class from other classes inside libcamera. Make this possible by exposing public _d() functions in the class deriving from Extensible. This won't allow access to the private data by applications as the definition of the Private class isn't visible outside of libcamera. The _d() functions need to be defined as template functions to delay their evaluation, as the static_cast() operator in the Extensible::_d() functions needs the Private class to be fully defined. The template argument is defaulted and ignored, as only its presence is required to delay evaluation. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-06-28libcamera: utils: Only enable utils::hex() for integer argumentsLaurent Pinchart
The utils::hex() function is defined as a function template that has implementations for integer arguments only. When given a different argument type, the compiler will not catch the issue, but linking will fail: src/libcamera/libcamera.so.p/camera_sensor.cpp.o: in function `libcamera::CameraSensor::validateSensorDriver()': camera_sensor.cpp:(.text+0x1e6b): undefined reference to `libcamera::utils::_hex libcamera::utils::hex<libcamera::ControlId const*>(libcamera::ControlId const*, unsigned int)' Move the failure to compilation time by enabling the function for integer arguments only. This provides better diagnostics: ../../src/libcamera/camera_sensor.cpp: In member function ‘int libcamera::CameraSensor::validateSensorDriver()’: ../../src/libcamera/camera_sensor.cpp:199:77: error: no matching function for call to ‘hex(const libcamera::ControlId*&)’ Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2021-06-25libcamera/base: Validate internal headers as privateKieran Bingham
Headers which must not be exposed as part of the public libcamera API should include base/private.h. Any interface which includes the private.h header will only be able to build if the libcamera_private dependency is used (or the libcamera_base_private dependency directly). Build targets which are intended to use the private API's will use the libcamera_private to handle the automatic definition of the inclusion guard. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>