summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-03 22:55:11 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-07 18:10:38 +0300
commit0bc9286eb97aa4d38d643ee5c45fa6a487d12459 (patch)
treef959b21afc6a8dcc7eb12f8bc3a41e7b2274b202
parentba3a1adc13b9a2c2e92f438bcf5320d77bd08bd9 (diff)
libcamera: pipeline_handler: Implement factories through class templates
The REGISTER_PIPELINE_HANDLER() macro defines a class type that inherits from the PipelineHandlerFactory class, and implements a constructor and a createInstance() function. Replace the code generation through macro with the C++ equivalent, a class template, as done in libipa with the Algorithm and CameraSensorHelper factories. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Xavier Roumegue <xavier.roumegue@oss.nxp.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r--include/libcamera/internal/pipeline_handler.h44
-rw-r--r--src/libcamera/camera_manager.cpp6
-rw-r--r--src/libcamera/pipeline_handler.cpp65
-rw-r--r--test/ipa/ipa_interface_test.cpp6
4 files changed, 71 insertions, 50 deletions
diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h
index ad74dc82..b6139a88 100644
--- a/include/libcamera/internal/pipeline_handler.h
+++ b/include/libcamera/internal/pipeline_handler.h
@@ -95,23 +95,23 @@ private:
Mutex lock_;
unsigned int useCount_ LIBCAMERA_TSA_GUARDED_BY(lock_);
- friend class PipelineHandlerFactory;
+ friend class PipelineHandlerFactoryBase;
};
-class PipelineHandlerFactory
+class PipelineHandlerFactoryBase
{
public:
- PipelineHandlerFactory(const char *name);
- virtual ~PipelineHandlerFactory() = default;
+ PipelineHandlerFactoryBase(const char *name);
+ virtual ~PipelineHandlerFactoryBase() = default;
std::shared_ptr<PipelineHandler> create(CameraManager *manager) const;
const std::string &name() const { return name_; }
- static std::vector<PipelineHandlerFactory *> &factories();
+ static std::vector<PipelineHandlerFactoryBase *> &factories();
private:
- static void registerType(PipelineHandlerFactory *factory);
+ static void registerType(PipelineHandlerFactoryBase *factory);
virtual std::unique_ptr<PipelineHandler>
createInstance(CameraManager *manager) const = 0;
@@ -119,19 +119,23 @@ private:
std::string name_;
};
-#define REGISTER_PIPELINE_HANDLER(handler) \
-class handler##Factory final : public PipelineHandlerFactory \
-{ \
-public: \
- handler##Factory() : PipelineHandlerFactory(#handler) {} \
- \
-private: \
- std::unique_ptr<PipelineHandler> \
- createInstance(CameraManager *manager) const \
- { \
- return std::make_unique<handler>(manager); \
- } \
-}; \
-static handler##Factory global_##handler##Factory;
+template<typename _PipelineHandler>
+class PipelineHandlerFactory final : public PipelineHandlerFactoryBase
+{
+public:
+ PipelineHandlerFactory(const char *name)
+ : PipelineHandlerFactoryBase(name)
+ {
+ }
+
+ std::unique_ptr<PipelineHandler>
+ createInstance(CameraManager *manager) const override
+ {
+ return std::make_unique<_PipelineHandler>(manager);
+ }
+};
+
+#define REGISTER_PIPELINE_HANDLER(handler) \
+static PipelineHandlerFactory<handler> global_##handler##Factory(#handler);
} /* namespace libcamera */
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index 2c3f2d86..2c100c24 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -142,10 +142,10 @@ void CameraManager::Private::createPipelineHandlers()
* file and only fallback on all handlers if there is no
* configuration file.
*/
- const std::vector<PipelineHandlerFactory *> &factories =
- PipelineHandlerFactory::factories();
+ const std::vector<PipelineHandlerFactoryBase *> &factories =
+ PipelineHandlerFactoryBase::factories();
- for (const PipelineHandlerFactory *factory : factories) {
+ for (const PipelineHandlerFactoryBase *factory : factories) {
LOG(Camera, Debug)
<< "Found registered pipeline handler '"
<< factory->name() << "'";
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 488dd8d3..588a3db3 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -64,8 +64,7 @@ LOG_DEFINE_CATEGORY(Pipeline)
*
* In order to honour the std::enable_shared_from_this<> contract,
* PipelineHandler instances shall never be constructed manually, but always
- * through the PipelineHandlerFactory::create() function implemented by the
- * respective factories.
+ * through the PipelineHandlerFactoryBase::create() function.
*/
PipelineHandler::PipelineHandler(CameraManager *manager)
: manager_(manager), useCount_(0)
@@ -643,27 +642,25 @@ void PipelineHandler::disconnect()
*/
/**
- * \class PipelineHandlerFactory
- * \brief Registration of PipelineHandler classes and creation of instances
+ * \class PipelineHandlerFactoryBase
+ * \brief Base class for pipeline handler factories
*
- * To facilitate discovery and instantiation of PipelineHandler classes, the
- * PipelineHandlerFactory class maintains a registry of pipeline handler
- * classes. Each PipelineHandler subclass shall register itself using the
- * REGISTER_PIPELINE_HANDLER() macro, which will create a corresponding
- * instance of a PipelineHandlerFactory subclass and register it with the
- * static list of factories.
+ * The PipelineHandlerFactoryBase class is the base of all specializations of
+ * the PipelineHandlerFactory class template. It implements the factory
+ * registration, maintains a registry of factories, and provides access to the
+ * registered factories.
*/
/**
- * \brief Construct a pipeline handler factory
+ * \brief Construct a pipeline handler factory base
* \param[in] name Name of the pipeline handler class
*
- * Creating an instance of the factory registers is with the global list of
+ * Creating an instance of the factory base registers it with the global list of
* factories, accessible through the factories() function.
*
* The factory \a name is used for debug purpose and shall be unique.
*/
-PipelineHandlerFactory::PipelineHandlerFactory(const char *name)
+PipelineHandlerFactoryBase::PipelineHandlerFactoryBase(const char *name)
: name_(name)
{
registerType(this);
@@ -676,7 +673,7 @@ PipelineHandlerFactory::PipelineHandlerFactory(const char *name)
* \return A shared pointer to a new instance of the PipelineHandler subclass
* corresponding to the factory
*/
-std::shared_ptr<PipelineHandler> PipelineHandlerFactory::create(CameraManager *manager) const
+std::shared_ptr<PipelineHandler> PipelineHandlerFactoryBase::create(CameraManager *manager) const
{
std::unique_ptr<PipelineHandler> handler = createInstance(manager);
handler->name_ = name_.c_str();
@@ -684,7 +681,7 @@ std::shared_ptr<PipelineHandler> PipelineHandlerFactory::create(CameraManager *m
}
/**
- * \fn PipelineHandlerFactory::name()
+ * \fn PipelineHandlerFactoryBase::name()
* \brief Retrieve the factory name
* \return The factory name
*/
@@ -696,9 +693,10 @@ std::shared_ptr<PipelineHandler> PipelineHandlerFactory::create(CameraManager *m
* The caller is responsible to guarantee the uniqueness of the pipeline handler
* name.
*/
-void PipelineHandlerFactory::registerType(PipelineHandlerFactory *factory)
+void PipelineHandlerFactoryBase::registerType(PipelineHandlerFactoryBase *factory)
{
- std::vector<PipelineHandlerFactory *> &factories = PipelineHandlerFactory::factories();
+ std::vector<PipelineHandlerFactoryBase *> &factories =
+ PipelineHandlerFactoryBase::factories();
factories.push_back(factory);
}
@@ -707,26 +705,45 @@ void PipelineHandlerFactory::registerType(PipelineHandlerFactory *factory)
* \brief Retrieve the list of all pipeline handler factories
* \return the list of pipeline handler factories
*/
-std::vector<PipelineHandlerFactory *> &PipelineHandlerFactory::factories()
+std::vector<PipelineHandlerFactoryBase *> &PipelineHandlerFactoryBase::factories()
{
/*
* The static factories map is defined inside the function to ensure
* it gets initialized on first use, without any dependency on
* link order.
*/
- static std::vector<PipelineHandlerFactory *> factories;
+ static std::vector<PipelineHandlerFactoryBase *> factories;
return factories;
}
/**
+ * \class PipelineHandlerFactory
+ * \brief Registration of PipelineHandler classes and creation of instances
+ * \tparam _PipelineHandler The pipeline handler class type for this factory
+ *
+ * To facilitate discovery and instantiation of PipelineHandler classes, the
+ * PipelineHandlerFactory class implements auto-registration of pipeline
+ * handlers. Each PipelineHandler subclass shall register itself using the
+ * REGISTER_PIPELINE_HANDLER() macro, which will create a corresponding
+ * instance of a PipelineHandlerFactory and register it with the static list of
+ * factories.
+ */
+
+/**
+ * \fn PipelineHandlerFactory::PipelineHandlerFactory(const char *name)
+ * \brief Construct a pipeline handler factory
+ * \param[in] name Name of the pipeline handler class
+ *
+ * Creating an instance of the factory registers it with the global list of
+ * factories, accessible through the factories() function.
+ *
+ * The factory \a name is used for debug purpose and shall be unique.
+ */
+
+/**
* \fn PipelineHandlerFactory::createInstance() const
* \brief Create an instance of the PipelineHandler corresponding to the factory
* \param[in] manager The camera manager
- *
- * This virtual function is implemented by the REGISTER_PIPELINE_HANDLER()
- * macro. It creates a pipeline handler instance associated with the camera
- * \a manager.
- *
* \return A unique pointer to a newly constructed instance of the
* PipelineHandler subclass corresponding to the factory
*/
diff --git a/test/ipa/ipa_interface_test.cpp b/test/ipa/ipa_interface_test.cpp
index a629abc2..6b93e976 100644
--- a/test/ipa/ipa_interface_test.cpp
+++ b/test/ipa/ipa_interface_test.cpp
@@ -52,9 +52,9 @@ protected:
ipaManager_ = make_unique<IPAManager>();
/* Create a pipeline handler for vimc. */
- const std::vector<PipelineHandlerFactory *> &factories =
- PipelineHandlerFactory::factories();
- for (const PipelineHandlerFactory *factory : factories) {
+ const std::vector<PipelineHandlerFactoryBase *> &factories =
+ PipelineHandlerFactoryBase::factories();
+ for (const PipelineHandlerFactoryBase *factory : factories) {
if (factory->name() == "PipelineHandlerVimc") {
pipe_ = factory->create(nullptr);
break;