{"id":26471,"url":"https://patchwork.libcamera.org/api/1.1/patches/26471/?format=json","web_url":"https://patchwork.libcamera.org/patch/26471/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260407153427.1825999-32-laurent.pinchart@ideasonboard.com>","date":"2026-04-07T15:34:16","name":"[v2,31/42] libcamera: Pass CameraManager around instead of GlobalConfiguration","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"1c43757c71f267dc8d02be71dbba83c5e4d2c793","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/1.1/people/2/?format=json","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/26471/mbox/","series":[{"id":5873,"url":"https://patchwork.libcamera.org/api/1.1/series/5873/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5873","date":"2026-04-07T15:33:45","name":"libcamera: Global configuration file improvements","version":2,"mbox":"https://patchwork.libcamera.org/series/5873/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/26471/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/26471/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 16992C32F7\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  7 Apr 2026 15:35:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 90A5762E34;\n\tTue,  7 Apr 2026 17:35:18 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7F87062E1A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  7 Apr 2026 17:35:11 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id E87D7C58\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  7 Apr 2026 17:33:43 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"B2MGRFd9\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1775576024;\n\tbh=3at8PC8gVCz6SvWxMVJ345PHN657ctcrqP5XClwUvfw=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=B2MGRFd9UOgB+1+Nu2EPJMk2+2xzXKjJnZN/F8Vr/FWi/xFj26PkJGOYxBQIRC0CB\n\tTT8AvgtBMs8Cbo+wcM/gmLU30E28AT57CKmdg7JlOLYul3Y4rTsRhe6/OTGO8hHxvB\n\tDlWmXpD+ys4RTWPLe5aCba3LEfoozX+FU7zKIQ38=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Subject":"[PATCH v2 31/42] libcamera: Pass CameraManager around instead of\n\tGlobalConfiguration","Date":"Tue,  7 Apr 2026 18:34:16 +0300","Message-ID":"<20260407153427.1825999-32-laurent.pinchart@ideasonboard.com>","X-Mailer":"git-send-email 2.52.0","In-Reply-To":"<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>","References":"<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"The GlobalConfiguration is explicitly passed around through constructors\nof various objects that need access to the configuration. This ad-hoc\nsolution works for the specific use cases it was meant to support, but\nisn't very generic. We have a top-level object in libcamera, the\nCameraManager, that also needs to be accessed from various locations and\nis passed to object constructors. Standardize on passing the\nCameraManager everywhere, and access the global configuration through\nit.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n---\n include/libcamera/internal/ipa_manager.h         | 10 +++++-----\n include/libcamera/internal/ipa_proxy.h           |  4 ++--\n .../libcamera/internal/software_isp/benchmark.h  |  6 +++---\n .../internal/software_isp/swstats_cpu.h          |  6 +++---\n src/libcamera/camera_manager.cpp                 |  3 ++-\n src/libcamera/ipa_manager.cpp                    |  7 +++++--\n src/libcamera/ipa_proxy.cpp                      | 16 +++++++++++-----\n src/libcamera/software_isp/benchmark.cpp         |  7 ++++++-\n src/libcamera/software_isp/debayer.cpp           | 14 ++++++--------\n src/libcamera/software_isp/debayer.h             |  4 ++--\n src/libcamera/software_isp/debayer_cpu.cpp       |  7 ++++---\n src/libcamera/software_isp/debayer_cpu.h         |  4 ++--\n src/libcamera/software_isp/debayer_egl.cpp       |  7 +++----\n src/libcamera/software_isp/debayer_egl.h         |  4 +++-\n src/libcamera/software_isp/software_isp.cpp      |  9 +++++----\n src/libcamera/software_isp/swstats_cpu.cpp       |  8 ++++----\n test/ipa/ipa_interface_test.cpp                  |  5 +----\n .../module_ipa_proxy.cpp.tmpl                    |  8 ++++----\n .../libcamera_templates/module_ipa_proxy.h.tmpl  |  4 ++--\n 19 files changed, 73 insertions(+), 60 deletions(-)","diff":"diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\nindex ecb6ae896e0c..aaa3ca37c493 100644\n--- a/include/libcamera/internal/ipa_manager.h\n+++ b/include/libcamera/internal/ipa_manager.h\n@@ -16,13 +16,13 @@\n #include <libcamera/ipa/ipa_interface.h>\n #include <libcamera/ipa/ipa_module_info.h>\n \n-#include \"libcamera/internal/camera_manager.h\"\n #include \"libcamera/internal/pub_key.h\"\n \n namespace libcamera {\n \n LOG_DECLARE_CATEGORY(IPAManager)\n \n+class CameraManager;\n class GlobalConfiguration;\n class IPAModule;\n class PipelineHandler;\n@@ -30,7 +30,7 @@ class PipelineHandler;\n class IPAManager\n {\n public:\n-\tIPAManager(const GlobalConfiguration &configuration);\n+\tIPAManager(const CameraManager &cm);\n \t~IPAManager();\n \n \ttemplate<typename T>\n@@ -43,9 +43,9 @@ public:\n \n \t\tauto proxy = [&]() -> std::unique_ptr<T> {\n \t\t\tif (isSignatureValid(m))\n-\t\t\t\treturn std::make_unique<typename T::Threaded>(m, configuration_);\n+\t\t\t\treturn std::make_unique<typename T::Threaded>(m, cm_);\n \t\t\telse\n-\t\t\t\treturn std::make_unique<typename T::Isolated>(m, configuration_);\n+\t\t\t\treturn std::make_unique<typename T::Isolated>(m, cm_);\n \t\t}();\n \n \t\tif (!proxy->isValid()) {\n@@ -73,7 +73,7 @@ private:\n \n \tbool isSignatureValid(IPAModule *ipa) const;\n \n-\tconst GlobalConfiguration &configuration_;\n+\tconst CameraManager &cm_;\n \tstd::vector<std::unique_ptr<IPAModule>> modules_;\n \n #if HAVE_IPA_PUBKEY\ndiff --git a/include/libcamera/internal/ipa_proxy.h b/include/libcamera/internal/ipa_proxy.h\nindex f1865d67e8d3..723978426950 100644\n--- a/include/libcamera/internal/ipa_proxy.h\n+++ b/include/libcamera/internal/ipa_proxy.h\n@@ -13,7 +13,7 @@\n \n #include <libcamera/ipa/ipa_interface.h>\n \n-#include \"libcamera/internal/global_configuration.h\"\n+#include \"libcamera/internal/camera_manager.h\"\n \n namespace libcamera {\n \n@@ -28,7 +28,7 @@ public:\n \t\tProxyRunning,\n \t};\n \n-\tIPAProxy(IPAModule *ipam, const GlobalConfiguration &configuration);\n+\tIPAProxy(IPAModule *ipam, const CameraManager &cm);\n \t~IPAProxy();\n \n \tbool isValid() const { return valid_; }\ndiff --git a/include/libcamera/internal/software_isp/benchmark.h b/include/libcamera/internal/software_isp/benchmark.h\nindex 5526abc56f64..cc7f9d71e7fa 100644\n--- a/include/libcamera/internal/software_isp/benchmark.h\n+++ b/include/libcamera/internal/software_isp/benchmark.h\n@@ -13,15 +13,15 @@\n #include <stdint.h>\n #include <string>\n #include <time.h>\n-#include <libcamera/base/log.h>\n-#include \"libcamera/internal/global_configuration.h\"\n \n namespace libcamera {\n \n+class CameraManager;\n+\n class Benchmark\n {\n public:\n-\tBenchmark(const GlobalConfiguration &configuration, const std::string &name);\n+\tBenchmark(const CameraManager &cm, const std::string &name);\n \t~Benchmark();\n \n \tvoid startFrame(void);\ndiff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\nindex feee92f999d2..802370bdb59c 100644\n--- a/include/libcamera/internal/software_isp/swstats_cpu.h\n+++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n@@ -20,7 +20,6 @@\n \n #include \"libcamera/internal/bayer_format.h\"\n #include \"libcamera/internal/framebuffer.h\"\n-#include \"libcamera/internal/global_configuration.h\"\n #include \"libcamera/internal/shared_mem_object.h\"\n #include \"libcamera/internal/software_isp/swisp_stats.h\"\n \n@@ -28,14 +27,15 @@\n \n namespace libcamera {\n \n-class PixelFormat;\n+class CameraManager;\n class MappedFrameBuffer;\n+class PixelFormat;\n struct StreamConfiguration;\n \n class SwStatsCpu\n {\n public:\n-\tSwStatsCpu(const GlobalConfiguration &configuration);\n+\tSwStatsCpu(const CameraManager &cm);\n \t~SwStatsCpu() = default;\n \n \t/*\ndiff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp\nindex 5762c210ffc2..f774bd84291b 100644\n--- a/src/libcamera/camera_manager.cpp\n+++ b/src/libcamera/camera_manager.cpp\n@@ -93,7 +93,8 @@ void CameraManager::Private::run()\n \n int CameraManager::Private::init()\n {\n-\tipaManager_ = std::make_unique<IPAManager>(configuration());\n+\tCameraManager *const o = LIBCAMERA_O_PTR();\n+\tipaManager_ = std::make_unique<IPAManager>(*o);\n \n \tenumerator_ = DeviceEnumerator::create();\n \tif (!enumerator_ || enumerator_->enumerate())\ndiff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\nindex 1e905e8b82e8..dd1f483beec3 100644\n--- a/src/libcamera/ipa_manager.cpp\n+++ b/src/libcamera/ipa_manager.cpp\n@@ -100,13 +100,16 @@ LOG_DEFINE_CATEGORY(IPAManager)\n \n /**\n  * \\brief Construct an IPAManager instance\n+ * \\param[in] cm The camera manager\n  *\n  * The IPAManager class is meant to only be instantiated once, by the\n  * CameraManager.\n  */\n-IPAManager::IPAManager(const GlobalConfiguration &configuration)\n-\t: configuration_(configuration)\n+IPAManager::IPAManager(const CameraManager &cm)\n+\t: cm_(cm)\n {\n+\tconst GlobalConfiguration &configuration = cm._d()->configuration();\n+\n #if HAVE_IPA_PUBKEY\n \tif (!pubKey_.isValid())\n \t\tLOG(IPAManager, Warning) << \"Public key not valid\";\ndiff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp\nindex a3ccfa6035e1..6c8780a012d5 100644\n--- a/src/libcamera/ipa_proxy.cpp\n+++ b/src/libcamera/ipa_proxy.cpp\n@@ -117,13 +117,19 @@ std::string ipaConfigurationFile(const std::string &ipaName, const std::string &\n /**\n  * \\brief Construct an IPAProxy instance\n  * \\param[in] ipam The IPA module\n- * \\param[in] configuration The global configuration\n+ * \\param[in] cm The camera manager\n  */\n-IPAProxy::IPAProxy(IPAModule *ipam, const GlobalConfiguration &configuration)\n-\t: valid_(false), state_(ProxyStopped), ipam_(ipam),\n-\t  configPaths_(configuration.envListOption(\"LIBCAMERA_IPA_CONFIG_PATH\", { \"ipa\", \"config_paths\" }).value_or(std::vector<std::string>())),\n-\t  execPaths_(configuration.envListOption(\"LIBCAMERA_IPA_PROXY_PATH\", { \"ipa\", \"proxy_paths\" }).value_or(std::vector<std::string>()))\n+IPAProxy::IPAProxy(IPAModule *ipam, const CameraManager &cm)\n+\t: valid_(false), state_(ProxyStopped), ipam_(ipam)\n {\n+\tconst GlobalConfiguration &configuration = cm._d()->configuration();\n+\n+\tconfigPaths_ = configuration.envListOption(\"LIBCAMERA_IPA_CONFIG_PATH\",\n+\t\t\t\t\t\t   { \"ipa\", \"config_paths\" })\n+\t\t\t\t    .value_or(std::vector<std::string>());\n+\texecPaths_ = configuration.envListOption(\"LIBCAMERA_IPA_PROXY_PATH\",\n+\t\t\t\t\t\t { \"ipa\", \"proxy_paths\" })\n+\t\t\t\t  .value_or(std::vector<std::string>());\n }\n \n IPAProxy::~IPAProxy()\ndiff --git a/src/libcamera/software_isp/benchmark.cpp b/src/libcamera/software_isp/benchmark.cpp\nindex 36c49770e1a7..96f0ae004563 100644\n--- a/src/libcamera/software_isp/benchmark.cpp\n+++ b/src/libcamera/software_isp/benchmark.cpp\n@@ -12,6 +12,9 @@\n \n #include <libcamera/base/log.h>\n \n+#include \"libcamera/internal/camera_manager.h\"\n+#include \"libcamera/internal/global_configuration.h\"\n+\n namespace libcamera {\n \n LOG_DEFINE_CATEGORY(Benchmark)\n@@ -26,9 +29,11 @@ LOG_DEFINE_CATEGORY(Benchmark)\n /**\n  * \\brief Constructs a Benchmark object\n  */\n-Benchmark::Benchmark(const GlobalConfiguration &configuration, const std::string &name)\n+Benchmark::Benchmark(const CameraManager &cm, const std::string &name)\n \t: name_(name)\n {\n+\tconst GlobalConfiguration &configuration = cm._d()->configuration();\n+\n \tskipBeforeMeasure_ = configuration.option<unsigned int>(\n \t\t\t\t\t\t{ \"software_isp\", \"measure\", \"skip\" })\n \t\t\t\t\t\t\t.value_or(skipBeforeMeasure_);\ndiff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp\nindex a6bceb58b787..2d7abfb8325d 100644\n--- a/src/libcamera/software_isp/debayer.cpp\n+++ b/src/libcamera/software_isp/debayer.cpp\n@@ -18,12 +18,6 @@ namespace libcamera {\n  * \\brief Struct to hold the debayer parameters.\n  */\n \n-/**\n- * \\fn Debayer::Debayer(const GlobalConfiguration &configuration)\n- * \\brief Construct a Debayer object\n- * \\param[in] configuration Global configuration reference\n- */\n-\n /**\n  * \\var DebayerParams::gains\n  * \\brief Colour channel gains\n@@ -58,8 +52,12 @@ namespace libcamera {\n \n LOG_DEFINE_CATEGORY(Debayer)\n \n-Debayer::Debayer(const GlobalConfiguration &configuration)\n-\t: bench_(configuration, \"Debayer\")\n+/**\n+ * \\brief Construct a Debayer object\n+ * \\param[in] cm The camera manager\n+ */\n+Debayer::Debayer(const CameraManager &cm)\n+\t: bench_(cm, \"Debayer\")\n {\n }\n \ndiff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h\nindex ea1ec6dcf857..a2a17ec18495 100644\n--- a/src/libcamera/software_isp/debayer.h\n+++ b/src/libcamera/software_isp/debayer.h\n@@ -22,12 +22,12 @@\n \n #include \"libcamera/internal/bayer_format.h\"\n #include \"libcamera/internal/dma_buf_allocator.h\"\n-#include \"libcamera/internal/global_configuration.h\"\n #include \"libcamera/internal/software_isp/benchmark.h\"\n #include \"libcamera/internal/software_isp/debayer_params.h\"\n \n namespace libcamera {\n \n+class CameraManager;\n class FrameBuffer;\n \n LOG_DECLARE_CATEGORY(Debayer)\n@@ -35,7 +35,7 @@ LOG_DECLARE_CATEGORY(Debayer)\n class Debayer : public Object\n {\n public:\n-\tDebayer(const GlobalConfiguration &configuration);\n+\tDebayer(const CameraManager &cm);\n \tvirtual ~Debayer() = 0;\n \n \tvirtual int configure(const StreamConfiguration &inputCfg,\ndiff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\nindex dd0fff871414..d9f5b32689e7 100644\n--- a/src/libcamera/software_isp/debayer_cpu.cpp\n+++ b/src/libcamera/software_isp/debayer_cpu.cpp\n@@ -89,10 +89,10 @@ DebayerCpuThread::DebayerCpuThread(DebayerCpu *debayer, unsigned int threadIndex\n /**\n  * \\brief Constructs a DebayerCpu object\n  * \\param[in] stats Pointer to the stats object to use\n- * \\param[in] configuration The global configuration\n+ * \\param[in] cm The camera manager\n  */\n-DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration)\n-\t: Debayer(configuration), stats_(std::move(stats))\n+DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm)\n+\t: Debayer(cm), stats_(std::move(stats))\n {\n \t/*\n \t * Reading from uncached buffers may be very slow.\n@@ -105,6 +105,7 @@ DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats, const GlobalConfigurat\n \t * \\todo Make memcpy automatic based on runtime detection of platform\n \t * capabilities.\n \t */\n+\tconst GlobalConfiguration &configuration = cm._d()->configuration();\n \tbool enableInputMemcpy =\n \t\tconfiguration.option<bool>({ \"software_isp\", \"copy_input_buffer\" }).value_or(true);\n \ndiff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\nindex 05fecc8feb56..4f7a924b0abd 100644\n--- a/src/libcamera/software_isp/debayer_cpu.h\n+++ b/src/libcamera/software_isp/debayer_cpu.h\n@@ -19,7 +19,7 @@\n #include <libcamera/base/object.h>\n \n #include \"libcamera/internal/bayer_format.h\"\n-#include \"libcamera/internal/global_configuration.h\"\n+#include \"libcamera/internal/camera_manager.h\"\n #include \"libcamera/internal/software_isp/debayer_params.h\"\n #include \"libcamera/internal/software_isp/swstats_cpu.h\"\n \n@@ -31,7 +31,7 @@ class DebayerCpuThread;\n class DebayerCpu : public Debayer\n {\n public:\n-\tDebayerCpu(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration);\n+\tDebayerCpu(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm);\n \t~DebayerCpu();\n \n \tint configure(const StreamConfiguration &inputCfg,\ndiff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\nindex 2ad258bca69f..8f0c229fd823 100644\n--- a/src/libcamera/software_isp/debayer_egl.cpp\n+++ b/src/libcamera/software_isp/debayer_egl.cpp\n@@ -29,13 +29,12 @@ namespace libcamera {\n  */\n \n /**\n- * \\fn DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration)\n  * \\brief Construct a DebayerEGL object\n  * \\param[in] stats Statistics processing object\n- * \\param[in] configuration Global configuration reference\n+ * \\param[in] cm The camera manager\n  */\n-DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration)\n-\t: Debayer(configuration), stats_(std::move(stats))\n+DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm)\n+\t: Debayer(cm), stats_(std::move(stats))\n {\n }\n \ndiff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\nindex bdde676f2394..5b6c440f5d27 100644\n--- a/src/libcamera/software_isp/debayer_egl.h\n+++ b/src/libcamera/software_isp/debayer_egl.h\n@@ -35,10 +35,12 @@ namespace libcamera {\n #define DEBAYER_EGL_MIN_SIMPLE_RGB_GAIN_TEXTURE_UNITS 4\n #define DEBAYER_OPENGL_COORDS 4\n \n+class CameraManager;\n+\n class DebayerEGL : public Debayer\n {\n public:\n-\tDebayerEGL(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration);\n+\tDebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm);\n \t~DebayerEGL();\n \n \tint configure(const StreamConfiguration &inputCfg,\ndiff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\nindex 5b225c7cff93..cd0e9d06a1e1 100644\n--- a/src/libcamera/software_isp/software_isp.cpp\n+++ b/src/libcamera/software_isp/software_isp.cpp\n@@ -95,9 +95,9 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n \t\treturn;\n \t}\n \n-\tconst GlobalConfiguration &configuration = pipe->cameraManager()->_d()->configuration();\n+\tconst CameraManager &cm = *pipe->cameraManager();\n \n-\tauto stats = std::make_unique<SwStatsCpu>(configuration);\n+\tauto stats = std::make_unique<SwStatsCpu>(cm);\n \tif (!stats->isValid()) {\n \t\tLOG(SoftwareIsp, Error) << \"Failed to create SwStatsCpu object\";\n \t\treturn;\n@@ -105,6 +105,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n \tstats->statsReady.connect(this, &SoftwareIsp::statsReady);\n \n #if HAVE_DEBAYER_EGL\n+\tconst GlobalConfiguration &configuration = cm._d()->configuration();\n \tstd::optional<std::string> softISPMode = configuration.envOption(\"LIBCAMERA_SOFTISP_MODE\", { \"software_isp\", \"mode\" });\n \tif (softISPMode) {\n \t\tif (softISPMode != \"gpu\" && softISPMode != \"cpu\") {\n@@ -117,11 +118,11 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n \t}\n \n \tif (!softISPMode || softISPMode == \"gpu\")\n-\t\tdebayer_ = std::make_unique<DebayerEGL>(std::move(stats), configuration);\n+\t\tdebayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm);\n \n #endif\n \tif (!debayer_)\n-\t\tdebayer_ = std::make_unique<DebayerCpu>(std::move(stats), configuration);\n+\t\tdebayer_ = std::make_unique<DebayerCpu>(std::move(stats), cm);\n \n \tdebayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);\n \tdebayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);\ndiff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\nindex 3595c9e690f1..5366e019fe3f 100644\n--- a/src/libcamera/software_isp/swstats_cpu.cpp\n+++ b/src/libcamera/software_isp/swstats_cpu.cpp\n@@ -36,9 +36,9 @@ namespace libcamera {\n  */\n \n /**\n- * \\fn SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration)\n+ * \\fn SwStatsCpu::SwStatsCpu(const CameraManager &cm)\n  * \\brief Construct a SwStatsCpu object\n- * \\param[in] configuration Global configuration reference\n+ * \\param[in] cm The camera manager\n  *\n  * Creates a SwStatsCpu object and initialises shared memory for statistics\n  * exchange.\n@@ -159,8 +159,8 @@ namespace libcamera {\n \n LOG_DEFINE_CATEGORY(SwStatsCpu)\n \n-SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration)\n-\t: sharedStats_(\"softIsp_stats\"), bench_(configuration, \"CPU stats\")\n+SwStatsCpu::SwStatsCpu(const CameraManager &cm)\n+\t: sharedStats_(\"softIsp_stats\"), bench_(cm, \"CPU stats\")\n {\n \tif (!sharedStats_)\n \t\tLOG(SwStatsCpu, Error)\ndiff --git a/test/ipa/ipa_interface_test.cpp b/test/ipa/ipa_interface_test.cpp\nindex c1fe2267cc6e..271c4e2c9dc2 100644\n--- a/test/ipa/ipa_interface_test.cpp\n+++ b/test/ipa/ipa_interface_test.cpp\n@@ -47,7 +47,6 @@ public:\n \t\tnotifier_.reset();\n \t\tipa_.reset();\n \t\tipaManager_.reset();\n-\t\tconfig_.reset();\n \t\tcameraManager_.reset();\n \t}\n \n@@ -90,8 +89,7 @@ protected:\n \t\tnotifier_->activated.connect(this, &IPAInterfaceTest::readTrace);\n \n \t\t/* Create the IPA manager. */\n-\t\tconfig_ = std::make_unique<GlobalConfiguration>();\n-\t\tipaManager_ = std::make_unique<IPAManager>(*config_);\n+\t\tipaManager_ = std::make_unique<IPAManager>(*cameraManager_);\n \n \t\treturn TestPass;\n \t}\n@@ -169,7 +167,6 @@ private:\n \tstd::shared_ptr<PipelineHandler> pipe_;\n \tstd::unique_ptr<ipa::vimc::IPAProxyVimc> ipa_;\n \tstd::unique_ptr<CameraManager> cameraManager_;\n-\tstd::unique_ptr<GlobalConfiguration> config_;\n \tstd::unique_ptr<IPAManager> ipaManager_;\n \tenum ipa::vimc::IPAOperationCode trace_;\n \tstd::unique_ptr<EventNotifier> notifier_;\ndiff --git a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl\nindex e6e19b3030b9..0d0a16147edd 100644\n--- a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl\n+++ b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl\n@@ -45,8 +45,8 @@ namespace {{ns}} {\n {% endfor %}\n {%- endif %}\n \n-{{proxy_name}}Threaded::{{proxy_name}}Threaded(IPAModule *ipam, const GlobalConfiguration &configuration)\n-\t: {{proxy_name}}(ipam, configuration), thread_(\"{{proxy_name}}\")\n+{{proxy_name}}Threaded::{{proxy_name}}Threaded(IPAModule *ipam, const CameraManager &cm)\n+\t: {{proxy_name}}(ipam, cm), thread_(\"{{proxy_name}}\")\n {\n \tLOG(IPAProxy, Debug)\n \t\t<< \"initializing {{module_name}} proxy in thread: loading IPA from \"\n@@ -127,8 +127,8 @@ namespace {{ns}} {\n \n /* ========================================================================== */\n \n-{{proxy_name}}Isolated::{{proxy_name}}Isolated(IPAModule *ipam, const GlobalConfiguration &configuration)\n-\t: {{proxy_name}}(ipam, configuration),\n+{{proxy_name}}Isolated::{{proxy_name}}Isolated(IPAModule *ipam, const CameraManager &cm)\n+\t: {{proxy_name}}(ipam, cm),\n \t  controlSerializer_(ControlSerializer::Role::Proxy), seq_(0)\n {\n \tLOG(IPAProxy, Debug)\ndiff --git a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl\nindex ef280ca423f6..d48b90dcfa41 100644\n--- a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl\n+++ b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl\n@@ -50,7 +50,7 @@ protected:\n class {{proxy_name}}Threaded : public {{proxy_name}}\n {\n public:\n-\t{{proxy_name}}Threaded(IPAModule *ipam, const GlobalConfiguration &configuration);\n+\t{{proxy_name}}Threaded(IPAModule *ipam, const CameraManager &cm);\n \t~{{proxy_name}}Threaded();\n \n {% for method in interface_main.methods %}\n@@ -112,7 +112,7 @@ private:\n class {{proxy_name}}Isolated : public {{proxy_name}}\n {\n public:\n-\t{{proxy_name}}Isolated(IPAModule *ipam, const GlobalConfiguration &configuration);\n+\t{{proxy_name}}Isolated(IPAModule *ipam, const CameraManager &cm);\n \t~{{proxy_name}}Isolated();\n \n {% for method in interface_main.methods %}\n","prefixes":["v2","31/42"]}