From patchwork Wed Dec 17 10:01:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25574 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 366D4C326C for ; Wed, 17 Dec 2025 10:01:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8087461A37; Wed, 17 Dec 2025 11:01:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RmSrsvWH"; dkim-atps=neutral Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4810161A2C for ; Wed, 17 Dec 2025 11:01:43 +0100 (CET) Received: by mail-wm1-x341.google.com with SMTP id 5b1f17b1804b1-477a2ab455fso59485825e9.3 for ; Wed, 17 Dec 2025 02:01:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965702; x=1766570502; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dZHtM5rS1+WasttTnOa/hgF19f8pxm9uPEY0c2MJV14=; b=RmSrsvWH9jgiRhMvEn5xbNVHx/Mro0LxV77n0Le01NLG4cZpn8EAFFTI5YB4aRWjEl C/6OQ0Va8PqP6BA0Z1YzEIOv+cF8xAgVFteINuQpCEWk74MAA0EpUyoNipvCPlePyL64 xccokET6dUGN3pbaMMDSaP11t7hqsbVeWIz6HV4P96n/NdGn/RS1LcGt97BhXkmryBw4 1MVDMWCBPrUUn+FKmqlB6T+HZpT9DJqlm+OiEzplzw3feMZZWqJZfwDmcMn1ZxlVOahE WbSWb1f3H8L8HcatTgnnE2aDYTCZubYYaSFuMq4aZGtKluiI0Q4TNBO3X4wGmGwtpQxg a4Sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965702; x=1766570502; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=dZHtM5rS1+WasttTnOa/hgF19f8pxm9uPEY0c2MJV14=; b=wpmbApgdoGkJCRgP1rcPwxedqKBBzZ0IjILtsjWhTEqTl1vbMfrB53VNLAl2jceLaJ KXcY1dgzyTkrhum8DcMbsY78Vx7BB/xsb1EWaw9uIm/oEuH8K9KvUzosR6PKpAr0TTkl PmCGzbHMxacbhv3k48N6i0CCYTIhNEOgvWri/aD/Is/d8ypgoEQHstcdLu3DUFaaMR79 wrhLOpzFGQMGvkfepfeYGrt0Pf/PPlzMfZ+Vji8QhCCFeEX3f5AjcSdor0Iap5rslFGK ehslBxmaSUbmTqK0WKonNIwT85yhMXhbbfC7Ksrwkc4asNUcv1URWzzYPbJDYWbRsMCi qK+w== X-Gm-Message-State: AOJu0Yworxukr4t214YnLXsIvOdJONnxPrty4ld8ROyM8LlVcYB4EwwW OEQYtUw8g2MGP9qfg+R1QMgZzV5tCA2MlWg4/zcy8oPZpe4SozMPKpZmfiVgbKaUEjucbmy7JLj 8nlL72Gg= X-Gm-Gg: AY/fxX4CJ/wwPxD0nqtDPW2itw3Oe3k5B6NeET/PGyckJWTNWOQQgt2voU2lUVTt3PA ZDluvf1VyxYehPmD1FNzM1IL/0QRpo89bZ6+OvLmxtjL4BrCRIab/alPQ2ed0sV0NESPM4inBUq ec0SDJqDO0tOrsGp3BC3LUGPvZV4dGbSgLYNs0OEb5ZUEUYI9gcmzGG3dMuT8m1juSL8ZRCfdPj en1gkDldEkaH95dwv+qwwZ8BCLV4bfZwj9TiJNP/d6evFnRikf/tmJunN6ZjG8o9OcQ3q0JAATU aLwcpdRM4HRz0nJvIdOGl7FZ5CyIqExsLpOTC/+cSWwkBePYT24YdHIswtXJShndl1ypedXCYid +MiejY47ACWoN+eRoR8TsGjuDAkVXu6dbc82naxsQnPkfquhY0Sv99SvJ61L1XyJxMDOVizAGVW YawUyTI86J2vgO5WTDAZWWrmhSn0rJZtQ1wvqTaXXQot2rYk8dH8HjlJkcOtDLRCWm4cM= X-Google-Smtp-Source: AGHT+IHMTrPrehygcRjE2z/y9prMTCpPyyhNNyfOPbLgTjg29NyqDEMimKI+CpaAnhVH8xaKxGDXtw== X-Received: by 2002:a05:600c:19cd:b0:47a:819f:3acf with SMTP id 5b1f17b1804b1-47a8f8abfa7mr186808455e9.10.1765965702492; Wed, 17 Dec 2025 02:01:42 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:42 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Kieran Bingham , Milan Zamazal Subject: [PATCH v9 01/26] libcamera: software_isp: gbm: Add a GBM helper class for GPU surface access Date: Wed, 17 Dec 2025 10:01:13 +0000 Message-ID: <20251217100138.82525-2-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" A helper class to interact with GBM. This will allow us to specify the internal storage format of the GPU when making a texture for the Debayer vertex/fragment shaders and thus ensure we receive an uncompressed and untiled output buffer. Acked-by: Kieran Bingham Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue Reviewed-by: Robert Mader --- include/libcamera/internal/gbm.h | 39 ++++++++ include/libcamera/internal/meson.build | 1 + src/libcamera/gbm.cpp | 130 +++++++++++++++++++++++++ src/libcamera/meson.build | 10 ++ 4 files changed, 180 insertions(+) create mode 100644 include/libcamera/internal/gbm.h create mode 100644 src/libcamera/gbm.cpp diff --git a/include/libcamera/internal/gbm.h b/include/libcamera/internal/gbm.h new file mode 100644 index 000000000..09811d1ef --- /dev/null +++ b/include/libcamera/internal/gbm.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + * Helper class for managing GBM interactions + */ + +#pragma once + +#include + +#include + +#include + +namespace libcamera { + +LOG_DECLARE_CATEGORY(GBM) + +class GBM +{ +public: + GBM(); + ~GBM(); + + int createDevice(); + struct gbm_device *getDevice(); + PixelFormat getPixelFormat(); + +private: + int fd_; + struct gbm_device *gbmDevice_; + PixelFormat format_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index e9540a2f7..b8324996b 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -23,6 +23,7 @@ libcamera_internal_headers = files([ 'dma_buf_allocator.h', 'formats.h', 'framebuffer.h', + 'gbm.h', 'global_configuration.h', 'ipa_data_serializer.h', 'ipa_manager.h', diff --git a/src/libcamera/gbm.cpp b/src/libcamera/gbm.cpp new file mode 100644 index 000000000..659860500 --- /dev/null +++ b/src/libcamera/gbm.cpp @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + * Helper class for managing GBM interactions + */ + +#include "libcamera/internal/gbm.h" + +#include +#include +#include +#include +#include + +#include +#include + +namespace libcamera { + +LOG_DEFINE_CATEGORY(GBM) + +/** + * \class GBM + * \brief Helper class for managing GBM interactions + * + * The GBM class provides a simplified interface for creating and managing + * GBM devices. It handles the initialization and teardown of GBM devices + * used for buffer allocation in graphics and camera pipelines. + * + * This class is responsible for opening a DRI render node, creating a GBM + * device, and providing access to the device and its associated pixel format. + */ + +/** + *\var GBM::fd_ + *\brief file descriptor to DRI device + */ + +/** + *\var GBM::gbmDevice_ + *\brief Pointer to GBM device structure derived from fd_ + */ + +/** + *\var GBM::format_ + *\brief Pixel format the GBM surface was created in + */ + +/** + *\brief GBM constructor. + * + * Creates a GBM instance with unitialised state. + */ +GBM::GBM() +{ + fd_ = 0; + gbmDevice_ = nullptr; +} + +/** + *\brief GBM destructor + * + * Cleans up the GBM device if it was successfully created, and closes + * the associated file descriptor. + */ +GBM::~GBM() +{ + if (gbmDevice_) + gbm_device_destroy(gbmDevice_); +} + +/** + * \brief Create and initialize a GBM device + * + * \todo Get dri device name from envOption setting + * + * Opens the DRI render node (/dev/dri/renderD128) and creates a GBM + * device using the libgbm library. Sets the default pixel format to + * ARGB8888. + * + * \return 0 on success, or a negative error code on failure + */ +int GBM::createDevice() +{ + const char *dri_node = "/dev/dri/renderD128"; + + fd_ = open(dri_node, O_RDWR | O_CLOEXEC); + if (fd_ < 0) { + LOG(GBM, Error) << "Open " << dri_node << " fail " << fd_; + return fd_; + } + + gbmDevice_ = gbm_create_device(fd_); + if (!gbmDevice_) { + LOG(GBM, Error) << "gbm_create_device fail"; + close(fd_); + return -errno; + } + + format_ = libcamera::formats::ARGB8888; + + return 0; +} + +/** + * \brief Retrieve the GBM device handle + * + * \return Pointer to the gbm_device structure, or nullptr if the device + * has not been created + */ +struct gbm_device *GBM::getDevice() +{ + return gbmDevice_; +} + +/** + * \brief Retrieve the pixel format + * + * \return The PixelFormat used by this GBM instance (ARGB8888) + */ + +PixelFormat GBM::getPixelFormat() +{ + return format_; +} +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 575408b2c..e5b5330a8 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -70,6 +70,15 @@ libcamera_deps = [] libatomic = cc.find_library('atomic', required : false) libthreads = dependency('threads') +libgbm = cc.find_library('gbm', required: false) +gbm_works = cc.check_header('gbm.h', required: false) + +if libgbm.found() and gbm_works + libcamera_internal_sources += files([ + 'gbm.cpp', + ]) +endif + subdir('base') subdir('converter') subdir('ipa') @@ -178,6 +187,7 @@ libcamera_deps += [ libcamera_base_private, libcrypto, libdl, + libgbm, liblttng, libudev, libyaml, From patchwork Wed Dec 17 10:01:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25575 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 7A5B9C3257 for ; Wed, 17 Dec 2025 10:01:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 82D3C61A4C; Wed, 17 Dec 2025 11:01:49 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="UB/otWAU"; dkim-atps=neutral Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 18D92609DE for ; Wed, 17 Dec 2025 11:01:45 +0100 (CET) Received: by mail-wm1-x343.google.com with SMTP id 5b1f17b1804b1-47796a837c7so40437935e9.0 for ; Wed, 17 Dec 2025 02:01:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965704; x=1766570504; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vOmBUGR5sLk+T64wEUuxLhWzrd/gAp6qdIYxfuOs9p4=; b=UB/otWAUwNZZwKEAPOUyXegUdXcWT7RQCJ7FW7gTc0RUqQwiRji+fklVuCY4HbCMkP zhWk3EhscFttYeltiS2tID6n38sj3ZTlFQHRqyn3gUnl1UhUrLL/nXOFaJswAhKm2fP5 zi3d/gWEmPbr8Tc3UIHxpk3Qd9gvy0QVC5zh1BTXx+inwGDTo0UPudarZEHLhOYHHMkx nS5EagWpRuKjTabkozw8gq82WN8fBh5ZKwC4cm5LgIuIGKfpYJhfVIAnwkTUTLrD4bi9 lt+C0YdzkmOvvBCIlXn0TfGjgVR1PqVoF2sJ1wMahPX6m9GSUpUivVAdpqWs4hbHIpmi Gd9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965704; x=1766570504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=vOmBUGR5sLk+T64wEUuxLhWzrd/gAp6qdIYxfuOs9p4=; b=xIs8jmMPFlDe8SvY/baPIHUMofhGRS82WsoJolZOQiof+7DFXThU7aKg5dH2njO2nJ OatZ0mCQqJmPk9enmKwvlo89Qk2q9SdFyySQFubgC4PPxWhwOa/fbbwstvPnPazx3KK1 Pd6aWz7WKFHvYFq/DwYcbnNPQSD872R4lqEKXG8yr0FEic3B1QA4OulJQ9hdGw6vCVuW KFUKYMVObo0HiVPCcuNvKvUiL3MF2Umzkjfab5yIgovgoRPbgafk6k4bnd9JLW5uJEVX Lvi/5nduMz5Tx9VZmOAWbRgvET6eMzKNnQfIfz3CfyzwvDgDKfplJhWLHmjFOePl4obW in7Q== X-Gm-Message-State: AOJu0YxywAXjV7NpKeXTAm1eKPk7pz27X2WO2uYdYfkgsvf0TmrX49RL ZbECaqfHUk9BzoYR9OX3GoXTexUmfSck4QUzaBTTS4y3ou+xhencG5ASocYw8HI+OPt+MUm6wYY 5+3sizoI= X-Gm-Gg: AY/fxX6ghRls6XqIwILjcSjv6aV9pncuQSqiklKXLmuMJKIxQtvFPafp71u1wNEvcxQ 4x0czGzrZQHcmc1GI9xoo5StQpylgoIjw1h/aFfRo0hPwfMcBx5niy2MFx5hitJDGc7SAnBj4Bi fd3OVX4IWH0tUWCKPTy1wF+Uxh0xKXMfmGG9zy9BH+Gqfkfm8gjSGokrhMsspDRlhs0vqbIXuVK qADyvTGJLoSiSjGJxilTF9qqlH/XxH4Bwgkj9Vy866Dxm/H5SEm/XCRHh9tHPasjmwXSw5yBitC g//DjZOsWHZkdoA/sMQlQpoq/86Ihlo/Nap1pzJJW5lcCfnW7EObGvo2E9omGBn9Ypep3RU+l9E 7aTqg2PV9LAqe+Nrqvhzvt4jOckPA8FBLs6pPv5Vy0HtzgOyyH1rGLZgBxE2qsqOvIy9aMu/FJY ntf2A2fxoH96P8EAx7riHh2EAHqdZZGCDLiJffwroTQsvWCXR3+OxpkqwTztbSxV0JUGy1BWHhw L6OhQ== X-Google-Smtp-Source: AGHT+IGloi15L8X+MdHQRnvA1rru6d5+hfcMYKv7pCykyCWLZUC6pxv4djG0RK/MA+LKbA4/KGMheg== X-Received: by 2002:a05:600c:37cf:b0:471:1774:3003 with SMTP id 5b1f17b1804b1-47bd74aec30mr47149995e9.29.1765965703545; Wed, 17 Dec 2025 02:01:43 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:43 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Kieran Bingham , Hans de Goede , Milan Zamazal Subject: [PATCH v9 02/26] libcamera: software_isp: egl: Add a eGL base helper class Date: Wed, 17 Dec 2025 10:01:14 +0000 Message-ID: <20251217100138.82525-3-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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 an eGL base helper class which provides an eGL context based on a passed width and height. The initGLContext function could be overloaded to provide an interface to a real display. A set of helper functions is provided to compile and link GLSL shaders. linkShaderProgram currently compiles vertex/fragment pairs but could be overloaded or passed a parameter to link a compute shader instead. Breaking the eGL interface away from debayering - allows to use the eGL context inside of a dma-buf heap cleanly, reuse that context inside of a debayer layer and conceivably reuse the context in a multi-stage shader pass. Small note the image_attrs[] array doesn't pass checkstyle.py however the elements of the array are in pairs. Acked-by: Kieran Bingham [bod: Takes fix from Hans for constructor stride bpp] [bod: Drops eglClientWaitSync in favour of glFinish Robert/Milan] Co-developed-by: Hans de Goede Signed-off-by: Hans de Goede Co-developed-by: Milan Zamazal Signed-off-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue Reviewed-by: Robert Mader Acked-by: Kieran Bingham --- include/libcamera/internal/egl.h | 185 ++++++++++ src/libcamera/egl.cpp | 612 +++++++++++++++++++++++++++++++ src/libcamera/meson.build | 23 ++ 3 files changed, 820 insertions(+) create mode 100644 include/libcamera/internal/egl.h create mode 100644 src/libcamera/egl.cpp diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h new file mode 100644 index 000000000..1ed93f3dc --- /dev/null +++ b/include/libcamera/internal/egl.h @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + */ + +#pragma once + +#include +#include + +#include +#include +#include + +#include "libcamera/internal/gbm.h" + +#define EGL_EGLEXT_PROTOTYPES +#include +#include +#define GL_GLEXT_PROTOTYPES +#include +#include + +namespace libcamera { + +LOG_DECLARE_CATEGORY(eGL) + +/** + * \class eGLImage + * \brief Helper class for managing EGL image resources + * + * The eGLImage class encapsulates OpenGL ES texture and framebuffer objects + * along with their associated EGL image. It aggregates handles, descriptors, + * and routines for managing textures that can be associated with shader + * uniform IDs. + * + * This class is particularly useful for managing DMA-BUF backed textures + * in zero-copy rendering pipelines, where textures are bound to specific + * texture units and can be used as both input textures and render targets. + */ +class eGLImage +{ +public: + /** + * \brief Construct an eGLImage with explicit stride + * \param[in] width Image width in pixels + * \param[in] height Image height in pixels + * \param[in] bpp Bytes per pixel + * \param[in] stride Row stride in bytes + * \param[in] texture_unit OpenGL texture unit (e.g., GL_TEXTURE0) + * \param[in] texture_unit_uniform_id Shader uniform ID for this texture unit + * + * Creates an eGLImage with the specified dimensions and stride. The stride + * may differ from width * bpp due to alignment. + */ + eGLImage(uint32_t width, uint32_t height, uint32_t bpp, uint32_t stride, GLenum texture_unit, uint32_t texture_unit_uniform_id) + { + init(width, height, bpp, stride, texture_unit, texture_unit_uniform_id); + } + /** + * \brief Construct an eGLImage with automatic stride calculation + * \param[in] width Image width in pixels + * \param[in] height Image height in pixels + * \param[in] bpp Bytes per pixel + * \param[in] texture_unit OpenGL texture unit (e.g., GL_TEXTURE0) + * \param[in] texture_unit_uniform_id Shader uniform ID for this texture unit + * + * Creates an eGLImage with automatic stride calculation. The stride is + * aligned to 256 bytes because 256 byte alignment is a common baseline alignment for GPUs. + */ + eGLImage(uint32_t width, uint32_t height, uint32_t bpp, GLenum texture_unit, uint32_t texture_unit_uniform_id) + { + uint32_t stride = libcamera::utils::alignUp(width * bpp / 8, 256); + + init(width, height, bpp, stride, texture_unit, texture_unit_uniform_id); + } + + /** + * \brief Destroy the eGLImage + * + * Cleans up OpenGL resources by deleting the framebuffer object and + * texture. + */ + ~eGLImage() + { + glDeleteFramebuffers(1, &fbo_); + glDeleteTextures(1, &texture_); + } + + uint32_t width_; /**< Image width in pixels */ + uint32_t height_; /**< Image height in pixels */ + uint32_t stride_; /**< Row stride in bytes */ + uint32_t offset_; /**< Buffer offset (reserved for future use) */ + uint32_t framesize_; /**< Total frame size in bytes (stride * height) */ + uint32_t bpp_; /**< Bytes per pixel */ + uint32_t texture_unit_uniform_id_; /**< Shader uniform id for texture unit */ + GLenum texture_unit_; /**< Texture unit associated with this image eg (GL_TEXTURE0) */ + GLuint texture_; /**< OpenGL texture object ID */ + GLuint fbo_; /**< OpenGL frame buffer object ID */ + EGLImageKHR image_; /**< EGL Image handle */ + +private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(eGLImage) + + /** + * \brief Initialise eGLImage state + * \param[in] width Image width in pixels + * \param[in] height Image height in pixels + * \param[in] bpp Bytes per pixel + * \param[in] stride Row stride in bytes + * \param[in] texture_unit OpenGL texture unit + * \param[in] texture_unit_uniform_id Shader uniform ID + * + * Common initialisation routine called by both constructors. Sets up + * member variables and generates OpenGL texture and framebuffer objects. + */ + void init(uint32_t width, uint32_t height, uint32_t bpp, uint32_t stride, GLenum texture_unit, uint32_t texture_unit_uniform_id) + { + image_ = EGL_NO_IMAGE_KHR; + width_ = width; + height_ = height; + bpp_ = bpp; + stride_ = stride; + framesize_ = stride_ * height_; + texture_unit_ = texture_unit; + texture_unit_uniform_id_ = texture_unit_uniform_id; + + glGenTextures(1, &texture_); + glGenFramebuffers(1, &fbo_); + } +}; + +class eGL +{ +public: + eGL(); + ~eGL(); + + int initEGLContext(GBM *gbmContext); + void cleanUp(); + + int createInputDMABufTexture2D(std::unique_ptr &eglImage, int fd); + int createOutputDMABufTexture2D(std::unique_ptr &eglImage, int fd); + void destroyDMABufTexture(std::unique_ptr &eglImage); + void createTexture2D(std::unique_ptr &eglImage, GLint format, uint32_t width, uint32_t height, void *data); + + void pushEnv(std::vector &shaderEnv, const char *str); + void makeCurrent(); + + int compileVertexShader(GLuint &shaderId, const unsigned char *shaderData, + unsigned int shaderDataLen, + Span shaderEnv); + int compileFragmentShader(GLuint &shaderId, const unsigned char *shaderData, + unsigned int shaderDataLen, + Span shaderEnv); + int linkProgram(GLuint &programId, GLuint fragmentshaderId, GLuint vertexshaderId); + void dumpShaderSource(GLuint shaderId); + void useProgram(GLuint programId); + void deleteProgram(GLuint programId); + void syncOutput(); + +private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(eGL) + + pid_t tid_; + + EGLDisplay display_; + EGLContext context_; + EGLSurface surface_; + + int compileShader(int shaderType, GLuint &shaderId, const unsigned char *shaderData, + unsigned int shaderDataLen, + Span shaderEnv); + + int createDMABufTexture2D(std::unique_ptr &eglImage, int fd, bool output); + + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; +}; +} //namespace libcamera diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp new file mode 100644 index 000000000..c6fde5e42 --- /dev/null +++ b/src/libcamera/egl.cpp @@ -0,0 +1,612 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + */ + +#include "libcamera/internal/egl.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +namespace libcamera { + +LOG_DEFINE_CATEGORY(eGL) + +/** + * \class eGL + * \brief Helper class for managing OpenGL ES operations + * + * It provides: + * + * - EGL context setup and management + * - Extension function pointer retrieval + * - Shader compilation and program linking + * - DMA-BUF texture creation and management + * - Synchronisation primitives + * + * This class is designed to work with zero-copy buffers via DMA-BUF file + * descriptors. + */ + +/** + *\var eGL::tid_ + *\brief Thread ID of the thread associated with this EGL context + */ + +/** + *\var eGL::display_ + *\brief EGL display handle + */ + +/** + *\var eGL::context_ + *\brief EGL context handle + */ + +/** + *\var eGL::surface_ + *\brief EGL sufrace handle + */ + +/** + * \brief Construct an EGL helper + * + * Creates an eGL instance with uninitialised context. Call initEGLContext() + * to set up the EGL display, context, and load extension functions. + */ +eGL::eGL() +{ + context_ = EGL_NO_CONTEXT; + surface_ = EGL_NO_SURFACE; + display_ = EGL_NO_DISPLAY; +} + +/** + * \brief Destroy the EGL helper + * + * Destroys the EGL context and surface if they were successfully created. + */ +eGL::~eGL() +{ + if (context_ != EGL_NO_CONTEXT) + eglDestroyContext(display_, context_); + + if (surface_ != EGL_NO_SURFACE) + eglDestroySurface(display_, surface_); +} + +/** + * \brief Synchronise rendering output + * + * Sychronise here. Calls glFinish() right now. + * + */ +void eGL::syncOutput() +{ + ASSERT(tid_ == Thread::currentId()); + + glFinish(); +} + +/** + * \brief Create a DMA-BUF backed 2D texture + * \param[in,out] eglImage EGL image to associate with the DMA-BUF + * \param[in] fd DMA-BUF file descriptor + * \param[in] output If true, create framebuffer for render target + * + * Internal implementation for creating DMA-BUF textures. Creates an EGL + * image from the DMA-BUF and binds it to a 2D texture. If output is true, + * also creates and attaches a framebuffer object. + * + * \return 0 on success, or -ENODEV on failure + */ +int eGL::createDMABufTexture2D(std::unique_ptr &eglImage, int fd, bool output) +{ + int ret = 0; + + ASSERT(tid_ == Thread::currentId()); + + // clang-format off + EGLint image_attrs[] = { + EGL_WIDTH, (EGLint)eglImage->width_, + EGL_HEIGHT, (EGLint)eglImage->height_, + EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, + EGL_DMA_BUF_PLANE0_FD_EXT, fd, + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, + EGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)eglImage->stride_, + EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, 0, + EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, 0, + EGL_NONE, + }; + // clang-format on + + eglImage->image_ = eglCreateImageKHR(display_, EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + NULL, image_attrs); + + if (eglImage->image_ == EGL_NO_IMAGE_KHR) { + LOG(eGL, Error) << "eglCreateImageKHR fail"; + ret = -ENODEV; + goto done; + } + + // Bind texture unit and texture + glActiveTexture(eglImage->texture_unit_); + glBindTexture(GL_TEXTURE_2D, eglImage->texture_); + + // Generate texture with filter semantics + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage->image_); + + // Nearest filtering + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + // Wrap to edge to avoid edge artifacts + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (output) { + // Generate a framebuffer from our texture direct to dma-buf handle buffer + glBindFramebuffer(GL_FRAMEBUFFER, eglImage->fbo_); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, eglImage->texture_, 0); + + GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (err != GL_FRAMEBUFFER_COMPLETE) { + LOG(eGL, Error) << "glFrameBufferTexture2D error " << err; + eglDestroyImageKHR(display_, eglImage->image_); + ret = -ENODEV; + goto done; + } + } +done: + return ret; +} + +/** + * \brief Create an input DMA-BUF backed texture + * \param[in,out] eglImage EGL image to associate with the DMA-BUF + * \param[in] fd DMA-BUF file descriptor + * + * Creates an EGL image from a DMA-BUF file descriptor and binds it to + * a 2D texture for use as an input texture in shaders. The texture is + * configured with nearest filtering and clamp-to-edge wrapping. + * + * \return 0 on success, or -ENODEV on failure + */ +int eGL::createInputDMABufTexture2D(std::unique_ptr &eglImage, int fd) +{ + ASSERT(tid_ == Thread::currentId()); + + return createDMABufTexture2D(eglImage, fd, false); +} + +/** + * \brief Create an output DMA-BUF backed texture + * \param[in,out] eglImage EGL image to associate with the DMA-BUF + * \param[in] fd DMA-BUF file descriptor + * + * Creates an EGL image from a DMA-BUF file descriptor and binds it to + * a 2D texture, then attaches it to a framebuffer object for use as a + * render target. This enables zero-copy rendering directly to the + * DMA-BUF. + * + * \return 0 on success, or -ENODEV on failure + */ +int eGL::createOutputDMABufTexture2D(std::unique_ptr &eglImage, int fd) +{ + ASSERT(tid_ == Thread::currentId()); + + return createDMABufTexture2D(eglImage, fd, true); +} + +/** + * \brief Destroy a DMA-BUF texture's EGL image + * \param[in,out] eglImage EGL image to destroy + * + * Destroys the EGL image associated with a DMA-BUF texture. The OpenGL + * texture and framebuffer objects are destroyed separately in the + * eGLImage destructor. + */ +void eGL::destroyDMABufTexture(std::unique_ptr &eglImage) +{ + eglDestroyImage(display_, eglImage->image_); +} + +/** + * \brief Create a 2D texture from a memory buffer + * \param[in,out] eglImage EGL image to associate with the texture + * \param[in] format OpenGL internal format (e.g., GL_RGB, GL_RGBA) + * \param[in] width Texture width in pixels + * \param[in] height Texture height in pixels + * \param[in] data Pointer to pixel data, or nullptr for uninitialised texture + * + * Creates a 2D texture from a CPU-accessible memory buffer. The texture + * is configured with nearest filtering and clamp-to-edge wrapping. This + * is useful for uploading static data like lookup tables or uniform color + * matrices to the GPU. + */ +void eGL::createTexture2D(std::unique_ptr &eglImage, GLint format, uint32_t width, uint32_t height, void *data) +{ + ASSERT(tid_ == Thread::currentId()); + + glActiveTexture(eglImage->texture_unit_); + glBindTexture(GL_TEXTURE_2D, eglImage->texture_); + + // Generate texture, bind, associate image to texture, configure, unbind + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + + // Nearest filtering + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + // Wrap to edge to avoid edge artifacts + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +/** + * \brief Initialise the EGL context + * \param[in] gbmContext Pointer to initialised GBM context + * + * Sets up the EGL display from the GBM device, creates an OpenGL ES 2.0 + * context, and retrieves function pointers for required extensions + * including: + * - eglCreateImageKHR / eglDestroyImageKHR + * - glEGLImageTargetTexture2DOES + * + * \return 0 on success, or -ENODEV on failure + */ +int eGL::initEGLContext(GBM *gbmContext) +{ + EGLint configAttribs[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + + EGLint contextAttribs[] = { + EGL_CONTEXT_MAJOR_VERSION, 2, + EGL_NONE + }; + + EGLint numConfigs; + EGLConfig config; + EGLint major; + EGLint minor; + + if (!eglBindAPI(EGL_OPENGL_ES_API)) { + LOG(eGL, Error) << "API bind fail"; + goto fail; + } + + display_ = eglGetDisplay(gbmContext->getDevice()); + if (display_ == EGL_NO_DISPLAY) { + LOG(eGL, Error) << "Unable to get EGL display"; + goto fail; + } + + if (eglInitialize(display_, &major, &minor) != EGL_TRUE) { + LOG(eGL, Error) << "eglInitialize fail"; + goto fail; + } + + LOG(eGL, Info) << "EGL: version " << major << "." << minor; + LOG(eGL, Info) << "EGL: EGL_VERSION: " << eglQueryString(display_, EGL_VERSION); + LOG(eGL, Info) << "EGL: EGL_VENDOR: " << eglQueryString(display_, EGL_VENDOR); + LOG(eGL, Info) << "EGL: EGL_CLIENT_APIS: " << eglQueryString(display_, EGL_CLIENT_APIS); + LOG(eGL, Info) << "EGL: EGL_EXTENSIONS: " << eglQueryString(display_, EGL_EXTENSIONS); + + eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR"); + if (!eglCreateImageKHR) { + LOG(eGL, Error) << "eglCreateImageKHR not found"; + goto fail; + } + + eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR"); + if (!eglDestroyImageKHR) { + LOG(eGL, Error) << "eglDestroyImageKHR not found"; + goto fail; + } + + glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); + if (!glEGLImageTargetTexture2DOES) { + LOG(eGL, Error) << "glEGLImageTargetTexture2DOES not found"; + goto fail; + } + + if (eglChooseConfig(display_, configAttribs, &config, 1, &numConfigs) != EGL_TRUE) { + LOG(eGL, Error) << "eglChooseConfig fail"; + goto fail; + } + + context_ = eglCreateContext(display_, config, EGL_NO_CONTEXT, contextAttribs); + if (context_ == EGL_NO_CONTEXT) { + LOG(eGL, Error) << "eglContext returned EGL_NO_CONTEXT"; + goto fail; + } + + tid_ = Thread::currentId(); + + makeCurrent(); + + return 0; +fail: + + return -ENODEV; +} + +/** + * \brief Clean up EGL resources + * + * Destroys the EGL sync object. Must be called from the same thread + * that created the EGL context. + */ +void eGL::cleanUp() +{ +} + +/** + * \brief Make the EGL context current for the calling thread + * + * Binds the EGL context to the current thread, allowing OpenGL ES + * operations to be performed. Must be called from the thread that + * will perform rendering operations. + */ +void eGL::makeCurrent() +{ + ASSERT(tid_ == Thread::currentId()); + + if (eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, context_) != EGL_TRUE) { + LOG(eGL, Error) << "eglMakeCurrent fail"; + } +} + +/** + * \brief Activate a shader program for rendering + * \param[in] programId OpenGL program object ID + * + * Sets the specified program as the current rendering program. All + * subsequent draw calls will use this program's shaders. + */ +void eGL::useProgram(GLuint programId) +{ + ASSERT(tid_ == Thread::currentId()); + + glUseProgram(programId); +} + +/** + * \brief Delete a shader program + * \param[in] programId OpenGL program object ID + * + * Deletes a shader program and frees associated resources. The program + * must not be currently in use. + */ +void eGL::deleteProgram(GLuint programId) +{ + ASSERT(tid_ == Thread::currentId()); + + glDeleteProgram(programId); +} + +/** + * \brief Add a preprocessor definition to shader environment + * \param[in,out] shaderEnv Vector of shader environment strings + * \param[in] str Preprocessor definition string (e.g., "#define APPLY_RGB_PARAMETERS") + * + * Appends a preprocessor definition to the shader environment vector. + * These definitions are prepended to shader source code during compilation. + */ +void eGL::pushEnv(std::vector &shaderEnv, const char *str) +{ + std::string addStr = str; + + addStr.push_back('\n'); + shaderEnv.push_back(std::move(addStr)); +} + +/** + * \brief Compile a vertex shader + * \param[out] shaderId OpenGL shader object ID + * \param[in] shaderData Pointer to shader source code + * \param[in] shaderDataLen Length of shader source in bytes + * \param[in] shaderEnv Span of preprocessor definitions to prepend + * + * Compiles a vertex shader from source code with optional preprocessor + * definitions. On compilation failure, logs the shader info log. + * + * \return 0 on success, or -EINVAL on compilation failure + */ +int eGL::compileVertexShader(GLuint &shaderId, const unsigned char *shaderData, + unsigned int shaderDataLen, + Span shaderEnv) +{ + return compileShader(GL_VERTEX_SHADER, shaderId, shaderData, shaderDataLen, shaderEnv); +} + +/** + * \brief Compile a fragment shader + * \param[out] shaderId OpenGL shader object ID + * \param[in] shaderData Pointer to shader source code + * \param[in] shaderDataLen Length of shader source in bytes + * \param[in] shaderEnv Span of preprocessor definitions to prepend + * + * Compiles a fragment shader from source code with optional preprocessor + * definitions. On compilation failure, logs the shader info log. + * + * \return 0 on success, or -EINVAL on compilation failure + */ +int eGL::compileFragmentShader(GLuint &shaderId, const unsigned char *shaderData, + unsigned int shaderDataLen, + Span shaderEnv) +{ + return compileShader(GL_FRAGMENT_SHADER, shaderId, shaderData, shaderDataLen, shaderEnv); +} + +/** + * \brief Compile a shader of specified type + * \param[in] shaderType GL_VERTEX_SHADER or GL_FRAGMENT_SHADER + * \param[out] shaderId OpenGL shader object ID + * \param[in] shaderData Pointer to shader source code + * \param[in] shaderDataLen Length of shader source in bytes + * \param[in] shaderEnv Span of preprocessor definitions to prepend + * + * Internal helper function for shader compilation. Prepends environment + * definitions to the shader source and compiles the shader. + * + * \return 0 on success, or -EINVAL on compilation failure + */ +int eGL::compileShader(int shaderType, GLuint &shaderId, const unsigned char *shaderData, + unsigned int shaderDataLen, + Span shaderEnv) +{ + GLint success; + size_t i; + + ASSERT(tid_ == Thread::currentId()); + + auto count = 1 + shaderEnv.size(); + auto shaderSourceData = std::make_unique(count); + auto shaderDataLengths = std::make_unique(count); + + // Prefix defines before main body of shader + for (i = 0; i < shaderEnv.size(); i++) { + shaderSourceData[i] = shaderEnv[i].c_str(); + shaderDataLengths[i] = shaderEnv[i].length(); + } + + // Now the main body of the shader program + shaderSourceData[i] = reinterpret_cast(shaderData); + shaderDataLengths[i] = shaderDataLen; + + // And create the shader + shaderId = glCreateShader(shaderType); + glShaderSource(shaderId, count, shaderSourceData.get(), shaderDataLengths.get()); + glCompileShader(shaderId); + + // Check status + glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) { + GLint sizeLog = 0; + + glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &sizeLog); + auto infoLog = std::make_unique(sizeLog); + + glGetShaderInfoLog(shaderId, sizeLog, &sizeLog, infoLog.get()); + LOG(eGL, Error) << infoLog.get(); + } + + return (success == GL_TRUE) ? 0 : -EINVAL; +} + +/** + * \brief Dump shader source code to the log + * \param[in] shaderId OpenGL shader object ID + * + * Retrieves and logs the complete source code of a compiled shader. + * Useful for debugging shader compilation issues. + */ +void eGL::dumpShaderSource(GLuint shaderId) +{ + GLint shaderLength = 0; + + ASSERT(tid_ == Thread::currentId()); + + glGetShaderiv(shaderId, GL_SHADER_SOURCE_LENGTH, &shaderLength); + + LOG(eGL, Debug) << "Shader length is " << shaderLength; + + if (shaderLength > 0) { + auto shaderSource = std::make_unique(shaderLength); + + glGetShaderSource(shaderId, shaderLength, &shaderLength, shaderSource.get()); + if (shaderLength) { + LOG(eGL, Debug) << "Shader source = " << shaderSource.get(); + } + } +} + +/** + * \brief Link a shader program + * \param[out] programId OpenGL program object ID + * \param[in] fragmentshaderId Compiled fragment shader ID + * \param[in] vertexshaderId Compiled vertex shader ID + * + * Links vertex and fragment shaders into an executable shader program. + * On link failure, logs the program info log and deletes the program. + * + * \return 0 on success, or -ENODEV on link failure + */ +int eGL::linkProgram(GLuint &programId, GLuint vertexshaderId, GLuint fragmentshaderId) +{ + GLint success; + GLenum err; + + ASSERT(tid_ == Thread::currentId()); + + programId = glCreateProgram(); + if (!programId) + goto fail; + + glAttachShader(programId, vertexshaderId); + if ((err = glGetError()) != GL_NO_ERROR) { + LOG(eGL, Error) << "Attach compute vertex shader fail"; + goto fail; + } + + glAttachShader(programId, fragmentshaderId); + if ((err = glGetError()) != GL_NO_ERROR) { + LOG(eGL, Error) << "Attach compute fragment shader fail"; + goto fail; + } + + glLinkProgram(programId); + if ((err = glGetError()) != GL_NO_ERROR) { + LOG(eGL, Error) << "Link program fail"; + goto fail; + } + + glDetachShader(programId, fragmentshaderId); + glDetachShader(programId, vertexshaderId); + + // Check status + glGetProgramiv(programId, GL_LINK_STATUS, &success); + if (success == GL_FALSE) { + GLint sizeLog = 0; + GLchar *infoLog; + + glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &sizeLog); + infoLog = new GLchar[sizeLog]; + + glGetProgramInfoLog(programId, sizeLog, &sizeLog, infoLog); + LOG(eGL, Error) << infoLog; + + delete[] infoLog; + goto fail; + } + + return 0; +fail: + if (programId) + glDeleteProgram(programId); + + return -ENODEV; +} +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index e5b5330a8..60f036da4 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -79,6 +79,27 @@ if libgbm.found() and gbm_works ]) endif +libegl = cc.find_library('EGL', required : false) +libglesv2 = cc.find_library('GLESv2', required : false) +mesa_works = cc.check_header('EGL/egl.h', required: false) + +if libegl.found() and mesa_works + config_h.set('HAVE_LIBEGL', 1) +endif + +if libglesv2.found() and mesa_works + config_h.set('HAVE_GLESV2', 1) +endif + +if mesa_works and gbm_works + libcamera_internal_sources += files([ + 'egl.cpp', + ]) + gles_headless_enabled = true +else + gles_headless_enabled = false +endif + subdir('base') subdir('converter') subdir('ipa') @@ -187,7 +208,9 @@ libcamera_deps += [ libcamera_base_private, libcrypto, libdl, + libegl, libgbm, + libglesv2, liblttng, libudev, libyaml, From patchwork Wed Dec 17 10:01:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25576 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 4D74CC326C for ; Wed, 17 Dec 2025 10:01:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 779BF61A5D; Wed, 17 Dec 2025 11:01:50 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="H45ZxNTw"; dkim-atps=neutral Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 14E6861A4E for ; Wed, 17 Dec 2025 11:01:46 +0100 (CET) Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-47118259fd8so55703995e9.3 for ; Wed, 17 Dec 2025 02:01:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965705; x=1766570505; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fs424H+/NHXIDhotX6BbcvYwsUeY8sQ6tmxWMohUjl4=; b=H45ZxNTwADrQOY9CRzNgFmWrzQc2sFHyBxvsaxWE9C5ycWMiOZ48v4NiM1YJpl041o 3sb0YWvLyyhY/48n/jDfRu9HOZFeM5Kl85RFPMsVbHxWcV8rSe1Ni91q5rKGIx2PZ3+T b1fux7Rt49o99u0bU6Ww6rg2moqqRHSZ7+IO8ZQn8TbZGMhO1tOddcQbzq+mVam4WQIQ YnqFx6sWsJdZwCsUfL/VjJ7hpQ0aMS0L0kpp3Lz0gY5s3lPkyTwLYFtCK4ylGnJS2CqQ DJ7M5IDoEPtz1eVn2C/UMSPy5qUHnLD488QPKxBm0DDF2323QN7g8EAUwGW+M/Rs9YPK y8zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965705; x=1766570505; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=fs424H+/NHXIDhotX6BbcvYwsUeY8sQ6tmxWMohUjl4=; b=Ib5WTiYDa7iLruPSAMoeKvZVZXVEUtW8Bn3pgBBlGQ8h8Ivy0+FvdT+vKAoQlbfJbz 5S0Q8fkgsJ19KvXidAGAw6ueS3yGal1eI6+BXO0GT/UQ2pQ4CfUdcCvgbwJZRoZRJfr9 HgXTnHaflxEa5ncpad0cmeJZHpEFFzFKy+cV5CyCawoGOxeI2Qh7bE7Pr7dxn4UkUvUo xu695Avo5tZWFUQMRwtZm497NCtrxDWetyB3TOZuGPwS6e6EJZ1B3RRxVKbQOm8mQoa0 EwQaHRHuu19umZ33AAcRzIxaRFC+DPiIq8yl2hNvEix38zgkDFvRTu8m+PLsxoXFAgkh WZqQ== X-Gm-Message-State: AOJu0YzNTizj1E7no0T65DuqmkghGVToXbDjZggFQoDifOgyNKY42psB 1EWWukw7G1CMov+cJQFb0jExZYZv7xVytZBirAGz1Hooer9ZPNbtIKxdwoJvXqnz6gpN7+/1l1T saHrm X-Gm-Gg: AY/fxX7SlqyGoaq4BCC1yYzH4qZkU2PphbTA8YAPqBcEepBPn6P4WdF+COvGAKP4VqZ SsLEBktRxrmWrZH2gJ1MgD5uokc6wWKRY8jsmSTFOHlvpbYeACW60gVYw3GuK2/mizLny+HFB7X qPRMCEs7JH6RnRXdt/y58PEALhm/e06W+/h1oWnGtOReVEf5SAWa3QvlmwkEL0qElklKAsZk2RE Sjna82I7QA7N5ikMjXSQDmGHacC7apKu3Dcom13EtQeH/oF9eTw9gUXezxc+wXSlVDX091r7RE2 Si16VWnJH83hvSCab9Spcrkwa25KBsdqjIILlo9rXiMXr7XrHPpzgux2NE9E0boIL1a8epXweCQ wcY8JoZQZvPCcsDpjow3yWWin3LIuq0NjWNHsUKBzrWy14u9RlScoOxLAKKG+tlLKW0PN/vhsTX Tpz6V/cwL+S4UrZXBVbPX56giPeSucxAmBscql5LO180CphCeqlABq5tYJJkz+tuUMPRpZ1g5bg WS75Q== X-Google-Smtp-Source: AGHT+IGiegwlJ9BiUeMiyHvDqNL0Wb8/5hwgYfciYdFiBiCZzsS0V/8yzpVWpiGeOUqV8jrh9lQ2Og== X-Received: by 2002:a05:600c:5487:b0:47b:deb9:f8a with SMTP id 5b1f17b1804b1-47bdeb91a35mr8922175e9.30.1765965705124; Wed, 17 Dec 2025 02:01:45 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:44 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 03/26] qcam: viewfinder_gl: Set no-op Bayer shader values Date: Wed, 17 Dec 2025 10:01:15 +0000 Message-ID: <20251217100138.82525-4-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Populate qcam viewfinder_gl to set default Bayer values so that the shaders can be used in their original mode without conditional compilation. Set an identity CCM, identity Black Level and set Gamma and Contrast to 1.0f respectively. Once this change is made we can use the Bayer shaders in their original format in qcam with raw streams. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/apps/qcam/viewfinder_gl.cpp | 26 ++++++++++++++++++++++++++ src/apps/qcam/viewfinder_gl.h | 12 ++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/apps/qcam/viewfinder_gl.cpp b/src/apps/qcam/viewfinder_gl.cpp index 1554c94d5..4698c5aac 100644 --- a/src/apps/qcam/viewfinder_gl.cpp +++ b/src/apps/qcam/viewfinder_gl.cpp @@ -473,6 +473,10 @@ bool ViewFinderGL::createFragmentShader() textureUniformSize_ = shaderProgram_.uniformLocation("tex_size"); textureUniformStrideFactor_ = shaderProgram_.uniformLocation("stride_factor"); textureUniformBayerFirstRed_ = shaderProgram_.uniformLocation("tex_bayer_first_red"); + ccmUniformDataIn_ = shaderProgram_.uniformLocation("ccm"); + blackLevelUniformDataIn_ = shaderProgram_.uniformLocation("blacklevel"); + gammaUniformDataIn_ = shaderProgram_.uniformLocation("gamma"); + contrastUniformDataIn_ = shaderProgram_.uniformLocation("contrast"); /* Create the textures. */ for (std::unique_ptr &texture : textures_) { @@ -542,6 +546,16 @@ void ViewFinderGL::doRender() /* Stride of the first plane, in pixels. */ unsigned int stridePixels; + /* Identity CCM */ + float ccm[] = { 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f }; + + QMatrix3x3 qCcmMat(ccm); + + /* Black Level */ + QVector3D qBlackLevelVec(0.0f, 0.0f, 0.0f); + switch (format_) { case libcamera::formats::NV12: case libcamera::formats::NV21: @@ -788,6 +802,18 @@ void ViewFinderGL::doRender() * the generic stride factor to 1.0. */ stridePixels = size_.width(); + + /* Colour Correction Matrix */ + shaderProgram_.setUniformValue(ccmUniformDataIn_, qCcmMat); + + /* Black Level */ + shaderProgram_.setUniformValue(blackLevelUniformDataIn_, qBlackLevelVec); + + /* Gamma */ + shaderProgram_.setUniformValue(gammaUniformDataIn_, 1.0f); + + /* Contrast */ + shaderProgram_.setUniformValue(contrastUniformDataIn_, 1.0f); break; default: diff --git a/src/apps/qcam/viewfinder_gl.h b/src/apps/qcam/viewfinder_gl.h index 23c657bcf..59f122217 100644 --- a/src/apps/qcam/viewfinder_gl.h +++ b/src/apps/qcam/viewfinder_gl.h @@ -103,5 +103,17 @@ private: GLuint textureUniformBayerFirstRed_; QPointF firstRed_; + /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ + GLint ccmUniformDataIn_; + + /* Black Level compensation */ + GLint blackLevelUniformDataIn_; + + /* Gamma */ + GLint gammaUniformDataIn_; + + /* Contrast */ + GLint contrastUniformDataIn_; + QMutex mutex_; /* Prevent concurrent access to image_ */ }; From patchwork Wed Dec 17 10:01:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25577 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 72450C3272 for ; Wed, 17 Dec 2025 10:01:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7B0E461A5B; Wed, 17 Dec 2025 11:01:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RwWOmEhZ"; dkim-atps=neutral Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 56EC761A35 for ; Wed, 17 Dec 2025 11:01:47 +0100 (CET) Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-477aa218f20so37293435e9.0 for ; Wed, 17 Dec 2025 02:01:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965707; x=1766570507; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IkJAuqeYrqHSkFYcCTDfg5+OJJh/GJhI6Eleh7WU2G8=; b=RwWOmEhZ6UB4QM3KhH9vQdpSOo3oyGd4/y3gSg8NL6sAQjxpFxbW7vNhNw0dwlv5to cUGa5KZlnIY6P1z/Bx8XtSQZVOK2kuWkJ8xMX6LSdKLcQqMVarihYadHm3fuFXXkI0G4 6Wc5grcmcpiOx3BQa2Hme30/tNppCbJDzhnHIl+W2KsUNd67bRUwHHDCqY4yBfTvIIkl SIOXeJo1XYx9raqt6Av2ZGdRusxubwJHxVhZgrwCOcP2KrbMvcfdCanjdr4uYVAKcCs5 o3bALQutFPhrcYJx7po2m1dTQ+jyJKVFkpFsjrFeLZXl3biRCAXM4aWl82t8DQprSiqg 6jMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965707; x=1766570507; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=IkJAuqeYrqHSkFYcCTDfg5+OJJh/GJhI6Eleh7WU2G8=; b=XFOJjRPxMet2FD5ukSjm9pn4uWOkXlp13nsd9avizTLszYJ9enbdLe3NXCxt0N1wVm Xaw0aay/MFHp34zSK6mwVC8noqCwuOc51SNrYlt44+cxbRRk3PO/wPa6lNe8xL5USiek +zdpTyu1PJcB++k6BXT+CWSCjAMda21EF7NIOY2fpru5LL4jEvCNP9aDkNgUrvc77fff 3kX29SbuNaYB5Eo2cVx7QzzYWwA03kvp1HiVs+cgbkkKxN8daaNZoqkSaa59vaLQj0fz x1ZSrw0TmUvK2Q1IlZcS6YS8nOHwyF498wPdIb1uDQvv4u+OF3k+JnOPLToKFmJG0S3v 10ZQ== X-Gm-Message-State: AOJu0Yz2DHWJcRiw7UQmRje53skhzt4do2x+znqn48iXouVEJ7niQJtd FS39vo0eulyNVs+dn/M6x5GjKhyyNWg9WaY8e8XdksacRsmXyt9ZgBWfeODxdAiro+lM7aF3WpZ Kg09v X-Gm-Gg: AY/fxX6odvXs6HrEkZ5ZfpDl0Z47Zea3zxVLY1m92qDdhKwV2YC1rh0S9c5RgY4aYHB yE6AhGc9phD95x/G5mykGbpfDDnGpF0L4FcppNlrG7+HHb0vBP8TxmHx6oAzJuzWAa/aK3uxnb1 xwPvsXuQ1oDJ5pFKbWBrpb7XRxnlUa3F7J2d9WtyWevmyK02IUOfyRVoC4+XCSKqy82zagc1P4/ 6D+wXK9iu8SPwh2faZvFRXdeW98ZvOJ6z3RryC6WrWBF87pzRIbFY2x87tmvqkgB5zDUuir9Ra7 Ek9U85c/x576g2rt7g84EJ1j6vK0+60QSxdjDUge2KKyanG21exlDaibMgV9VuQBmrrBUkcaT9i YTrAl/oNanFsgy3VH0jvWEvcfoOeqYbUiybYr7uviGD+bQFid8K1r5BCrffaXO7rG2pauEAQ9eu qjpf1/gzASYtlERAeDqmfspoPCw/g0ZAQy8QbpuHQn9uDS32+KRAh0DwLLQ9NI+QTz1FJ4/574O LLlMQ== X-Google-Smtp-Source: AGHT+IHdlmgm8g6MDlSgIC5JoC0PP8rGUZFJaH5lIRe5XSBfD3E7shwSAro3PxYnBZG1hVFQrabfNA== X-Received: by 2002:a05:600c:1c2a:b0:477:6d96:b3c8 with SMTP id 5b1f17b1804b1-47a8f905313mr190061065e9.23.1765965706612; Wed, 17 Dec 2025 02:01:46 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:46 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Milan Zamazal , Kieran Bingham , Bryan O'Donoghue Subject: [PATCH v9 04/26] libcamera: shaders: Rename bayer_8 to bayer_unpacked Date: Wed, 17 Dec 2025 10:01:16 +0000 Message-ID: <20251217100138.82525-5-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" From: Milan Zamazal bayer_8.* shaders are now used for all unpacked sensor data formats, regardless of the pixel bit width. Let's rename the "8-bit" shaders to avoid confusion. Signed-off-by: Milan Zamazal Reviewed-by: Kieran Bingham Signed-off-by: Bryan O'Donoghue --- src/apps/qcam/assets/shader/shaders.qrc | 4 ++-- src/apps/qcam/viewfinder_gl.cpp | 16 ++++++++-------- .../{bayer_8.frag => bayer_unpacked.frag} | 0 .../{bayer_8.vert => bayer_unpacked.vert} | 0 src/libcamera/shaders/meson.build | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) rename src/libcamera/shaders/{bayer_8.frag => bayer_unpacked.frag} (100%) rename src/libcamera/shaders/{bayer_8.vert => bayer_unpacked.vert} (100%) diff --git a/src/apps/qcam/assets/shader/shaders.qrc b/src/apps/qcam/assets/shader/shaders.qrc index 7369cdbe8..f11a68ef2 100644 --- a/src/apps/qcam/assets/shader/shaders.qrc +++ b/src/apps/qcam/assets/shader/shaders.qrc @@ -6,8 +6,8 @@ ../../../../../src/libcamera/shaders/YUV_3_planes.frag ../../../../../src/libcamera/shaders/YUV_packed.frag ../../../../../src/libcamera/shaders/bayer_1x_packed.frag - ../../../../../src/libcamera/shaders/bayer_8.frag - ../../../../../src/libcamera/shaders/bayer_8.vert + ../../../../../src/libcamera/shaders/bayer_unpacked.frag + ../../../../../src/libcamera/shaders/bayer_unpacked.vert ../../../../../src/libcamera/shaders/identity.vert diff --git a/src/apps/qcam/viewfinder_gl.cpp b/src/apps/qcam/viewfinder_gl.cpp index 4698c5aac..47f41350e 100644 --- a/src/apps/qcam/viewfinder_gl.cpp +++ b/src/apps/qcam/viewfinder_gl.cpp @@ -235,29 +235,29 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format) case libcamera::formats::SBGGR8: firstRed_.setX(1.0); firstRed_.setY(1.0); - vertexShaderFile_ = ":src/libcamera/shaders/bayer_8.vert"; - fragmentShaderFile_ = ":src/libcamera/shaders/bayer_8.frag"; + vertexShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.vert"; + fragmentShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.frag"; textureMinMagFilters_ = GL_NEAREST; break; case libcamera::formats::SGBRG8: firstRed_.setX(0.0); firstRed_.setY(1.0); - vertexShaderFile_ = ":src/libcamera/shaders/bayer_8.vert"; - fragmentShaderFile_ = ":src/libcamera/shaders/bayer_8.frag"; + vertexShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.vert"; + fragmentShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.frag"; textureMinMagFilters_ = GL_NEAREST; break; case libcamera::formats::SGRBG8: firstRed_.setX(1.0); firstRed_.setY(0.0); - vertexShaderFile_ = ":src/libcamera/shaders/bayer_8.vert"; - fragmentShaderFile_ = ":src/libcamera/shaders/bayer_8.frag"; + vertexShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.vert"; + fragmentShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.frag"; textureMinMagFilters_ = GL_NEAREST; break; case libcamera::formats::SRGGB8: firstRed_.setX(0.0); firstRed_.setY(0.0); - vertexShaderFile_ = ":src/libcamera/shaders/bayer_8.vert"; - fragmentShaderFile_ = ":src/libcamera/shaders/bayer_8.frag"; + vertexShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.vert"; + fragmentShaderFile_ = ":src/libcamera/shaders/bayer_unpacked.frag"; textureMinMagFilters_ = GL_NEAREST; break; case libcamera::formats::SBGGR10_CSI2P: diff --git a/src/libcamera/shaders/bayer_8.frag b/src/libcamera/shaders/bayer_unpacked.frag similarity index 100% rename from src/libcamera/shaders/bayer_8.frag rename to src/libcamera/shaders/bayer_unpacked.frag diff --git a/src/libcamera/shaders/bayer_8.vert b/src/libcamera/shaders/bayer_unpacked.vert similarity index 100% rename from src/libcamera/shaders/bayer_8.vert rename to src/libcamera/shaders/bayer_unpacked.vert diff --git a/src/libcamera/shaders/meson.build b/src/libcamera/shaders/meson.build index 386b342d0..dd441a577 100644 --- a/src/libcamera/shaders/meson.build +++ b/src/libcamera/shaders/meson.build @@ -4,7 +4,7 @@ # for the purposes of inclusion in OpenGL debayering shader_files = files([ 'bayer_1x_packed.frag', - 'bayer_8.frag', - 'bayer_8.vert', + 'bayer_unpacked.frag', + 'bayer_unpacked.vert', 'identity.vert', ]) From patchwork Wed Dec 17 10:01:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25578 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 99365C3257 for ; Wed, 17 Dec 2025 10:01:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1A4B061A4E; Wed, 17 Dec 2025 11:01:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="VWDyT45H"; dkim-atps=neutral Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E457E61A3D for ; Wed, 17 Dec 2025 11:01:48 +0100 (CET) Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-477b5e0323bso2172825e9.0 for ; Wed, 17 Dec 2025 02:01:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965708; x=1766570508; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FdyTcK0Xun67yTvAExHcO9DNNAcWNw/aYg3LzuhT/Zc=; b=VWDyT45HrpY5ZzxUwXtHCRQvGY1Ro49pxecPz8+QU+V4iZefnIrS7UnXHALWm0eDA0 oQsvisdYS79DjaZ6RP7BZBXuQrVwQJgRI07hKE22CYToMRUpgjfjEfqvQnaXJDH7jyis OHFj2Wp4FC+kAVDPu2lfmSv4X1HU7OV4awzGfGGuH2ml1iEvEGYx7lm8y7pw9Lq9JreR p//EhyfeQ3INRgOsGexcVKWBtfWe0hDOqi7IIns898vQPhmu2VAaqLgoHwzdkxdZQ2t4 KNaWUJvUvIxC9kC1DOl9ACgYEl+KA96Z6zOEcIeESxpLkYm+c2JzOLgVnfSuruYJdj1P FvNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965708; x=1766570508; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=FdyTcK0Xun67yTvAExHcO9DNNAcWNw/aYg3LzuhT/Zc=; b=gKMm7yFVBpbcHt6Lio0OR+xlWF0hTErDuu1veUuPRS6XtuLsVSKgMAyl5AEOd3Fyz/ /M6JKswmLVALfN3eztiyIi6VonZiKX9sqJwtp0SWbO88Xy1AkyywzlYehQ+5ZBkpZkGm N49v9KAUeiips9roUV0awX8ZesI+cKR8BCqTHJr3gNOftKx67DkJ/W/UHv0pfT10qfn9 j62LloQmPEWGlPJcaiGT0Dx22fgsv2qNNhv+hZu0I8CeIXBG6zeSZOpLEh+u8i9LJN47 21nui5lsCM2DoZDrwNOvAc7LkOlRSPd78P/0RGgEi6h6vGuTetDeBBnXIcf8L/H/LaTN TcFw== X-Gm-Message-State: AOJu0YyVF4pBAZdaENXflkjpSjkcusH//FlrIAvx1N0gQ364/Dc0NwmA bcmYJ6SLpl8n0sF42HewJmke6EBpKLxUnVptajALLzaJbE9E1jtVUAUykOYHc3GIDdPbTh6LU6x 37epD X-Gm-Gg: AY/fxX6GkXnSCuFgkkmH5XVQUWgcMYWKWx66xBE0cAAyK1NSLH4wBf9c5VtQ4ZSCHiu I3ljgkwicHA7Eo8aLSuSP9J1lZkvFb+ssbJ3ed2lUCRWT0yAYxp4f3ZdHwxu8+C3p7QwvyyYHkm TWhFdWpm7UXqcl7RoCKl729K9bHk43MqlMfLvlnDzdHrwYWdsHxDqxdBGwZYs7+/8uFqrcXg7UZ vSVeN2+QPEdibS43LHwwrakgOmVvn/Y5+nxzLLT1kmxcD7mRuVCLRWZDle+HZ7V7EL1zgG/bIuH DbI9dZpUl/ls3uaDIJpuI8tSCoRVP2Wj8yF7/FG/Z50Wg8qaCAi1o4M9b72E04/BKIFV9dsf2N4 53wsz5W7ubcmzkudJLnY9+jm1LsVyZDLtkBvjzghZ/mGXZULPry1A/2c8PJv59+pwWmOhGzrDh5 u5KZ3g0cb3g4gTj0kg1FSyhAxLGdwUrE762y788zU3oB+0eoOc9QmKZjlVxWJSV6s1H9g= X-Google-Smtp-Source: AGHT+IEGMus0Lj9mZ/7/h+by8HdYLmyjW1yaD+loaJEGH6yIYYLtUsHG9SoBNSjrzsqU8QqksFao0A== X-Received: by 2002:a05:600c:2218:b0:471:793:e795 with SMTP id 5b1f17b1804b1-47a89d2c84bmr145323825e9.0.1765965708090; Wed, 17 Dec 2025 02:01:48 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:47 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Kieran Bingham , Milan Zamazal Subject: [PATCH v9 05/26] libcamera: shaders: Use highp not mediump for float precision Date: Wed, 17 Dec 2025 10:01:17 +0000 Message-ID: <20251217100138.82525-6-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" mediump gives 10 bits of mantissa as the resolution. At higher resolutions 10 bits of accuracy is insufficient - for example at a width of 1928 bytes we need log2(1928) = ~11 bit resolution. Switching to highp gives us 23 bits of mantissa giving a sample width precision of about 2^23 ~ 8,388,608. Acked-by: Kieran Bingham Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/shaders/RGB.frag | 2 +- src/libcamera/shaders/YUV_2_planes.frag | 2 +- src/libcamera/shaders/YUV_3_planes.frag | 2 +- src/libcamera/shaders/YUV_packed.frag | 2 +- src/libcamera/shaders/bayer_1x_packed.frag | 2 +- src/libcamera/shaders/bayer_unpacked.frag | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcamera/shaders/RGB.frag b/src/libcamera/shaders/RGB.frag index 4c374ac98..724395894 100644 --- a/src/libcamera/shaders/RGB.frag +++ b/src/libcamera/shaders/RGB.frag @@ -6,7 +6,7 @@ */ #ifdef GL_ES -precision mediump float; +precision highp float; #endif varying vec2 textureOut; diff --git a/src/libcamera/shaders/YUV_2_planes.frag b/src/libcamera/shaders/YUV_2_planes.frag index 1d5d12062..d286f1179 100644 --- a/src/libcamera/shaders/YUV_2_planes.frag +++ b/src/libcamera/shaders/YUV_2_planes.frag @@ -6,7 +6,7 @@ */ #ifdef GL_ES -precision mediump float; +precision highp float; #endif varying vec2 textureOut; diff --git a/src/libcamera/shaders/YUV_3_planes.frag b/src/libcamera/shaders/YUV_3_planes.frag index 8f788e90a..8e3e0b4a5 100644 --- a/src/libcamera/shaders/YUV_3_planes.frag +++ b/src/libcamera/shaders/YUV_3_planes.frag @@ -6,7 +6,7 @@ */ #ifdef GL_ES -precision mediump float; +precision highp float; #endif varying vec2 textureOut; diff --git a/src/libcamera/shaders/YUV_packed.frag b/src/libcamera/shaders/YUV_packed.frag index b9ef9d41b..3c9e3e397 100644 --- a/src/libcamera/shaders/YUV_packed.frag +++ b/src/libcamera/shaders/YUV_packed.frag @@ -6,7 +6,7 @@ */ #ifdef GL_ES -precision mediump float; +precision highp float; #endif varying vec2 textureOut; diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index f53f55758..19b13ad08 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -20,7 +20,7 @@ */ #ifdef GL_ES -precision mediump float; +precision highp float; #endif /* diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index 7e35ca88e..aa7a1b004 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -16,7 +16,7 @@ Copyright (C) 2021, Linaro //Pixel Shader #ifdef GL_ES -precision mediump float; +precision highp float; #endif /** Monochrome RGBA or GL_LUMINANCE Bayer encoded texture.*/ From patchwork Wed Dec 17 10:01:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25579 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 4EE38C326C for ; Wed, 17 Dec 2025 10:02:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DE18861ABD; Wed, 17 Dec 2025 11:02:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="VzOeDH5k"; dkim-atps=neutral Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 72EBA61A5C for ; Wed, 17 Dec 2025 11:01:50 +0100 (CET) Received: by mail-wm1-x344.google.com with SMTP id 5b1f17b1804b1-47775fb6cb4so39071675e9.0 for ; Wed, 17 Dec 2025 02:01:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965710; x=1766570510; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Zkzu0tqbzAOlMWvnkw6w2p9R2Nid+3zoTkR/m4lKMgE=; b=VzOeDH5kBINuxbv/4m1l48PCe9GYJ0bnuyQUB/YQhUoYmagPK/tHDI0+/EHvpiUAQv cQhQgyGABxKkHPRaZppwbCDtHKAQSfhSeMUcJdqm18brntUAcmjIv5agAFDJZa6aR76r MCgpoSk333ETTiA13RjIqDLVFUpN//9U0r2FGSyr7Zf553oW7TQYufrfFsv7CI/seUus vbpf5WDzJzosTkY/afbw93URA+sXdnA5n8rPoDd19BH9vEPODWNDM6eIX4gTpvlvF1y+ 9iq+fog9iOVy9cseolHuqIhu4QsMGpIfUq6/53ADxKA6SdspI3BN6XnPbr5M98XDsIkB WgJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965710; x=1766570510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Zkzu0tqbzAOlMWvnkw6w2p9R2Nid+3zoTkR/m4lKMgE=; b=Dc6SGo/hXFi6MMJMtEDNa37d1Nkfu2XK1t5QeKx0XpsW3EzD0MhQ3ICbV3yfM9eknW 91cYj0ezv8pybEL1HG3sWW9U7sgD7QIi+8mOvUdDCrXVxts9M+eBXrgJwqMoLvELgPm8 iEbf4ImPBdfcPEnYncKYMfnqc6l+CjCYByfFi3e5t2oa7oNqxsuZ9wTUM4w1inKAfGSR MM4pL49eH1A40ukREwtNfwRnCYv61uHlj4lCT444dE+TEsNe5QY9bLPSW2n5SJjPBXG7 LQTGKz2x4CTPLNqEK+rcoNMpU1h/l0lGTZKpO97MfbUlFWnP9RAvVKwyX0tsnSdJUCAO jwdg== X-Gm-Message-State: AOJu0YxUQ4jFpiLaeE0MemQzoSz276sdfecuQuHQShIBP1BuyqGCNhy+ OOHgbGIJ4cOBIRJ57b0ipHfdnp74HZFD5pqEIBNCeDQT3pMfQcSWd8dbIaplzkkxfa+1yeteBRu i0IjZC28= X-Gm-Gg: AY/fxX5d1YoiNJawUcdvVBzfuE8UqZS0fAm0llb241mLrmiin5rxW7/FRXgnZmAuEXA 0pQmSWg6m+Fho12x3B5vbz8Xu+YWV16V+B36lrvSXEG5DHgTG6BGHUxH5q0S1EuTgH2HA3fGDDW QO5K37EXXwHt1sRFBceN71nJXr6MoGbytQDl453rPd9NjxqFafm1LmgDeqeHglaFb/lWDnlepZ6 ZIGUkGzqj4ubSIs6xrgS9MmVNbroAykg8YNFihaQpjL7w/jsZpb0AH75gaq5MqPgfhOjH4WLhmC Qn2AFXS+1QGyz0j1mwMbjWwIb88h+Pf69xImrZ40FcEC4IMhQVYZsNF0YLCT1JSdxh5YGhmok44 tKeC6/QXC7N6CukFK2Ffm6Xc5ViPhoYb+gqRkEUxVUh0S6I60T5HbcmOgaWnKar/OH1t1UmD757 Au7rt9KW1EuensJMS+TFVVsZYdtMNy5TzBUCQ5TxmNL7Pza4FUp6q6MxY2Qg1D0tUGY6Ou+BUk0 Z9tBQ== X-Google-Smtp-Source: AGHT+IF03kRrjPlt40PtVFkP72T6S43oPtDLssb2CttrBH9TpI8EvOpY2X5eIDWFkqDfXQVWAF0Jpw== X-Received: by 2002:a05:600c:19c6:b0:45c:4470:271c with SMTP id 5b1f17b1804b1-47a8f90598emr172228595e9.18.1765965709648; Wed, 17 Dec 2025 02:01:49 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:49 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 06/26] libcamera: shaders: Extend debayer shaders to apply CCM gains Date: Wed, 17 Dec 2025 10:01:18 +0000 Message-ID: <20251217100138.82525-7-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Extend Bayer shaders to support application of a passed CCM table. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/shaders/bayer_1x_packed.frag | 45 +++++++++++++++++++ src/libcamera/shaders/bayer_unpacked.frag | 51 +++++++++++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index 19b13ad08..171a928c2 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -65,6 +65,7 @@ uniform vec2 tex_step; uniform vec2 tex_bayer_first_red; uniform sampler2D tex_y; +uniform mat3 ccm; void main(void) { @@ -212,5 +213,49 @@ void main(void) vec3(patterns.y, C, patterns.x) : vec3(patterns.wz, C)); + /* + * CCM is a 3x3 in the format + * + * +--------------+----------------+---------------+ + * | RedRedGain | RedGreenGain | RedBlueGain | + * +--------------+----------------+---------------+ + * | GreenRedGain | GreenGreenGain | GreenBlueGain | + * +--------------+----------------+---------------+ + * | BlueRedGain | BlueGreenGain | BlueBlueGain | + * +--------------+----------------+---------------+ + * + * Rout = RedRedGain * Rin + RedGreenGain * Gin + RedBlueGain * Bin + * Gout = GreenRedGain * Rin + GreenGreenGain * Gin + GreenBlueGain * Bin + * Bout = BlueRedGain * Rin + BlueGreenGain * Gin + BlueBlueGain * Bin + * + * We upload to the GPU without transposition glUniformMatrix3f(.., .., GL_FALSE, ccm); + * + * CPU + * float ccm [] = { + * RedRedGain, RedGreenGain, RedBlueGain, + * GreenRedGain, GreenGreenGain, GreenBlueGain, + * BlueRedGain, BlueGreenGain, BlueBlueGain, + * }; + * + * GPU + * ccm = { + * RedRedGain, GreenRedGain, BlueRedGain, + * RedGreenGain, GreenGreenGain, BlueGreenGain, + * RedBlueGain, GreenBlueGain, BlueBlueGain, + * } + * + * However the indexing for the mat data-type is column major hence + * ccm[0][0] = RedRedGain, ccm[0][1] = RedGreenGain, ccm[0][2] = RedBlueGain + * + */ + float rin, gin, bin; + rin = rgb.r; + gin = rgb.g; + bin = rgb.b; + + rgb.r = (rin * ccm[0][0]) + (gin * ccm[0][1]) + (bin * ccm[0][2]); + rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); + rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); + gl_FragColor = vec4(rgb, 1.0); } diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index aa7a1b004..c41d72f4f 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -24,8 +24,11 @@ uniform sampler2D tex_y; varying vec4 center; varying vec4 yCoord; varying vec4 xCoord; +uniform mat3 ccm; void main(void) { + vec3 rgb; + #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r float C = texture2D(tex_y, center.xy).r; // ( 0, 0) @@ -97,11 +100,57 @@ void main(void) { PATTERN.xw += kB.xw * B; PATTERN.xz += kF.xz * F; - gl_FragColor.rgb = (alternate.y == 0.0) ? + rgb = (alternate.y == 0.0) ? ((alternate.x == 0.0) ? vec3(C, PATTERN.xy) : vec3(PATTERN.z, C, PATTERN.w)) : ((alternate.x == 0.0) ? vec3(PATTERN.w, C, PATTERN.z) : vec3(PATTERN.yx, C)); + + /* + * CCM is a 3x3 in the format + * + * +--------------+----------------+---------------+ + * | RedRedGain | RedGreenGain | RedBlueGain | + * +--------------+----------------+---------------+ + * | GreenRedGain | GreenGreenGain | GreenBlueGain | + * +--------------+----------------+---------------+ + * | BlueRedGain | BlueGreenGain | BlueBlueGain | + * +--------------+----------------+---------------+ + * + * Rout = RedRedGain * Rin + RedGreenGain * Gin + RedBlueGain * Bin + * Gout = GreenRedGain * Rin + GreenGreenGain * Gin + GreenBlueGain * Bin + * Bout = BlueRedGain * Rin + BlueGreenGain * Gin + BlueBlueGain * Bin + * + * We upload to the GPU without transposition glUniformMatrix3f(.., .., GL_FALSE, ccm); + * + * CPU + * float ccm [] = { + * RedRedGain, RedGreenGain, RedBlueGain, + * GreenRedGain, GreenGreenGain, GreenBlueGain, + * BlueRedGain, BlueGreenGain, BlueBlueGain, + * }; + * + * GPU + * ccm = { + * RedRedGain, GreenRedGain, BlueRedGain, + * RedGreenGain, GreenGreenGain, BlueGreenGain, + * RedBlueGain, GreenBlueGain, BlueBlueGain, + * } + * + * However the indexing for the mat data-type is column major hence + * ccm[0][0] = RedRedGain, ccm[0][1] = RedGreenGain, ccm[0][2] = RedBlueGain + * + */ + float rin, gin, bin; + rin = rgb.r; + gin = rgb.g; + bin = rgb.b; + + rgb.r = (rin * ccm[0][0]) + (gin * ccm[0][1]) + (bin * ccm[0][2]); + rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); + rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); + + gl_FragColor.rgb = rgb; } From patchwork Wed Dec 17 10:01:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25580 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 06DC7C3272 for ; Wed, 17 Dec 2025 10:02:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7AD1E61B0E; Wed, 17 Dec 2025 11:02:02 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ZS3f5+7w"; dkim-atps=neutral Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9D40F61A3F for ; Wed, 17 Dec 2025 11:01:51 +0100 (CET) Received: by mail-wm1-x341.google.com with SMTP id 5b1f17b1804b1-4777771ed1aso42310815e9.2 for ; Wed, 17 Dec 2025 02:01:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965711; x=1766570511; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nAlpCB4iJopL0Pn768w20N/UlmcrQmnghUNHBy8yJOY=; b=ZS3f5+7wA3N6QBoKyQuSG20kLtZ97PuFqu/dDszf/2fAqe5ag6OlZ9WiDFceO9YTrk +0Yw8EEKCZ2lwvWHFf3YNkSQY/16Chz8bOZT2ESV49zoQA3CcyQ0GysJ9B94BbvmlZQp oPVvlTtQBXupfY7FkTiCbbelVcT800MlpxUzHtpw3AoqXlbld13PtY1b3lIYSjUC8S8H 2TEIEfUoJ0pVlJ/+c9MW6ffMjywGr3KbfVE2X580mZnR18qn0L7jb9CCmvXlxGibDJ7K Gsx0WI66CjAT98jnJJwOAlHvCXkWpm3gFxW/fke5X7MXAmvGMz5jqEbrPfCAUMfJr2Lb 7J4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965711; x=1766570511; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=nAlpCB4iJopL0Pn768w20N/UlmcrQmnghUNHBy8yJOY=; b=nm5pslPUX0BZb3c2gP7YJK+uuWKu0gSGZKz0DtKFJQ9ZlhSsVgE4HxQ0JuJN/52pus pr/cUahfRxNZcmSW7YVy2O0kGOZd2Dns+7BOKD++7KNm9GBj55ioRT4ht3IwxHQbt7XV /LbzdNRqWp7ELjBgbDlwkAEev4Bq07vgP99cuNU/rfz2CzFtM5SlPPIq+DSNbGr/QTd8 JnAuV2Mq1OGHhlZb2mTw1QPNSC06HGy1vtqB60QluHpHKO8XPKc/QTr86mZ4mI9KNTeO NTEMNQFyOpf9Kg/B43ALkr+GhR6tOvclLe/aI6UXB8MzfaCteHfSU03+XF1g9TYoc05R JVnw== X-Gm-Message-State: AOJu0YxMZIFw+fBVm8kjyQ4FwwN8bDo6lvRp+TMVnnb6khksMP7ZwJQh YWVYhrswif8FPb9GWr4uvUMV2B5OIi9+k2B0HyXN0PP3vmtMuT7dXz/qyW5txJNTNPDjfvhcVnK FJxS0P3o= X-Gm-Gg: AY/fxX6b1o/N7MSCAlypsH0Yl2hL+gXadkqcsNP6FQl/I0qGbmn1+IRwXzxecZTpqdd CCxOUEcPK+RXjJA/ZsIILHjnPxa2Ne/yKRrA42+5+YzWGABF7RvwkLs3vAsy7uI5Iy1aYL3eq60 2uzg7Z57QRC7ArGHAyo7o43Ulk/IVBCvpP5VugZQO+ceBSl08ux5RiqtnVyKb5VEO9R8TPghOsU VFOW3rNnrqhCFCHlaU8lXjQwE1NqzZKkabt0Fs2NgFe0z1flQpeaPXRKYLxx4Ic06AOQtOT8meb 2HWnJ+ObxTSh7ZYql38Pyr77a/F/6z3EsjyueTvWjXm/0uXJS7DYbCMGTji7GNra4RAmp/Lh5/U /tgt/Da3GCUWV37AnQ5rQyfy5oIWVoL1h4mNOMKHxbYlLYtDS9xG10zae0CDYPJuTx4LODjEHks HOzE845bmXgz7OIxJJbbZm51VOyPNw1Ts5lRrKi1U7asN6Y1tdaEeRn1M9p3/AP8m53x6o7QvJX qH6/A== X-Google-Smtp-Source: AGHT+IHltAJSRMoZ/fQAsJFX2wyo7j87D4uDCaJMocqwCmIr9Wqa6eLKHWAuwlImXlqYro69upaP0A== X-Received: by 2002:a05:600c:548f:b0:477:994b:dbb8 with SMTP id 5b1f17b1804b1-47a8f8bd84amr160597375e9.11.1765965710745; Wed, 17 Dec 2025 02:01:50 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:50 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal , Kieran Bingham Subject: [PATCH v9 07/26] libcamera: shaders: Extend bayer shaders to support swapping R and B on output Date: Wed, 17 Dec 2025 10:01:19 +0000 Message-ID: <20251217100138.82525-8-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" We can easily facilitate swapping R and B on output. Pivot on an environment define for this purpose. Reviewed-by: Milan Zamazal Acked-by: Kieran Bingham Signed-off-by: Bryan O'Donoghue --- src/libcamera/shaders/bayer_1x_packed.frag | 4 ++++ src/libcamera/shaders/bayer_unpacked.frag | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index 171a928c2..db8c2a0b3 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -257,5 +257,9 @@ void main(void) rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); +#if defined (SWAP_BLUE) + gl_FragColor = vec4(rgb.bgr, 1.0); +#else gl_FragColor = vec4(rgb, 1.0); +#endif } diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index c41d72f4f..06d80f3dd 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -152,5 +152,9 @@ void main(void) { rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); - gl_FragColor.rgb = rgb; +#if defined (SWAP_BLUE) + gl_FragColor = vec4(rgb.bgr, 1.0); +#else + gl_FragColor = vec4(rgb, 1.0); +#endif } From patchwork Wed Dec 17 10:01:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25581 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 E2097C3274 for ; Wed, 17 Dec 2025 10:02:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 41B0A61A4E; Wed, 17 Dec 2025 11:02:04 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="NODkQbXl"; dkim-atps=neutral Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A552961A61 for ; Wed, 17 Dec 2025 11:01:52 +0100 (CET) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-4775ae77516so65869655e9.1 for ; Wed, 17 Dec 2025 02:01:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965712; x=1766570512; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5qjoeAop1GzrvnIG7vvLvJkbwSmYKtE+YPe2MFgINpo=; b=NODkQbXl1JrepZVGUlixpxv9hjhhmuYVS+CNKBUNaYGQyKtyw5L3HfAz5NP6uPQQwT QAPAhfhUU4czsdvzFA9dxwWLLJm05cIwzMmpP/3REBpxQrrAuBSdBJbRF7H44898luPx A9nM3iChDqg95wG5+XlzZ9N1YwmI5exa9kzg1tW19byH8ifnfsWJ9A2/If8gFkfW/y88 c5cccH68LsXpLzpNlorx2xyZai4rt3smkBAHLZQ/UbSkVCgnOeXapR/mox/gyUMuHsEr 0B4wZW3eMrJxPJB6dwLBMzH6LRbo9nkcfZpHdDQTS9W1iWleMWZmyKebt1EAq6zHr33E M/rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965712; x=1766570512; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=5qjoeAop1GzrvnIG7vvLvJkbwSmYKtE+YPe2MFgINpo=; b=NZFK/1ZAuFvuSnKjl74NrPeD6zZ371zGBJf2tKd95On2EAiS6Jq6ki4wP6KbGZOUvg jh5M7vZ7QzPwIuVM9UuHMEGBkELch7LSuKbXcV3gqOpZnDhcfTfFE0Nk77WsxssU4mS5 BlLdp/qu1EbCzx5kuPjo7LleVri1eNP8dUMltVQffrzgIOxcC/9CFPHRXN6J8k6Eb5OG LcK8ZUwDiUy8hQjv3Bp/uAHXP3G42BVVyoalCqGe1/s3uRb6AVENxSutMEMM7XDTxnVG PQyBi1Hyq1SoOKIrd56lNFu1Oy2sgkXtCcSeJVPUCF2E+m+Gjydip8CxPEb3oCgca7vC tgPw== X-Gm-Message-State: AOJu0YwRhukMq6aeyMhAZYTHfxzUS5Nyj1LINWx8U30ZgJ+utg+1MGrs 5FoWYRRdl/5Rk4pzj/ZdI4ECwMG15JWrir8TRR5IZWkKzX32fhMKN7Y4rLC5xHLKwqq+qRB8DaP wj+e6 X-Gm-Gg: AY/fxX4r2dKkbUz8+mT2Hp9bJkuXb9z5qQ1VaJhbT40c6gDWJPlZJR8I/Zcd/5l7xQK km0rErp32ULO92VoFYEbFFVGTJ4DXlwHOoDNVF1ea2WJiwNIegr8Vfj+AICVqThwQmDzM3E/gXu tAfqfevQYhZ/RVTNTDjFAAU4hNJnruIUWBy8hpm2DB34RcZR4u5rU2Ltco1WNUXS053ACRZ+Q3k VZGgWrGzNeO2Nx6VEASI7xjIHPpPf+u4PG/jqBxxPKO51BaFJIQek2ajiKLjac2sozitWTwR+Pv 7GdlV9mzd3k8FgXCWtXuv3nLkEeIf8MjCe4dbZDPeFK6pXh1WApfcM1z0/Wz/uFNK0kdXYjWc+z Rgk07dV9i62n7hImCJJ6PDDLmRq5zzJ4Ay5jbLo6US0aBhhO8+On3ASDvVnKZAdKJTmT6rBXy4Q PG/K8s4SrJMyo/exDgy2VzC4zXyJUMSuOm34g3Jvvfje229Wm5ZbTr5PhmZcAyEo4mZYM= X-Google-Smtp-Source: AGHT+IEbxmVj6iJaJeRujXAOmxO50UzzfHACot43NZJhcDF8OMis0J/Ok6txdUtyMYRYf4KNR2hh6Q== X-Received: by 2002:a05:600c:45cb:b0:477:9d54:58d7 with SMTP id 5b1f17b1804b1-47be01a441dmr3730945e9.29.1765965711717; Wed, 17 Dec 2025 02:01:51 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:51 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 08/26] libcamera: shaders: Add support for black level compensation Date: Wed, 17 Dec 2025 10:01:20 +0000 Message-ID: <20251217100138.82525-9-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Add the ability to apply a int blacklevel gain against the demosaiced data prior to application of colour correction data. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/shaders/bayer_1x_packed.frag | 3 +++ src/libcamera/shaders/bayer_unpacked.frag | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index db8c2a0b3..7036fe278 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -66,6 +66,7 @@ uniform vec2 tex_bayer_first_red; uniform sampler2D tex_y; uniform mat3 ccm; +uniform vec3 blacklevel; void main(void) { @@ -213,6 +214,8 @@ void main(void) vec3(patterns.y, C, patterns.x) : vec3(patterns.wz, C)); + rgb = rgb - blacklevel; + /* * CCM is a 3x3 in the format * diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index 06d80f3dd..f0d8cd1e2 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -25,6 +25,7 @@ varying vec4 center; varying vec4 yCoord; varying vec4 xCoord; uniform mat3 ccm; +uniform vec3 blacklevel; void main(void) { vec3 rgb; @@ -108,6 +109,8 @@ void main(void) { vec3(PATTERN.w, C, PATTERN.z) : vec3(PATTERN.yx, C)); + rgb = rgb - blacklevel; + /* * CCM is a 3x3 in the format * From patchwork Wed Dec 17 10:01:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25582 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 81D5AC32AF for ; Wed, 17 Dec 2025 10:02:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 037C361D64; Wed, 17 Dec 2025 11:02:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="cVscKM/w"; dkim-atps=neutral Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9017E61A36 for ; Wed, 17 Dec 2025 11:01:53 +0100 (CET) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-47a8195e515so45229425e9.0 for ; Wed, 17 Dec 2025 02:01:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965713; x=1766570513; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZRuITSMve+FWc8iDUneEG5zb0QDixsRjAIi5XBQ3RYM=; b=cVscKM/wCKvJFUVK5ppjBtSmlzVPnwFzuOtRowv78mP35qlpYYh6E/o7VM6Ph9VpSz AgkUL1dUlCWqaNZevlC6W03TICFb5XQbJt4+SHyQBNvAClpt+xaW+wL8I5P3Dc3fOjIF go43CNc6o3DGSY0Y9a+d+z1vwoKi8Q2V2xt9bTFTPx9vrhKmjzDpMYzyJ4XbD5PSTnMM McE5LcuufD3Qh2oN/jGtAmqENb/HAJusR7SQDzYch7sp8p5eb/5FwFxgW/xAl6zxmlsM YV4yml9WxodzIx8dnZ03vCPxqeqzm6i3rkZtSL4Ax+XCWu5vEn7BUB+Jb4cd4DR/ihM5 k3xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965713; x=1766570513; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ZRuITSMve+FWc8iDUneEG5zb0QDixsRjAIi5XBQ3RYM=; b=gC9mAKwXpVLD8Pk+0cVLkIPLq0J0GXR28kxZD9R2c+u7XqTW2rnVWFKSd2JAlEu3CT 88VVzpcX6IBOPYw0aF8OB0wr9b/gEROFMJVHDKly3ruQo1PSDVZ00qIBDLFdTDUaGQkc 52Eii2snQfLaysqjK/YL3bBJoy/H8HZeGeSgETUJbOnIPEOy5QKIaiyC6FbezUq0NYIT z0WwW+TOth0zj+4Awg7WioeN0LyWN/s+YMPy5HfEZtoDn8qrWKLRdLsrMAU1iYVrkJnL jHgvNtJq+tkgP60ID5GHWd09wYyyHlzJZ7dw4D11qgpa8EHTucOD3t0auIF4dK7XvM6g RqwA== X-Gm-Message-State: AOJu0Yy3jax0DZC875/n8APHAU4uamKKO6cHeaKAzkjD28V84KzA1doK sP58ZAwIvzdI4xOCJt5pigdamlt1qb52Axo4ca1EHC9FhUbQvJfWAztqnCQBi8fQQMBM9z3Y0d4 3cr1/ X-Gm-Gg: AY/fxX5227xr6LvdmD8irZUg/f3GqNQCUDSUUHk5bl6oiCaDRd2v/N7O9Fpm+y7xvty z6ETBrvq20rkBQnVdeLKQiQdnxYdSB7AlXHROjj0DAiX1Xfzjh/9Trd4mS8lYDA6EaoE+kJs7bu D4sdCAX+fT3LsLrDKqp366z+npbk4IYIlcQ2NHXdncvacrZDAC3qyA16MlDj6QsrMpcaYfamil2 loF/MR+MpoiVN9mWD2h/dHjeVbI/cNPXkbzRTqMijIsfBoKuUgjFH5gu7RhjdokY4MN62Frp/FY U3UXJDzWu4FAuqSKjPrwEsfTdVEi0UAUpKmukKF4RBFx28wQ3j8koBJkUPfSLQ/f9a1vO5xsSQ9 hr+XaoaPfydjkInlvvzXDdM3rCqH/jKP1I0yxUMZwpVEnQNeI94kVHhPR0OFqKezbXWxWWVFzK8 O8DgxtpdYmpupvXSz4HqeviqD67eDEFW7HXzC7mbh4X+HJwpSw/NcpDGkvA9MbkYbIGm8= X-Google-Smtp-Source: AGHT+IGT+CwgvaidH/6C7tpMUBsaACFuTtFglAX2FPTKT1yXK+w++FjF+HHhb5YwSBDY6AvUBBwIJg== X-Received: by 2002:a05:600c:6290:b0:477:63db:c718 with SMTP id 5b1f17b1804b1-47a8f8ce390mr222333985e9.16.1765965712753; Wed, 17 Dec 2025 02:01:52 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:52 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 09/26] libcamera: shaders: Add support for Gamma Date: Wed, 17 Dec 2025 10:01:21 +0000 Message-ID: <20251217100138.82525-10-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Add gamma compensation to the debayer shaders after colour correction is applied. Similarly only apply the calculated Gamma curve when using the CCM as the lookup tables already contain the data. Suggested-by: Milan Zamazal Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/shaders/bayer_1x_packed.frag | 4 ++++ src/libcamera/shaders/bayer_unpacked.frag | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index 7036fe278..77d9fbfa7 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -67,6 +67,7 @@ uniform vec2 tex_bayer_first_red; uniform sampler2D tex_y; uniform mat3 ccm; uniform vec3 blacklevel; +uniform float gamma; void main(void) { @@ -260,6 +261,9 @@ void main(void) rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); + /* Apply gamma after colour correction */ + rgb = pow(rgb, vec3(gamma)); + #if defined (SWAP_BLUE) gl_FragColor = vec4(rgb.bgr, 1.0); #else diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index f0d8cd1e2..aba11a87f 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -26,6 +26,7 @@ varying vec4 yCoord; varying vec4 xCoord; uniform mat3 ccm; uniform vec3 blacklevel; +uniform float gamma; void main(void) { vec3 rgb; @@ -155,6 +156,9 @@ void main(void) { rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); + /* Apply gamma after colour correction */ + rgb = pow(rgb, vec3(gamma)); + #if defined (SWAP_BLUE) gl_FragColor = vec4(rgb.bgr, 1.0); #else From patchwork Wed Dec 17 10:01:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25583 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 0F404C3257 for ; Wed, 17 Dec 2025 10:02:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7D75D61EF2; Wed, 17 Dec 2025 11:02:07 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="n4Svz3os"; dkim-atps=neutral Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DA77961A62 for ; Wed, 17 Dec 2025 11:01:54 +0100 (CET) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-4779cc419b2so55738595e9.3 for ; Wed, 17 Dec 2025 02:01:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965714; x=1766570514; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dN8UZt6qlRDwenuDplOdpGWNKDU85eQ9zmywwDQb0Cg=; b=n4Svz3os/ZSF1ubDiTvqlnqNBDZeBk5MV/Vhmg0oh7nWIuExvYLC4uwNGJedbbnih6 nQ9HitrmFKHoHtv/A60DTYDZQY4XToefZ0H2qcXDs+F3nEqNhcGndKUxvxU7PQEJOi03 WaBIiOIr+KTTEyW4ETEQ6nKIvgakGbTrok45LnhAHDqIguw/A92ZkiKy6lFpkLwPomMW G3bTUPvBaA4Z4gE1joZmZ8URQmlQQSdh2z61tb6ZpSBHAGDYePMigJ+7WaSQlAHblISu uMTW2QyyVTqFPh3j6BDrOAnrCkTm1k0ohsnjFHKOSE2pIqCYA8RkGAhxIh0y87Yhx7aI Br9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965714; x=1766570514; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=dN8UZt6qlRDwenuDplOdpGWNKDU85eQ9zmywwDQb0Cg=; b=eGXW5vDpNILcPYsZZptIJ8HxLwwg7L6ty2rQPe5NPNYK3zuOTP72NPXD2B2SqYsz8k J2wcmT362Wix14kClf8R99sO6FrDcuzCbnQwH7rqgVA2gQkdPhd0uIIPWL0TSWJi5lA5 veTwqOp9N7LuNRaviDh9p3gI9niYmY83YX1fWHVdujoBkpXzZojfh4p+2tblfKx7bAD4 tbLvm+Qs5fY5j/NM6qkTLu9l5QfUSFzBkeY0VA2SSfQ6v9I/MdslUPMxr4JyoLS2cddJ RMxRH5/t793ob+jh27GAocdSuYaYOjpD8zfZV+j08QpX5ERD12gqoSsGCo/gCzDyweRP bMdw== X-Gm-Message-State: AOJu0YzpJ+DlPIPrvtrLFDpEOmPItOQ6+q+nRFHklw0CAuCOIhndF5Kd Ju+mQhRGfAJ+EdpK0B8surHXFu5W3xEd32slO/6hy/7K1AwZc5ExSGhmJnGHGi3Yx17XmVszXGu 5P79W X-Gm-Gg: AY/fxX57E85XbO0YQpLlLS3MpIfl/GjIRseiyYRM0A2XF6Qr8+i5ZaJps06qG81hgMJ ShDbU9N6jWbrYM48yOFTAJZosdQou/ct5UbBSp/tUSuhCxiZhV2JuaMui0y2ZBM2DYQvNNu6jCj pQ+hXdj3ZghmW/tOS1kSE/DexuPLvh5NXf3FnBGIubLLTLXwAMb6dVEN2UijgBm9kbPncA+KelA Gq6j8NdGlhBioCjcGqFDJn20N2DVcxzQ+U9QPtvZ1S1vSpxcof6u5cDUjI2asCAdObylUZPviXw um50imzco0imFseXmn/uBp43JnelnKWq7PUdm2Z2d449yezh4SyMzlx3/u0YJyRB0UAq1S9uH0g ECt5TOKcxej4SszLlc30GZ3goCZVSZzQeJYEdQe/XBBDF1NmvwaJLlJ407+BibezQA6fL6UD+Hr IoSxKI6mh0WMF4ip23w3f+xHq5T59tT0f5R2IpvYXoWVQAruSPuvhN+PH9FsoHU0D2qq9v0oQZ0 ER2rQ== X-Google-Smtp-Source: AGHT+IHT248ilUmvEhxuKRiaCo+h+yFbzkDYPSfpUx0aBzdzbV56JKyZ1hxs7fKMdo0wq1jQ0E7oHQ== X-Received: by 2002:a05:600c:1994:b0:477:a978:3a7b with SMTP id 5b1f17b1804b1-47a8f905675mr155006335e9.22.1765965714017; Wed, 17 Dec 2025 02:01:54 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:53 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 10/26] libcamera: shaders: Add support for contrast Date: Wed, 17 Dec 2025 10:01:22 +0000 Message-ID: <20251217100138.82525-11-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Apply contrast after black-level and CCM operations. Suggested-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- src/libcamera/shaders/bayer_1x_packed.frag | 21 +++++++++++++++++++++ src/libcamera/shaders/bayer_unpacked.frag | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index 77d9fbfa7..0b730070e 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -68,6 +68,16 @@ uniform sampler2D tex_y; uniform mat3 ccm; uniform vec3 blacklevel; uniform float gamma; +uniform float contrast; + +float apply_contrast(float value, float contrastExp) +{ + // Apply simple S-curve + if (value < 0.5) + return 0.5 * pow(value / 0.5, contrastExp); + else + return 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp); +} void main(void) { @@ -261,6 +271,17 @@ void main(void) rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); + /* + * Contrast + * contrastExp 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2) + */ + float contrastExp = tan(clamp(contrast * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001)); + + rgb = clamp(rgb, 0.0, 1.0); + rgb.r = apply_contrast(rgb.r, contrastExp); + rgb.g = apply_contrast(rgb.g, contrastExp); + rgb.b = apply_contrast(rgb.b, contrastExp); + /* Apply gamma after colour correction */ rgb = pow(rgb, vec3(gamma)); diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index aba11a87f..114e32058 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -27,6 +27,16 @@ varying vec4 xCoord; uniform mat3 ccm; uniform vec3 blacklevel; uniform float gamma; +uniform float contrast; + +float apply_contrast(float value, float contrastExp) +{ + // Apply simple S-curve + if (value < 0.5) + return 0.5 * pow(value / 0.5, contrastExp); + else + return 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp); +} void main(void) { vec3 rgb; @@ -156,6 +166,17 @@ void main(void) { rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]); rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]); + /* + * Contrast + * Convert 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2) + */ + float contrastExp = tan(clamp(contrast * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001)); + + rgb = clamp(rgb, 0.0, 1.0); + rgb.r = apply_contrast(rgb.r, contrastExp); + rgb.g = apply_contrast(rgb.g, contrastExp); + rgb.b = apply_contrast(rgb.b, contrastExp); + /* Apply gamma after colour correction */ rgb = pow(rgb, vec3(gamma)); From patchwork Wed Dec 17 10:01:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25584 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 2F8D6C32DE for ; Wed, 17 Dec 2025 10:02:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6C5D561EA7; Wed, 17 Dec 2025 11:02:09 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="NKsBSjra"; dkim-atps=neutral Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 28C8261A37 for ; Wed, 17 Dec 2025 11:01:56 +0100 (CET) Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-47798ded6fcso36048175e9.1 for ; Wed, 17 Dec 2025 02:01:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965715; x=1766570515; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YOU8yzvJmLe2CYSAv2DGpWHlxVqrCoB7v5e5gKZ8hTI=; b=NKsBSjra9upLRoisqleuGpQA7xkdqUTLqtRWKV7rejY8XrcDK91vZhjjl9GbEtQOUg dNsmtXdXvAhQO4peryfc0Wm7nnOvU2H4DO9vendEsOh1pBqj6Sl53aHGrjKwN//ho8eG AYNE9bKT/gdwJY/hHGgsFoyHS8VBxFe1bIbWELvATn0IZ3JQsv9G9RZb6iN9QW+L6ZnG 43o1OTEiBMJBKfkLl53WqFMbGMTcLgdX6LGAOl4TjnEtAcddGolM2nMM3QqzyaCWl9YX xKQt21SHVe5xekdnXsgn0/5QBct3HtnbHOe4uPrLLknEUPLSyfPw7I1weiiZqQJSQCgR aXLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965715; x=1766570515; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=YOU8yzvJmLe2CYSAv2DGpWHlxVqrCoB7v5e5gKZ8hTI=; b=scPfkMuUe95USywphR/YocdHzGaVbMiS+7YSm2T1MiAs8ocTK4ZPDQq8SZgjSZdchQ 2MFWH5+Laf9J/2jOjDRfygLAWN/w+TMcmvBDLVQXfe//tSkuheZKxnT8FmeR4oqdLBpX WuTnttNHXMf23hqTX7ByJu2woUlj7qsxyXv+DfwZ2LUei1GOpNHCHJ87e6pJ33I0clQz B/u8MGSGUZZBc+fXYUNg3vISRZuiee8RXTivkMdKHa8n30aJuITy9/8FQRFfSW/1ZH+P h1a9wPc3mC5resi6dM5a0khUNI6yzj9wKeAGiAijPiqgVx+wAmsMf2vrjnXGJ8FKphEY WjVQ== X-Gm-Message-State: AOJu0Yy57cJcvinKMCQICS8cA8o4FZIxfiyvws+4bmuXEN5kGDUr7sNS fmoLmQM3Olh+z6lriV5+ixox8AtuUQE6Zni+ktUR9lItp4i8CQzywx8MMZorMaNuxgvk+8KUIqE HrNLj X-Gm-Gg: AY/fxX5DAUZuauP6tId5Yyt90YQ0w4/8XUFK089b1CwfeVz1/wu9i+oX/Q7VunvBk2Q Uti8FsozYyQvOc1oOAoEYeMZEGS8HbHcEOsQ7U7WXi5cAFfqzIRKMPJ9Z+fs5PxddvuDoO7mJaf YEYOgomWOj807SELz9CxKB4Wt4QrptXwBmqq/tCkC0zDboZ8qGrS4VZAFaL1XZlP8IZHuYpRadt Ybudzc5zEdM9R6FKEYEkj8bnAtNQ+LMn1LrwaOVznK6AYPLxcm6vh0+iLsmO3+//vI1tkoW826s 9MrwNASzB5/Ny00pAZPSKcS5LGlPrvKKGHVtW+UgFpE48HEcJWPRhYRYlrIesDlLe52qWvGU2s4 Uw/5h+nV+Q0KMgqak1LDG1w43LnYnQCDcBLvO+B+jO+ewNkqoYwgS9zOYrMOrsuVoQ0hRkxRMrA aeVh4G7v5m+I0x1vzajFNGy2VDqw+mTsb6t0xVeJPzEIaZ/t2A+GQksQvKvJfUYD60V8g= X-Google-Smtp-Source: AGHT+IGJMDKNayySZ0lAQu9EnYgnZ4Jrj3BMc07TyFmYyzc+DA4wyXGS7AunMx+kZzMnwcx4i3ID5w== X-Received: by 2002:a05:600c:608d:b0:477:632a:fd67 with SMTP id 5b1f17b1804b1-47a8f8c16bfmr194666445e9.12.1765965715380; Wed, 17 Dec 2025 02:01:55 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:54 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Hans de Goede , Milan Zamazal , Bryan O'Donoghue Subject: [PATCH v9 11/26] libcamera: shaders: Fix input sampling when width != stride Date: Wed, 17 Dec 2025 10:01:23 +0000 Message-ID: <20251217100138.82525-12-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" From: Hans de Goede When bayer_unpacked.vert is calculating the center and x/yCoord values stride != width is taken into account for x/yCoord deltas since it is taken into account by debayer_egl when setting the x part of tex_step uniform. But it is not taken into account for the center.x which is just directly copied from textureIn, leading to the input width sampling covering the entire input stride instead of just covering the input width. Use the existing and currently unused stride_factor uniform to pass the width/stride ratio and correct center.x for this. This fixes the misrendering seen on x86 laptops which is caused by the CSI2 receiver there requiring a stride which is a multiple of 32 often leading to stride != width. Signed-off-by: Hans de Goede Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/shaders/bayer_unpacked.vert | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcamera/shaders/bayer_unpacked.vert b/src/libcamera/shaders/bayer_unpacked.vert index fb5109eee..423dde0fa 100644 --- a/src/libcamera/shaders/bayer_unpacked.vert +++ b/src/libcamera/shaders/bayer_unpacked.vert @@ -21,7 +21,7 @@ attribute vec2 textureIn; uniform mat4 proj_matrix; -uniform vec2 tex_size; /* The texture size in pixels */ +uniform vec2 tex_size; /* The texture size in pixels */ uniform vec2 tex_step; /** Pixel position of the first red pixel in the */ @@ -40,8 +40,10 @@ varying vec4 xCoord; /** of the adjacent pixels.*/ varying vec4 yCoord; +uniform float stride_factor; + void main(void) { - center.xy = textureIn; + center.xy = vec2(textureIn.x * stride_factor, textureIn.y); center.zw = textureIn * tex_size + tex_bayer_first_red; xCoord = center.x + vec4(-2.0 * tex_step.x, From patchwork Wed Dec 17 10:01:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25585 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 27B16C326C for ; Wed, 17 Dec 2025 10:02:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6102661F2F; Wed, 17 Dec 2025 11:02:11 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="bhaxPWGX"; dkim-atps=neutral Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1C08361A54 for ; Wed, 17 Dec 2025 11:01:57 +0100 (CET) Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-477770019e4so51940615e9.3 for ; Wed, 17 Dec 2025 02:01:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965716; x=1766570516; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AkHDdjGVPAipGQD5NCfZ9IhKGBJlwJpwDuA7iC3dtE0=; b=bhaxPWGXx51WS96SOb0NzKb1KgKjU+lqRz/zAYuisG3TCqqrfa/fGh2V8Hso+XyxvW 3HQ8DcZsCTKDEYVCmcd6G5Zqe6SLwMHjB35jz9trS3qnnzd8yon1Ze1+BKMc6nLW//i+ Z2n5mmya3byNNcaRb7oGwVNhEhDbqnfydlOVHAUHXbCbV3arE6Nj31ljAD8SoOr3J+Ky rHR9kNFAO2ZZhpUg4vSezXy2O/FukJa6HmEPXpPegQQJo9YMYlsuWAFAqyZwsKxHbBEs 52ZXHQFhdYyTuWNYvUKDiGQZHKBH6cLSk4VBxCAtRRkmDWUkq7Gxjut3KAInZqfQuWWP /VEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965716; x=1766570516; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=AkHDdjGVPAipGQD5NCfZ9IhKGBJlwJpwDuA7iC3dtE0=; b=jkov0gSkBYam/kEmkGl3p2rP6jeh2EWJb7h9NmRaW8gT+i401IJG4CEsmP6qvBozdi PPn5z9qChCqZFL9VN4KTegRbU8xipBVktTlJ390VO19TCVVSxOVbc+cPQle/10PNWUMk UsIbxFNFf0MUf8tARh1IIG63S8tSTcm4X4LjkoHouhY+hqmYBoq0IAOzwZJvXRdLYwyO thGAE8+LkSl7HxmuSadInXRFdhJ0HmoQBJu5KUftwJcDWkJxHOTOhgFAaXOQre6Bc/Or 0St2Dj1U+9P2hbpOgnBbLTwTQvXSXSl02Jt/SbGutITbUoGqfQSt2HDfgt0zM8LeS2Zb 36Cg== X-Gm-Message-State: AOJu0YyDNfxwnnb/iNKCbg613KRlfIVgWYHh1Q6EHPe4a1hbx+izh1CV mO2EaATuUfTOiqNh8slHGY06SfVjdaNF6rvIPHKEVHjN+eyn6WETKKZbU3A1AxL9s3XPYPWW+4F IJ/w2 X-Gm-Gg: AY/fxX4BaODmVnJDmWqCi7/Ojd+5o1PkLB3IWJyeEX5b9kMuCoqbzVt4NJHZy211tKz hUxnaaR676QQDjEzD6sMyS6BtMr10W+RppDXswqcxQ4aiwDFUqLnnxcd2wAmJL76LZNS6rFAq5c xqtuiPFxVdZkp4DHxwWIoHBA/A46GAsBB0/DGCJt0xndWo5COt6Nbq/GPmDHr+s0fqP8zmXpvVA 6I8puZbA2jGaEqPpT5MkzHYmzpRE3egLd9pT6l5Ddyko0Np3IVQovG9y51ld9EhURJAEeKypLMj S756D5pz3cgTQWYdpMsJ3ii+A9vRj9WBtmUH+oq0657yjbJOiog8Cbo4kwugZc60ATL9Y2dksYS N+JTTR99j6GvUwLYKN6sT67hvi+V4e5v3MpcyczBOvUprHjEQ6WqEg979x/PvUiQb2AnA3RIgrc vZgOwDm8U9vbn5dKYRvYzD1rC1aTxBGSFIHr7uX5miDpzcKBqcMuU+OOLXXrWrNWZCR2I= X-Google-Smtp-Source: AGHT+IET7iFn7+qGYixQava9cJ1Oxff86MzCUZa5y3Azn07CzsyUquv6IUkCmGxOo95XRsyLySLe3g== X-Received: by 2002:a05:600c:6290:b0:477:76bf:e1fb with SMTP id 5b1f17b1804b1-47a8f8cdfd1mr230766945e9.16.1765965716350; Wed, 17 Dec 2025 02:01:56 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:55 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 12/26] libcamera: software_isp: Add member variables to track selected input/output pixelFormat Date: Wed, 17 Dec 2025 10:01:24 +0000 Message-ID: <20251217100138.82525-13-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" In order to have Debayer::start() tell the eGL shader compilation routine what the input and output pixel format is, we need to have a copy of the selected format available. Add variables to the inputConfig and outputConfig structures to allow tracking of this data for later use. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/software_isp/debayer.cpp | 10 ++++++++++ src/libcamera/software_isp/debayer.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index b33f818a7..4645b6a1b 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -290,6 +290,16 @@ Debayer::~Debayer() * output image buffer. Set during stream configuration. */ +/** + * \var Debayer::inputPixelFormat_ + * \brief The incoming pixel format + */ + +/** + * \var Debayer::outputPixelFormat_ + * \brief The output pixel format + */ + /** * \var Debayer::red_ * \brief Lookup table for red channel gain and correction values diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index b8287166e..d716ad080 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -75,6 +75,8 @@ public: DebayerInputConfig inputConfig_; DebayerOutputConfig outputConfig_; + PixelFormat inputPixelFormat_; + PixelFormat outputPixelFormat_; DebayerParams::LookupTable red_; DebayerParams::LookupTable green_; DebayerParams::LookupTable blue_; From patchwork Wed Dec 17 10:01:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25586 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 C1394C32E0 for ; Wed, 17 Dec 2025 10:02:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2B9CC61AA4; Wed, 17 Dec 2025 11:02:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ZpuNbcxP"; dkim-atps=neutral Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BDE2861A4C for ; Wed, 17 Dec 2025 11:01:58 +0100 (CET) Received: by mail-wm1-x342.google.com with SMTP id 5b1f17b1804b1-4777771ed1aso42312125e9.2 for ; Wed, 17 Dec 2025 02:01:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965718; x=1766570518; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8bRhPhWRAIH+CndgPIrv72h6Mc85MvUec+MxNX85Dko=; b=ZpuNbcxPu+EqDyQPe2gI1T2hOzgQDTHHicp85zY2EK1nVwbVEFPkeyvLLu6qrybkvF 3PX0mWvYiSOZ7Ir4rno/yeB/4AKwe+5z5S73fCXDDP42HqKw1kDysu4yRusenwAa9IcD PSDBJeEzxLH7UbHjs3wDsVYCz0roPhEy9hjXiyQOn/BHKkHvo7unlXcEAGeN2MljIxSH MuVqQxxvKRqXhdE5lqu3d0N5CIqLQVflqMPohzRaSDUcKLQJUQEFv8dmlkwVPH34dCnU nyxyPlzDXW0UKP+IWv0IE2tol/EIov5pKJyHbgnZ6ErmA2JJYA8TqrSKPy/P4D2Yw4c5 5DiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965718; x=1766570518; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=8bRhPhWRAIH+CndgPIrv72h6Mc85MvUec+MxNX85Dko=; b=XZgvCG6+HTzZg7Kg4waTHS+42z4Ev4V3uzU1ssl18mYSWWJ+2MAZ12ETZ/xyZZILZG AlIvzuvDl0ZkS7+T5wu/eZh13zp3ECib6rSpqq0EaCGmfV1bESWlKxddCcrhmLpvo9TO nTdxW2/MBsVd3ZAMr0XL8+ZIDSlqtQeB5ahntzkZ5k1nt+5XhGJ/AvXOH5gz0+n8mtE8 kzYwg6PB3frooNTwCPLsSCLNYzDGALF78fsLb092JGpbD7Ei03CBTjX47Wj3oNndPakP jQuniJupoaW7dZr7C+XM1jTXmKhaIoMuRHHJrj+1wRmag/U8Ft5z3Vz7RHFtEjJdDwpH x/dw== X-Gm-Message-State: AOJu0YyudYTgIWcOUQe4QslKshwgKJ8SNVisnjV5aF/HoEDDU/IG5qNu q/UYNktId7JJIkTdZGww/EHZMpX6z0I3oVNFTwC47jVFy+rL6031X/a1IiBoMeeZaRubMKENF+O NgronJ4A= X-Gm-Gg: AY/fxX6pwDnT6/g3LoVpu4MSfyL7b0Sa3ihJU2XSBJbKrNUxuANRqwyptUo8jjCtbRH NI96UkIZpUzgIj12ZL54UJixcv9IY9Nv9Zx9kye9jsp1udFYH/iVa6qXbe9EHKM8DD+HEDfqqeb bIU19QBaQjBHKcdgrZV8plTGO0nytt+NNg5EUtGNgR8TNC+MLdK6VeTWyty0j8cOG/1CPNzz3nU tGVAQBBy/IAmQ5Esxo54hQD5pVWd/UCn9nRZk182NP/lUrI0Em8zZG/lEyeuc+Ug28q1jfb4s3d WQS/P6oheSSrbAxKnGYSbMBDXef70NDdAblr8PObO/vcI97AqW1++vbRwN1FhRANywMizbBjzqT ArEywD+ZTjWZ13iScqQTe1LMNb88j8guyjcWS4H5jdB9LSUjqYWiUf2tA3JFpj3VXsZelkeWDFk 4mlopRG4ZjDFMBbamZC0nOTV+LZhK19SrpAC3OUQwydU4Op4GELJnZEocbGljOxkxEogA= X-Google-Smtp-Source: AGHT+IGYApBG4hOHTKmWfhhlweIoZ6C+3uXBXNQP5YvJ0EC+SLRhq04OmA7nexnYfg6EjVnLca7SjQ== X-Received: by 2002:a05:600c:4f11:b0:479:3a89:121d with SMTP id 5b1f17b1804b1-47a8f9180a2mr196336365e9.36.1765965717849; Wed, 17 Dec 2025 02:01:57 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:57 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 13/26] libcamera: software_isp: Add a Size_ member variable to pass to eGL later Date: Wed, 17 Dec 2025 10:01:25 +0000 Message-ID: <20251217100138.82525-14-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" We will be initialising eGL from Debayer::start(). We need a copy of the size data passed in configure() to tell the fragment shaders the right output size. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/software_isp/debayer.cpp | 5 +++++ src/libcamera/software_isp/debayer.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 4645b6a1b..a80661d2c 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -300,6 +300,11 @@ Debayer::~Debayer() * \brief The output pixel format */ +/** + * \var Debayer::outputSize_ + * \brief Output size object + */ + /** * \var Debayer::red_ * \brief Lookup table for red channel gain and correction values diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index d716ad080..cd2db9930 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -75,6 +75,7 @@ public: DebayerInputConfig inputConfig_; DebayerOutputConfig outputConfig_; + Size outputSize_; PixelFormat inputPixelFormat_; PixelFormat outputPixelFormat_; DebayerParams::LookupTable red_; From patchwork Wed Dec 17 10:01:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25587 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 66C4EC3272 for ; Wed, 17 Dec 2025 10:02:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8F8BC61D25; Wed, 17 Dec 2025 11:02:14 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="HVGTbMp+"; dkim-atps=neutral Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9AE1061A62 for ; Wed, 17 Dec 2025 11:02:00 +0100 (CET) Received: by mail-wm1-x344.google.com with SMTP id 5b1f17b1804b1-47aa03d3326so16017795e9.3 for ; Wed, 17 Dec 2025 02:02:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965720; x=1766570520; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zbZ/JpDoUIU5pXbdXgHhxRK3UhoBo8ZOIX42d6O1PdQ=; b=HVGTbMp+H+efJY8iYAmo31NHU65VgjV0lP+s7WufZ0prPioQHKEz/fnac6argEr+aq ADPx/nhO49xE6Nf8mLIbyfn7E5idqTNwzE9FrP2mY3xFC8R1PxSiForEoeT9E8QBqrb7 yDk/mJkDQrOuhZX5z77kAb+WMeEpDwbgHFT5KIhA/VdI/8nK0DP1tnwHKjtpUbQFcDRW jUwYYCgHdT2KzH7/MrhaFrypLjzbpnRJC1+do0k+jf5Rd/YZR6/DjfWT/IKMotBElvc7 xdLqr85tS9E4WPZdQ2KA38JX6Y1MsHRZ+lt6MMJDI6HgIhTY6EpshRxrtUjYMhKOMJgn OSrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965720; x=1766570520; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=zbZ/JpDoUIU5pXbdXgHhxRK3UhoBo8ZOIX42d6O1PdQ=; b=wOLgyOJeueC8Jw78QDS2ufUfNzRKkTS/O6UPg5bHsVaU8S4IOMFHst42BYLOaPlP7R 7//uBGa6EHTYzVF5ydYiJizoS8E7QhIRvk1qjqoGVkT1ejBQqrP1mmidBoewc7Gu9FIK zMST2mHEVDmoRIyBBm9ixLPLdP6Gcg+DxCDSpV1xHFd5sqf3SxgIiy+KTPFkLhk28fZt rNfSBR0vnU/cuxMbX8rieqD4vrbRdonScz9anrW0KhmfiF8BPlgc5ai6KDWY/ZKJ+yOH rmRfE8Su/JR+EhOE6UJGc4mXgMfyfYLoK1LHm9zMz+1EpTMDkvuEG63pHuCS8eHvyx25 KbtA== X-Gm-Message-State: AOJu0YxP0etIus5HXIOr+E2ScNyDhuPvCBmFeTi6K1E09wKlGH3qSibC +ChUwxN6J1k9GcVspGkkedMbbCiBDLuBwkNx4yCady4BRZnPyCZ+BBRBHnyzZCvUK2keb5jBHig fPT4UbHg= X-Gm-Gg: AY/fxX7UwIlqPc+x5aFZwcP3+vpRkiWUhgv5pXQgRD22BUscm4basjbhl75CMZibsz7 16jrY0hrPO/z99Vu55hQEp3Uwt7DSNyAE0TK89vtYdn0MeJH1CGUdRo66uF33VmweEhJ69zYERi rXFzGC/BW7MEBPvrLL2fIejJZPkYKeRdsH2Ie+qtgbwiI6/cTJLnBt1umxdtAK6hPfZ3QTgTKAe ijdlyp/VOg76lS3o7h7kylIgBm8rawu/FvbDNSDGIbhxxsfXsRIjDWCRP4DMGEAPXyAKuNZgXx7 xKXKG5+B6TX3muFD2PomWYMrv55lenn3NBChB81RxSgd7xf0hUMks3WcdKslIY5sRDSWijZBkzq ghB3nBsuvb/N5B73K5+FqmDeS9T00QqMtzzjLodjRtuuPnFBQXe8AjrnWgQl1HLddyMl4R2jres aSgZYs0o3R6WQRYs+Ux+IRQjc5cnPCwVpIHjkGwew1K+z+yvlN6zY1BhKCUbDec2MCo3g= X-Google-Smtp-Source: AGHT+IEbLt/TPNAcMeEgnlAZiRASblCy3dNPXkYby7suIpno321uWx5mlkv4M5BwQXTNmX9ze96Yrg== X-Received: by 2002:a05:600c:3484:b0:477:5897:a0c4 with SMTP id 5b1f17b1804b1-47a8f8a80ccmr181294885e9.4.1765965719572; Wed, 17 Dec 2025 02:01:59 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.01.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:01:59 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Robert Mader , Milan Zamazal Subject: [PATCH v9 14/26] libcamera: software_isp: debayer_egl: Add an eGL Debayer class Date: Wed, 17 Dec 2025 10:01:26 +0000 Message-ID: <20251217100138.82525-15-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Add a class to run the existing glsl debayer shaders on a GBM surface. Signed-off-by: Robert Mader Co-developed-by: Robert Mader [bod: took scaling and buffer size fixes from Robert] [bod: took fix for center byte calculation from Hans] [bod: took formatting fixes from Milan] Signed-off-by: Milan Zamazal Co-developed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue Reviewed-by: Robert Mader --- src/libcamera/software_isp/debayer_egl.cpp | 650 +++++++++++++++++++++ src/libcamera/software_isp/debayer_egl.h | 141 +++++ src/libcamera/software_isp/meson.build | 8 + 3 files changed, 799 insertions(+) create mode 100644 src/libcamera/software_isp/debayer_egl.cpp create mode 100644 src/libcamera/software_isp/debayer_egl.h diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp new file mode 100644 index 000000000..9d7134f2a --- /dev/null +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -0,0 +1,650 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + */ + +#include "debayer_egl.h" + +#include +#include +#include + +#include + +#include + +#include "../glsl_shaders.h" + +namespace libcamera { + +/** + * \class DebayerEGL + * \brief Class for debayering using an EGL Shader + * + * Implements an EGL shader based debayering solution. + */ + +/** + * \fn DebayerEGL::DebayerEGL(std::unique_ptr stats, const GlobalConfiguration &configuration) + * \brief Construct a DebayerEGL object + * \param[in] stats Statistics processing object + * \param[in] configuration Global configuration reference + */ +DebayerEGL::DebayerEGL(std::unique_ptr stats, const GlobalConfiguration &configuration) + : Debayer(configuration), stats_(std::move(stats)) +{ +} + +DebayerEGL::~DebayerEGL() +{ +} + +int DebayerEGL::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config) +{ + BayerFormat bayerFormat = + BayerFormat::fromPixelFormat(inputFormat); + + if ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10) && + bayerFormat.packing == BayerFormat::Packing::None && + isStandardBayerOrder(bayerFormat.order)) { + config.bpp = (bayerFormat.bitDepth + 7) & ~7; + config.patternSize.width = 2; + config.patternSize.height = 2; + config.outputFormats = std::vector({ formats::XRGB8888, + formats::ARGB8888, + formats::XBGR8888, + formats::ABGR8888 }); + return 0; + } + + if (bayerFormat.bitDepth == 10 && + bayerFormat.packing == BayerFormat::Packing::CSI2 && + isStandardBayerOrder(bayerFormat.order)) { + config.bpp = 10; + config.patternSize.width = 4; /* 5 bytes per *4* pixels */ + config.patternSize.height = 2; + config.outputFormats = std::vector({ formats::XRGB8888, + formats::ARGB8888, + formats::XBGR8888, + formats::ABGR8888 }); + return 0; + } + + LOG(Debayer, Error) + << "Unsupported input format " << inputFormat.toString(); + + return -EINVAL; +} + +int DebayerEGL::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config) +{ + if (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 || + outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) { + config.bpp = 32; + return 0; + } + + LOG(Debayer, Error) + << "Unsupported output format " << outputFormat.toString(); + + return -EINVAL; +} + +int DebayerEGL::getShaderVariableLocations(void) +{ + attributeVertex_ = glGetAttribLocation(programId_, "vertexIn"); + attributeTexture_ = glGetAttribLocation(programId_, "textureIn"); + + textureUniformBayerDataIn_ = glGetUniformLocation(programId_, "tex_y"); + ccmUniformDataIn_ = glGetUniformLocation(programId_, "ccm"); + blackLevelUniformDataIn_ = glGetUniformLocation(programId_, "blacklevel"); + gammaUniformDataIn_ = glGetUniformLocation(programId_, "gamma"); + contrastUniformDataIn_ = glGetUniformLocation(programId_, "contrast"); + + textureUniformStep_ = glGetUniformLocation(programId_, "tex_step"); + textureUniformSize_ = glGetUniformLocation(programId_, "tex_size"); + textureUniformStrideFactor_ = glGetUniformLocation(programId_, "stride_factor"); + textureUniformBayerFirstRed_ = glGetUniformLocation(programId_, "tex_bayer_first_red"); + textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix"); + + LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ + << " tex_y " << textureUniformBayerDataIn_ + << " ccm " << ccmUniformDataIn_ + << " blacklevel " << blackLevelUniformDataIn_ + << " gamma " << gammaUniformDataIn_ + << " contrast " << contrastUniformDataIn_ + << " tex_step " << textureUniformStep_ + << " tex_size " << textureUniformSize_ + << " stride_factor " << textureUniformStrideFactor_ + << " tex_bayer_first_red " << textureUniformBayerFirstRed_ + << " proj_matrix " << textureUniformProjMatrix_; + return 0; +} + +int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputFormat) +{ + std::vector shaderEnv; + unsigned int fragmentShaderDataLen; + const unsigned char *fragmentShaderData; + unsigned int vertexShaderDataLen; + const unsigned char *vertexShaderData; + GLenum err; + + /* Target gles 100 glsl requires "#version x" as first directive in shader */ + egl_.pushEnv(shaderEnv, "#version 100"); + + /* Specify GL_OES_EGL_image_external */ + egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable"); + + /* + * Tell shaders how to re-order output taking account of how the + * pixels are actually stored by GBM + */ + switch (outputFormat) { + case formats::ARGB8888: + case formats::XRGB8888: + break; + case formats::ABGR8888: + case formats::XBGR8888: + egl_.pushEnv(shaderEnv, "#define SWAP_BLUE"); + break; + default: + goto invalid_fmt; + } + + /* Pixel location parameters */ + glFormat_ = GL_LUMINANCE; + bytesPerPixel_ = 1; + shaderStridePixels_ = inputConfig_.stride; + + switch (inputFormat) { + case libcamera::formats::SBGGR8: + case libcamera::formats::SBGGR10_CSI2P: + case libcamera::formats::SBGGR12_CSI2P: + firstRed_x_ = 1.0; + firstRed_y_ = 1.0; + break; + case libcamera::formats::SGBRG8: + case libcamera::formats::SGBRG10_CSI2P: + case libcamera::formats::SGBRG12_CSI2P: + firstRed_x_ = 0.0; + firstRed_y_ = 1.0; + break; + case libcamera::formats::SGRBG8: + case libcamera::formats::SGRBG10_CSI2P: + case libcamera::formats::SGRBG12_CSI2P: + firstRed_x_ = 1.0; + firstRed_y_ = 0.0; + break; + case libcamera::formats::SRGGB8: + case libcamera::formats::SRGGB10_CSI2P: + case libcamera::formats::SRGGB12_CSI2P: + firstRed_x_ = 0.0; + firstRed_y_ = 0.0; + break; + default: + goto invalid_fmt; + break; + }; + + /* Shader selection */ + switch (inputFormat) { + case libcamera::formats::SBGGR8: + case libcamera::formats::SGBRG8: + case libcamera::formats::SGRBG8: + case libcamera::formats::SRGGB8: + fragmentShaderData = bayer_unpacked_frag; + fragmentShaderDataLen = bayer_unpacked_frag_len; + vertexShaderData = bayer_unpacked_vert; + vertexShaderDataLen = bayer_unpacked_vert_len; + break; + case libcamera::formats::SBGGR10_CSI2P: + case libcamera::formats::SGBRG10_CSI2P: + case libcamera::formats::SGRBG10_CSI2P: + case libcamera::formats::SRGGB10_CSI2P: + egl_.pushEnv(shaderEnv, "#define RAW10P"); + if (BayerFormat::fromPixelFormat(inputFormat).packing == BayerFormat::Packing::None) { + fragmentShaderData = bayer_unpacked_frag; + fragmentShaderDataLen = bayer_unpacked_frag_len; + vertexShaderData = bayer_unpacked_vert; + vertexShaderDataLen = bayer_unpacked_vert_len; + glFormat_ = GL_RG; + bytesPerPixel_ = 2; + } else { + fragmentShaderData = bayer_1x_packed_frag; + fragmentShaderDataLen = bayer_1x_packed_frag_len; + vertexShaderData = identity_vert; + vertexShaderDataLen = identity_vert_len; + shaderStridePixels_ = width_; + } + break; + case libcamera::formats::SBGGR12_CSI2P: + case libcamera::formats::SGBRG12_CSI2P: + case libcamera::formats::SGRBG12_CSI2P: + case libcamera::formats::SRGGB12_CSI2P: + egl_.pushEnv(shaderEnv, "#define RAW12P"); + if (BayerFormat::fromPixelFormat(inputFormat).packing == BayerFormat::Packing::None) { + fragmentShaderData = bayer_unpacked_frag; + fragmentShaderDataLen = bayer_unpacked_frag_len; + vertexShaderData = bayer_unpacked_vert; + vertexShaderDataLen = bayer_unpacked_vert_len; + glFormat_ = GL_RG; + bytesPerPixel_ = 2; + } else { + fragmentShaderData = bayer_1x_packed_frag; + fragmentShaderDataLen = bayer_1x_packed_frag_len; + vertexShaderData = identity_vert; + vertexShaderDataLen = identity_vert_len; + shaderStridePixels_ = width_; + } + break; + default: + goto invalid_fmt; + break; + }; + + if (egl_.compileVertexShader(vertexShaderId_, vertexShaderData, vertexShaderDataLen, shaderEnv)) + goto compile_fail; + + if (egl_.compileFragmentShader(fragmentShaderId_, fragmentShaderData, fragmentShaderDataLen, shaderEnv)) + goto compile_fail; + + if (egl_.linkProgram(programId_, vertexShaderId_, fragmentShaderId_)) + goto link_fail; + + egl_.dumpShaderSource(vertexShaderId_); + egl_.dumpShaderSource(fragmentShaderId_); + + /* Ensure we set the programId_ */ + egl_.useProgram(programId_); + err = glGetError(); + if (err != GL_NO_ERROR) + goto program_fail; + + if (getShaderVariableLocations()) + goto parameters_fail; + + return 0; + +parameters_fail: + LOG(Debayer, Error) << "Program parameters fail"; + return -ENODEV; + +program_fail: + LOG(Debayer, Error) << "Use program error " << err; + return -ENODEV; + +link_fail: + LOG(Debayer, Error) << "Linking program fail"; + return -ENODEV; + +compile_fail: + LOG(Debayer, Error) << "Compile debayer shaders fail"; + return -ENODEV; + +invalid_fmt: + LOG(Debayer, Error) << "Unsupported input output format combination"; + return -EINVAL; +} + +/** + * \brief Get the output frame size + * + * \return The output frame size + */ +unsigned int DebayerEGL::frameSize() +{ + return outputConfig_.frameSize; +} + +int DebayerEGL::configure(const StreamConfiguration &inputCfg, + const std::vector> &outputCfgs, + bool ccmEnabled) +{ + if (getInputConfig(inputCfg.pixelFormat, inputConfig_) != 0) + return -EINVAL; + + if (stats_->configure(inputCfg) != 0) + return -EINVAL; + + if (!ccmEnabled) + return -EINVAL; + + const Size &stats_pattern_size = stats_->patternSize(); + if (inputConfig_.patternSize.width != stats_pattern_size.width || + inputConfig_.patternSize.height != stats_pattern_size.height) { + LOG(Debayer, Error) + << "mismatching stats and debayer pattern sizes for " + << inputCfg.pixelFormat.toString(); + return -EINVAL; + } + + inputConfig_.stride = inputCfg.stride; + inputPixelFormat_ = inputCfg.pixelFormat; + width_ = inputCfg.size.width; + height_ = inputCfg.size.height; + + if (outputCfgs.size() != 1) { + LOG(Debayer, Error) + << "Unsupported number of output streams: " + << outputCfgs.size(); + return -EINVAL; + } + + StreamConfiguration &outputCfg = outputCfgs[0]; + SizeRange outSizeRange = sizes(inputCfg.pixelFormat, inputCfg.size); + std::tie(outputConfig_.stride, outputConfig_.frameSize) = + strideAndFrameSize(outputCfg.pixelFormat, outputCfg.size); + + if (!outSizeRange.contains(outputCfg.size) || outputConfig_.stride != outputCfg.stride) { + LOG(Debayer, Error) + << "Invalid output size/stride: " + << "\n " << outputCfg.size << " (" << outSizeRange << ")" + << "\n " << outputCfg.stride << " (" << outputConfig_.stride << ")"; + return -EINVAL; + } + + outputPixelFormat_ = outputCfg.pixelFormat; + outputSize_ = outputCfg.size; + + window_.x = ((inputCfg.size.width - outputCfg.size.width) / 2) & + ~(inputConfig_.patternSize.width - 1); + window_.y = ((inputCfg.size.height - outputCfg.size.height) / 2) & + ~(inputConfig_.patternSize.height - 1); + window_.width = outputCfg.size.width; + window_.height = outputCfg.size.height; + + /* + * Don't pass x,y from window_ since process() already adjusts for it. + * But crop the window to 2/3 of its width and height for speedup. + */ + stats_->setWindow(Rectangle(window_.size())); + + return 0; +} + +Size DebayerEGL::patternSize(PixelFormat inputFormat) +{ + DebayerEGL::DebayerInputConfig config; + + if (getInputConfig(inputFormat, config) != 0) + return {}; + + return config.patternSize; +} + +std::vector DebayerEGL::formats(PixelFormat inputFormat) +{ + DebayerEGL::DebayerInputConfig config; + + if (getInputConfig(inputFormat, config) != 0) + return std::vector(); + + return config.outputFormats; +} + +std::tuple +DebayerEGL::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) +{ + DebayerEGL::DebayerOutputConfig config; + + if (getOutputConfig(outputFormat, config) != 0) + return std::make_tuple(0, 0); + + /* Align stride to 256 bytes as a generic GPU memory access alignment */ + unsigned int stride = libcamera::utils::alignUp(size.width * config.bpp / 8, 256); + + return std::make_tuple(stride, stride * size.height); +} + +void DebayerEGL::setShaderVariableValues(DebayerParams ¶ms) +{ + /* + * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats + * are stored in a GL_LUMINANCE texture. The texture width is + * equal to the stride. + */ + GLfloat firstRed[] = { firstRed_x_, firstRed_y_ }; + GLfloat imgSize[] = { (GLfloat)width_, + (GLfloat)height_ }; + GLfloat Step[] = { static_cast(bytesPerPixel_) / (inputConfig_.stride - 1), + 1.0f / (height_ - 1) }; + GLfloat Stride = (GLfloat)width_ / (shaderStridePixels_ / bytesPerPixel_); + /* + * Scale input to output size, keeping the aspect ratio and preferring + * cropping over black bars. + */ + GLfloat scale = std::max((GLfloat)window_.width / width_, + (GLfloat)window_.height / height_); + GLfloat trans = -(1.0f - scale); + GLfloat projMatrix[] = { + scale, 0, 0, 0, + 0, scale, 0, 0, + 0, 0, 1, 0, + trans, trans, 0, 1 + }; + + /* vertexIn - bayer_8.vert */ + glEnableVertexAttribArray(attributeVertex_); + glVertexAttribPointer(attributeVertex_, 2, GL_FLOAT, GL_TRUE, + 2 * sizeof(GLfloat), vcoordinates); + + /* textureIn - bayer_8.vert */ + glEnableVertexAttribArray(attributeTexture_); + glVertexAttribPointer(attributeTexture_, 2, GL_FLOAT, GL_TRUE, + 2 * sizeof(GLfloat), tcoordinates); + + /* + * Set the sampler2D to the respective texture unit for each texutre + * To simultaneously sample multiple textures we need to use multiple + * texture units + */ + glUniform1i(textureUniformBayerDataIn_, eglImageBayerIn_->texture_unit_uniform_id_); + + /* + * These values are: + * firstRed = tex_bayer_first_red - bayer_8.vert + * imgSize = tex_size - bayer_8.vert + * step = tex_step - bayer_8.vert + * Stride = stride_factor identity.vert + * textureUniformProjMatri = No scaling + */ + glUniform2fv(textureUniformBayerFirstRed_, 1, firstRed); + glUniform2fv(textureUniformSize_, 1, imgSize); + glUniform2fv(textureUniformStep_, 1, Step); + glUniform1f(textureUniformStrideFactor_, Stride); + glUniformMatrix4fv(textureUniformProjMatrix_, 1, GL_FALSE, projMatrix); + + LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ + << " tex_y " << textureUniformBayerDataIn_ + << " tex_step " << textureUniformStep_ + << " tex_size " << textureUniformSize_ + << " stride_factor " << textureUniformStrideFactor_ + << " tex_bayer_first_red " << textureUniformBayerFirstRed_; + + LOG(Debayer, Debug) << "textureUniformY_ = 0 " + << " firstRed.x " << firstRed[0] + << " firstRed.y " << firstRed[1] + << " textureUniformSize_.width " << imgSize[0] + << " textureUniformSize_.height " << imgSize[1] + << " textureUniformStep_.x " << Step[0] + << " textureUniformStep_.y " << Step[1] + << " textureUniformStrideFactor_ " << Stride + << " textureUniformProjMatrix_ " << textureUniformProjMatrix_; + + GLfloat ccm[9] = { + params.ccm[0][0], + params.ccm[0][1], + params.ccm[0][2], + params.ccm[1][0], + params.ccm[1][1], + params.ccm[1][2], + params.ccm[2][0], + params.ccm[2][1], + params.ccm[2][2], + }; + glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); + LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.ccm; + + /* + * 0 = Red, 1 = Green, 2 = Blue + */ + glUniform3f(blackLevelUniformDataIn_, params.blackLevel[0], params.blackLevel[1], params.blackLevel[2]); + LOG(Debayer, Debug) << " blackLevelUniformDataIn_ " << blackLevelUniformDataIn_ << " data " << params.blackLevel; + + /* + * Gamma + */ + glUniform1f(gammaUniformDataIn_, params.gamma); + LOG(Debayer, Debug) << " gammaUniformDataIn_ " << gammaUniformDataIn_ << " data " << params.gamma; + + /* + * Contrast + */ + glUniform1f(contrastUniformDataIn_, params.contrast); + LOG(Debayer, Debug) << " contrastUniformDataIn_ " << contrastUniformDataIn_ << " data " << params.contrast; + + return; +} + +int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams ¶ms) +{ + /* eGL context switch */ + egl_.makeCurrent(); + + /* Create a standard texture input */ + egl_.createTexture2D(eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data()); + + /* Generate the output render framebuffer as render to texture */ + egl_.createOutputDMABufTexture2D(eglImageBayerOut_, out_fd); + + setShaderVariableValues(params); + glViewport(0, 0, width_, height_); + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_FAN, 0, DEBAYER_OPENGL_COORDS); + + GLenum err = glGetError(); + if (err != GL_NO_ERROR) { + LOG(eGL, Error) << "Drawing scene fail " << err; + return -ENODEV; + } else { + egl_.syncOutput(); + } + + return 0; +} + +void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params) +{ + bench_.startFrame(); + + std::vector dmaSyncers; + + dmaSyncBegin(dmaSyncers, input, nullptr); + + setParams(params); + + /* Copy metadata from the input buffer */ + FrameMetadata &metadata = output->_d()->metadata(); + metadata.status = input->metadata().status; + metadata.sequence = input->metadata().sequence; + metadata.timestamp = input->metadata().timestamp; + + MappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read); + if (!in.isValid()) { + LOG(Debayer, Error) << "mmap-ing buffer(s) failed"; + goto error; + } + + if (debayerGPU(in, output->planes()[0].fd.get(), params)) { + LOG(Debayer, Error) << "debayerGPU failed"; + goto error; + } + + bench_.finishFrame(); + + metadata.planes()[0].bytesused = output->planes()[0].length; + + /* Calculate stats for the whole frame */ + stats_->processFrame(frame, 0, input); + dmaSyncers.clear(); + + outputBufferReady.emit(output); + inputBufferReady.emit(input); + + return; + +error: + bench_.finishFrame(); + metadata.status = FrameMetadata::FrameError; + return; +} + +int DebayerEGL::start() +{ + GLint maxTextureImageUnits; + + if (gbmSurface_.createDevice()) + return -ENODEV; + + if (egl_.initEGLContext(&gbmSurface_)) + return -ENODEV; + + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits); + + LOG(Debayer, Debug) << "Available fragment shader texture units " << maxTextureImageUnits; + + /* Raw bayer input as texture */ + eglImageBayerIn_ = std::make_unique(width_, height_, 32, inputConfig_.stride, GL_TEXTURE0, 0); + + /* Texture we will render to */ + eglImageBayerOut_ = std::make_unique(outputSize_.width, outputSize_.height, 31, outputConfig_.stride, GL_TEXTURE1, 1); + + if (initBayerShaders(inputPixelFormat_, outputPixelFormat_)) + return -EINVAL; + + return 0; +} + +void DebayerEGL::stop() +{ + eglImageBayerOut_.release(); + eglImageBayerIn_.release(); + + egl_.cleanUp(); +} + +SizeRange DebayerEGL::sizes(PixelFormat inputFormat, const Size &inputSize) +{ + Size patternSize = this->patternSize(inputFormat); + unsigned int borderHeight = patternSize.height; + + if (patternSize.isNull()) + return {}; + + /* No need for top/bottom border with a pattern height of 2 */ + if (patternSize.height == 2) + borderHeight = 0; + + /* + * For debayer interpolation a border is kept around the entire image + * and the minimum output size is pattern-height x pattern-width. + */ + if (inputSize.width < (3 * patternSize.width) || + inputSize.height < (2 * borderHeight + patternSize.height)) { + LOG(Debayer, Warning) + << "Input format size too small: " << inputSize.toString(); + return {}; + } + + return SizeRange(Size(patternSize.width, patternSize.height), + Size((inputSize.width - 2 * patternSize.width) & ~(patternSize.width - 1), + (inputSize.height - 2 * borderHeight) & ~(patternSize.height - 1)), + patternSize.width, patternSize.height); +} + +} /* namespace libcamera */ diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h new file mode 100644 index 000000000..c0a68fd35 --- /dev/null +++ b/src/libcamera/software_isp/debayer_egl.h @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Bryan O'Donoghue. + * + * Authors: + * Bryan O'Donoghue + * + */ + +#pragma once + +#include +#include +#include + +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#include + +#include "libcamera/internal/bayer_format.h" +#include "libcamera/internal/egl.h" +#include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/mapped_framebuffer.h" +#include "libcamera/internal/software_isp/benchmark.h" +#include "libcamera/internal/software_isp/swstats_cpu.h" + +#include +#include +#include + +#include "debayer.h" + +namespace libcamera { + +#define DEBAYER_EGL_MIN_SIMPLE_RGB_GAIN_TEXTURE_UNITS 4 +#define DEBAYER_OPENGL_COORDS 4 + +class DebayerEGL : public Debayer +{ +public: + DebayerEGL(std::unique_ptr stats, const GlobalConfiguration &configuration); + ~DebayerEGL(); + + int configure(const StreamConfiguration &inputCfg, + const std::vector> &outputCfgs, + bool ccmEnabled); + + Size patternSize(PixelFormat inputFormat); + + std::vector formats(PixelFormat input); + std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size); + + void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params); + int start(); + void stop(); + + const SharedFD &getStatsFD() { return stats_->getStatsFD(); } + unsigned int frameSize(); + + SizeRange sizes(PixelFormat inputFormat, const Size &inputSize); + +private: + static int getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config); + static int getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config); + int setupStandardBayerOrder(BayerFormat::Order order); + void pushEnv(std::vector &shaderEnv, const char *str); + int initBayerShaders(PixelFormat inputFormat, PixelFormat outputFormat); + int initEGLContext(); + int generateTextures(); + int compileShaderProgram(GLuint &shaderId, GLenum shaderType, + unsigned char *shaderData, int shaderDataLen, + std::vector shaderEnv); + int linkShaderProgram(void); + int getShaderVariableLocations(); + void setShaderVariableValues(DebayerParams ¶ms); + void configureTexture(GLuint &texture); + int debayerGPU(MappedFrameBuffer &in, int out_fd, DebayerParams ¶ms); + + /* Shader program identifiers */ + GLuint vertexShaderId_; + GLuint fragmentShaderId_; + GLuint programId_; + enum { + BAYER_INPUT_INDEX = 0, + BAYER_OUTPUT_INDEX, + BAYER_BUF_NUM, + }; + + /* Pointer to object representing input texture */ + std::unique_ptr eglImageBayerIn_; + std::unique_ptr eglImageBayerOut_; + + /* Shader parameters */ + float firstRed_x_; + float firstRed_y_; + GLint attributeVertex_; + GLint attributeTexture_; + GLint textureUniformStep_; + GLint textureUniformSize_; + GLint textureUniformStrideFactor_; + GLint textureUniformBayerFirstRed_; + GLint textureUniformProjMatrix_; + + GLint textureUniformBayerDataIn_; + + /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ + GLint ccmUniformDataIn_; + + /* Black Level compensation */ + GLint blackLevelUniformDataIn_; + + /* Gamma */ + GLint gammaUniformDataIn_; + + /* Contrast */ + GLint contrastUniformDataIn_; + + Rectangle window_; + std::unique_ptr stats_; + eGL egl_; + GBM gbmSurface_; + uint32_t width_; + uint32_t height_; + GLint glFormat_; + unsigned int bytesPerPixel_; + uint32_t shaderStridePixels_; + GLfloat vcoordinates[DEBAYER_OPENGL_COORDS][2] = { + { -1.0f, -1.0f }, + { -1.0f, +1.0f }, + { +1.0f, +1.0f }, + { +1.0f, -1.0f }, + }; + GLfloat tcoordinates[DEBAYER_OPENGL_COORDS][2] = { + { 0.0f, 0.0f }, + { 0.0f, 1.0f }, + { 1.0f, 1.0f }, + { 1.0f, 0.0f }, + }; +}; + +} /* namespace libcamera */ diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build index 59fa5f02a..c61ac7d59 100644 --- a/src/libcamera/software_isp/meson.build +++ b/src/libcamera/software_isp/meson.build @@ -2,6 +2,7 @@ softisp_enabled = pipelines.contains('simple') summary({'SoftISP support' : softisp_enabled}, section : 'Configuration') +summary({'SoftISP GPU acceleration' : gles_headless_enabled}, section : 'Configuration') if not softisp_enabled subdir_done() @@ -14,3 +15,10 @@ libcamera_internal_sources += files([ 'software_isp.cpp', 'swstats_cpu.cpp', ]) + +if softisp_enabled and gles_headless_enabled + config_h.set('HAVE_DEBAYER_EGL', 1) + libcamera_internal_sources += files([ + 'debayer_egl.cpp', + ]) +endif From patchwork Wed Dec 17 10:01:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25588 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 BA769C32E7 for ; Wed, 17 Dec 2025 10:02:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 111AE61F4F; Wed, 17 Dec 2025 11:02:17 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="I+rdohQh"; dkim-atps=neutral Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AB1AC61A37 for ; Wed, 17 Dec 2025 11:02:01 +0100 (CET) Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-47bdbc90dcaso5943375e9.1 for ; Wed, 17 Dec 2025 02:02:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965721; x=1766570521; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BO0mMIWhB901RhyMhEcHbc+LWlQiOyKCJvDrt0v6kXI=; b=I+rdohQhnb48j5GwtDjHGq5C04i2iS+y5oGcPRnjdghDRLhNiWbL5zHQyWH/gMMhxp dRmFtaURy8dj6Qxg0km9H+kVlW9x6C3IADOglE8bXXXShryjM40/060wwc19sYOrFJ1/ +lk3jTSqnvzLIJEPtubQkvOeINXQvy1YIDkFLS+jsKdL6nvNbY8yRG2sRbb8mvvAJMvk 8fV61PB+DqtoAwlJDr7pIYQTAPH4oziRXemZzmGtGnllzzjC5hFWx6ej/zVxPYnKkCRX O7oVTxgpv5lsanLHJJJQybCce9RS07c397qGpVnlt+5d5nyqY0M7oxWLK3jIaDe2RIFT gWpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965721; x=1766570521; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=BO0mMIWhB901RhyMhEcHbc+LWlQiOyKCJvDrt0v6kXI=; b=A9Y3rwSpg1nM5OanpvMPPH+wJZdsamKpQVlBpiLn2P8+a0pq7bueXdkT+B9Rc0iBWA SFYZkFK6YPJ6fX4L6Qf+wY9g/3Ry6g9/SlNP+FdQ4Urvz7aNPMZysSnzNpwbyzlet4UO IpmcP8JuoiNjUphcBdcNJafasp2vMgkQ2F3e2iGAMqethnEGGC7KGh2Wy1hIwHxf4j9a TCB7fx6PEI5l+RSd/SAKXofECk8UuCyfqlBe36gX4qWX4bk7Uh4u5yMSlH8Dlj3lIkHW jPPerafqXlyUzt42CvEmMgCehtmJ5XbN5HhNy97IfVERJEXn/mGv0yOQVcL0dbRvYVtf vYCQ== X-Gm-Message-State: AOJu0Yx+LH8Wv5hgch4BdGEI7KExNOP/vOlDQaKXFl5ONNxDx1npLTny 3fBA4uGKCq10ZjZiE9NTcHnVf69M3nBnt0+zAXBJxhKu+dJ6QeW/UyvWiudm2YMVRaVaeRJVyvY OZpD/ X-Gm-Gg: AY/fxX5suHXjaaUhuw0UXAYsj17a7jXbyTFbmj9+w+hMJxP55sMKObjemGvX2b9tvPr +r10Iwol904gcthPdBW7GXNdPcOuGrImB8KgM77aRRldR3onmAZHZ43m4/tDsSYEX4kXY35cHOe R11vAq4iaFjcYqrsQLBqzSwGJCwusxvTvPZVtB0AYb0v20ACiUah3zoCE0XXeBqP2P4XEsUXkPY y5q83m4yu70yfuuiZYBNszkUWc0GxeQKKxqwLVEqbr6OitVdXwqF+yO2/Ei60Qz61OhthP8WoBb tuDIZYk7ZxlFOI43ZwTVpaDEhDZfBBENAr5MVFvE9EEUE07awsIiaLzjul+yk8AqtDH5yqCkEjI DUJQgbiKBuUlfYS4Ug/gNWtYj8Gy4svQMtSwoDUyqRx9XrBlfKyiocBggRCfxQ2Zro/IrIS0Rm+ tLzo6A97vGOytQakk7st4agYsD1ZHDpD3MAvCe+iqqvSeI9vR0GvxZAjk09Iqgl2+YCdM= X-Google-Smtp-Source: AGHT+IEuHVIjI3uI49LaFagDFH6IbZnPoRCd1fUpWHaX48z5VVUNeM7pDMgn2HPO5dhJ0Btva/ZifQ== X-Received: by 2002:a05:600c:8288:b0:477:a1a2:d829 with SMTP id 5b1f17b1804b1-47a8f8c0caamr165081045e9.13.1765965720968; Wed, 17 Dec 2025 02:02:00 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:00 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Kieran Bingham , Milan Zamazal Subject: [PATCH v9 15/26] libcamera: software_isp: debayer_cpu: Make getInputConfig and getOutputConfig static Date: Wed, 17 Dec 2025 10:01:27 +0000 Message-ID: <20251217100138.82525-16-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Make getInputConfig and getOutputConfig static so as to allow for interrogation of the supported pixel formats prior to object instantiation. Do this so as to allow the higher level logic make an informed choice between CPU and GPU ISP based on which pixel formats are supported. Currently CPU ISP supports more diverse input and output schemes. Acked-by: Kieran Bingham Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/software_isp/debayer_cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index ecc4f9dd0..67df2b93a 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -97,8 +97,8 @@ private: template void debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]); - int getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config); - int getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config); + static int getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config); + static int getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config); int setupStandardBayerOrder(BayerFormat::Order order); int setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat, From patchwork Wed Dec 17 10:01:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25589 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 F2430C32EA for ; Wed, 17 Dec 2025 10:02:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1403F61D61; Wed, 17 Dec 2025 11:02:18 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="iFVwTFfS"; dkim-atps=neutral Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 459ED61A5D for ; Wed, 17 Dec 2025 11:02:03 +0100 (CET) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-47a80d4a065so34399635e9.2 for ; Wed, 17 Dec 2025 02:02:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965722; x=1766570522; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=HhtFnWRlGMhahKWMF7YUw5HWUh4rGouum/Sd9bsme4c=; b=iFVwTFfSrDszGMjEhPZre7AzEyoln26S0l8+1hIy9vSeXi2iFdz02XnTJYqfVBIlrY 7Ts7k8jzFtr/6g/dOrHVS+F31YSVmlNV83xgBdG7jZi5ESI1rBhwnT59iF68FM1P49X7 Dd6nNtI//SvK6APQk1o1XQZjbmg8b1WLE5PIwkf3zAA4ReqdIsCApzmO5UjFr/5Khat5 zR5X6Y1Z8GdOSRpMC+X18lTxCyRvtUF/dX3kSGrIEV5A8T811rmskFQx1gVwNsLhKKXq SmcsHMG5qj3OQgjAjSg0gkCCvuH5PbTGrWudZNkoDMqqaII5joJcJwTRSb1X3YIUnoq7 e3Mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965722; x=1766570522; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=HhtFnWRlGMhahKWMF7YUw5HWUh4rGouum/Sd9bsme4c=; b=k+KHcEK4+woYbr5a3LMMuuhbO8M5xNFLmpmNRvaChxiD2TLPKT2sYf+hrk5Rat3Q9H CicPHNNr2TxX3097nE7UFK0xio2WBIDobVsFP9nHaC7fZ2WVlQbzpasvnEdXVRAjIrFd YFE50rLkWBVOXpokvjKRMMj9RtJYx4E7ArIGGcop/nVLN6YabdMefFrL9h8loBUti+u2 ZRAq+ZQyqeWR22IBf9CMze+/4NYFS2TE7+aMzkdKsY/qneQas2bkHWFoc/AVV6erx8xu FE/s/zp1hi18/xO4ZILRl6bxw/2h9g/EGI0mrsR+NjHgSJJYjt5+8JW/21LAEb8sHQiz YF7g== X-Gm-Message-State: AOJu0Yxo+uyQm2sVa620xClqsCC7WkP1XxOHj8cQQIXutYMubkYbZR2/ nqARecQYyFprztf54F5+pfcDmcHGCLj2JphobI+kOKc5Mhj7dZelhZ16SHCGLGqQd+gyMtmUOlk GZL7B X-Gm-Gg: AY/fxX5fAUYWTk9w8LfNaUjQLR1nfnK6UzOMfRs+cTNbWfaG8OnxPZmW9ewwsqv9rey LQcmCfC+sI2hq8T95wOtQFVv80ezqD3Ax9rgpaCiaTeHKpsZ7cbFI350U7SGR1knJRrNaZ+fLTl 6NvxOx57AG3fbCPHBBZ4zZji1dZUfgRH4wQUKJHY99PjyjtOhxKaZSI2Y91T/fhqVupdMuwohKt o0IgL5dArFHvbeRrXKQeaXTANRE900aDaI81wI9XN0M+jI+zq8grN+kf+dBdPeyYzWfK7TIBSAf mi03PPv3G1IUChtG4sSVA+/KRlXivvkKqBNnS8LWyCmrXztQjG0SlTd3S539RxhXPpGxsj25fFD 7mRc8Zznjja5ehjI5aINi/pI+hIbSSj4zwQME/hMr7tfciCeedSBeYFspCoxliVgEHNix034zSj qH9Ff9kDYEqHghjp52CuMPO+NY+UALqRXq+AVTnCkVZpHrZWvtrwyIm0ePArYRN4jbs1M= X-Google-Smtp-Source: AGHT+IG+MBWNlnyRkWB6WvCtr/mb9eU2Pi5slwFy2nlm3x5eGfGYuNmDVHK/Sd6Tca6h9a/kLjzkqg== X-Received: by 2002:a05:600c:4e4c:b0:471:114e:5894 with SMTP id 5b1f17b1804b1-47a8f90da04mr188513975e9.25.1765965722478; Wed, 17 Dec 2025 02:02:02 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:02 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Milan Zamazal , Bryan O'Donoghue Subject: [PATCH v9 16/26] libcamera: software_isp: GPU support for unpacked 10/12-bit formats Date: Wed, 17 Dec 2025 10:01:28 +0000 Message-ID: <20251217100138.82525-17-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" From: Milan Zamazal The GPU processing supports 8-bit sensor formats and 10/12-bit packed formats. Support for 10/12-bit unpacked formats is missing, let's add it. 10/12-bit unpacked formats use two adjacent bytes to store the value. This means the 8-bit shaders can be used if we can modify them for additional support of 16-bit addressing. This requires the following modifications: - Using GL_RG (two bytes per pixel) instead of GL_LUMINANCE (one byte per pixel) as the texture format for the given input formats. - Setting the texture width to the number of pixels rather than the number of bytes. - Making the definition of `fetch' macro variable, according to the pixel format. - Using only `fetch' for accessing the texture. Signed-off-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue Reviewed-by: Hans de Goede --- src/libcamera/shaders/bayer_unpacked.frag | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag index 114e32058..477e8bbf6 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -41,9 +41,17 @@ float apply_contrast(float value, float contrastExp) void main(void) { vec3 rgb; + #if defined(RAW10P) + #define pixel(p) p.r / 4.0 + p.g * 64.0 + #define fetch(x, y) pixel(texture2D(tex_y, vec2(x, y))) + #elif defined(RAW12P) + #define pixel(p) p.r / 16.0 + p.g * 16.0 + #define fetch(x, y) pixel(texture2D(tex_y, vec2(x, y))) + #else #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r + #endif - float C = texture2D(tex_y, center.xy).r; // ( 0, 0) + float C = fetch(center.x, center.y); // ( 0, 0) const vec4 kC = vec4( 4.0, 6.0, 5.0, 5.0) / 8.0; // Determine which of four types of pixels we are on. From patchwork Wed Dec 17 10:01:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25590 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 45729C32EF for ; Wed, 17 Dec 2025 10:02:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9BB6B61F58; Wed, 17 Dec 2025 11:02:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="DbRcZJ3v"; dkim-atps=neutral Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2138B61A4B for ; Wed, 17 Dec 2025 11:02:04 +0100 (CET) Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-47774d3536dso3950785e9.0 for ; Wed, 17 Dec 2025 02:02:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965723; x=1766570523; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qveDztGD+z1bcvRVfeWU9FTU1qkHWCGGVTIxAh2VXQw=; b=DbRcZJ3vQ+KDfW17o2Y2Jurn7GKo2iQl1vtOqNeC8SBw/5RB9+LJh+hmtpOCcXnhZI n7SzTXrhQHbOHeFIQ4M91wEAXVtnh2W+5tph/yh+MAtZaEUrRXaY1WkcjMCp79EnyRMx HAGmx/BZ8a5/aJBJ8OhbUBie1zZdYbJryzZZADzDrP2JQVaEMqrzMzdANZ2+iwppM8gM JWi0/8SHCPvu7FmWNndGhWs6XJSlghQBCfRKEJnfEFEIv/c7ChNZTICCvQTGycjX+4kz fvSqJefZa7gSW/Af7ojVtalnaBTxoY94GmXKlUNZY/4W+8+oz8ag7M3ULRrREFmE+z52 uVgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965723; x=1766570523; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qveDztGD+z1bcvRVfeWU9FTU1qkHWCGGVTIxAh2VXQw=; b=q/PvIf2Km1SqLEtp+RYHRmqQq33p97F7BA08aM+w5yCJYDq1FhP8tX/8s4qPnK01SX qhm5kiHxwmJLqy1XvzoPhnd5C06bKRiCwntUXolGeswhJGyH1PdUEpnFOK0fJ5NCyJL6 hf2oWacWTCPDrS5pRWft5T1V4wjARfOrxJGETKQWnzYYXN0LPFWWzJcWfOH7FAS1Dpb7 J0Ab8RJw+vkCzPrSJIl/qhe6gK3GMY+gqaA3mlrEIE7tGCw19BEqSDUkBgmbfpdBtUqz 2M8365yVqy/I/1Aq/rP18FoyujTITFczKodOvIGWxLVRPCPIIwU42wjgL51Y4LMBE77t DGYw== X-Gm-Message-State: AOJu0Yz8XdRyapu2t4/fOY2EsmSRndpzWCs3tniXxiG6dqjbX5YW38q8 UYewGkK2aGQ66mUxE2MeQqIx6ajx/5WTU5R5JiPD1cCMpLzzyNrbaVYxsUDtv7lTnAlFz4UG0h1 eq2GK X-Gm-Gg: AY/fxX5y/9XoIuP0lpFPmZV+FwtxtLvo7oPwUSuuFrE4GytPRPATFI72RlkY8vtSxpB QOYzvtLnpsPA89bmiw4BNx5xFZEw/zYeiw/LCMmV3tgGhd0eLyWFsx5S+v5bFwORVLWCs2UVn9X XXrvcNvjywzkOE7VTksWhfxmALmFBU9z1f9VlI5cwrf8YcFZMMSE2yD5bqUdhRDSnx0kd+689fZ NtZKJTdlFFTLKbE08GNEwxI/rbvEqo5hvZXDLAh7w9ISBkNICncJoNt/Huw5z0i/R95z9QwQf4h O0dtCAdhwrfU0Htg6bVOfqUQbr7lxp7i3RmVhCyt0hLSeTzt399+zBQkuDZu3+7IwylBTB/wrMy MekhAgf5x+YLxJKFqK6keESSXMekwNJ34YwrYZanCRq3q5RBcizPgmBA0UOYSqYBS3s7A9zqLWF OGCuKL/rdGgvIqLsJnB+iDgomrIwa7ZYcZyk/VJaRCqToTR3bozIovwvnlNaixcmaEdQI= X-Google-Smtp-Source: AGHT+IEUBa+i2kNjTRIKWAJTv5314mgvVfudrWtUIH+OvUhYIbJwT+NoP6DLUlLjphEXBSarAPqaKw== X-Received: by 2002:a05:600c:3ba3:b0:477:a219:cdc3 with SMTP id 5b1f17b1804b1-47a8f1c33c5mr212046055e9.12.1765965723387; Wed, 17 Dec 2025 02:02:03 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:02 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 17/26] libcamera: software_isp: debayer_egl: Make DebayerEGL an environment option Date: Wed, 17 Dec 2025 10:01:29 +0000 Message-ID: <20251217100138.82525-18-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" If GPUISP support is available make it so an environment variable can switch it on. Given we don't have full feature parity with CPUISP just yet on pixel format output, we should default to CPUISP mode giving the user the option to switch on GPUISP by setting LIBCAMERA_SOFTISP_MODE=gpu Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/software_isp/software_isp.cpp | 24 ++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index b31a374d8..efe44e393 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -25,6 +26,9 @@ #include "libcamera/internal/software_isp/debayer_params.h" #include "debayer_cpu.h" +#if HAVE_DEBAYER_EGL +#include "debayer_egl.h" +#endif /** * \file software_isp.cpp @@ -117,7 +121,25 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, } stats->statsReady.connect(this, &SoftwareIsp::statsReady); - debayer_ = std::make_unique(std::move(stats), configuration); +#if HAVE_DEBAYER_EGL + std::optional softISPMode = configuration.envOption("LIBCAMERA_SOFTISP_MODE", { "software_isp", "mode" }); + + if (softISPMode && softISPMode == "gpu") { + debayer_ = std::make_unique(std::move(stats), configuration); + if (!debayer_) { + LOG(SoftwareIsp, Error) << "Failed to instantiate GPUISP"; + return; + } + } +#endif + if (!debayer_) + debayer_ = std::make_unique(std::move(stats), configuration); + + if (!debayer_) { + LOG(SoftwareIsp, Error) << "Failed to create Debayer object"; + return; + } + debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady); debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady); From patchwork Wed Dec 17 10:01:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25591 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 0060EC3274 for ; Wed, 17 Dec 2025 10:02:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8AE3561E53; Wed, 17 Dec 2025 11:02:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="SmZJR3xo"; dkim-atps=neutral Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 68FAD61D25 for ; Wed, 17 Dec 2025 11:02:05 +0100 (CET) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-47775fb6c56so43866705e9.1 for ; Wed, 17 Dec 2025 02:02:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965725; x=1766570525; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=enuSJNXFUuoTYs1Tq2LkRLCCtdszeCb+2wiWiBmGXZE=; b=SmZJR3xoP1ShFvmRMRhOrovj7zQtpz7iZEn/JQM2gXuM7jc9hkIHK2NEzM9OR9h6Gp HLJkA4yBPfEaGEmLFILd8d6blPUmQhiH84aD2j96Oa228bKpPGcMpio84IJjLDI4HzqN mNpTOem0+oMO0gASFQHCLlxfFnb0VI9k0ye5S+YTxbaVkp18UQjM0XnHB6XCtwv63FDN u9iGR4fSSKTVWHvWYxA5E9bwStvaJVpLi3WRib+gjEqWqfB0aflGYpYS6zg5I9J0Xm5C x8PjX4PyYl7nhbI/hY6htuRLJg+CVF5tXFdq/KJuRvH+lsXInlsiVPvE66QsxQyoJjUA dXUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965725; x=1766570525; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=enuSJNXFUuoTYs1Tq2LkRLCCtdszeCb+2wiWiBmGXZE=; b=edAMR/mpYbxpOmkSzM4X3Cza/OyWlv1oNU9LR+TFl40s31xvowfS/mTJ4oJvMZuPnq L+dMhZlK3r1Rt2anGXGizWBlMFB4diNNvzKfrdjpj7gaSVIV9aBIbW2PGxX2LjokAEmB bf31AS+Y7wEuV8DQJ8yG9BHjymO4oVHvAm74uY4WrLok4lBkoSDLFCfrbJbRwZ6/BhqF 6xs6C2VNyk7N53k6TjyX/LAz/gu6jO1bWR9kI5TLBb9hSqVW6bHcTAa0Tbb+0hke9qIw sAING9eoJeWofHh9+RGlDLAauAFHKiWrXO3pBuCCubtX/TVhXbNINGtNlxI+YoEdS07S JA0g== X-Gm-Message-State: AOJu0YyhsdLDSWVVbV+v3zAhVzdFzc4oLVbwbkAPNk2EoCoSIBFyb6Kw cmn0nTb7GZB/lfUiRqfC3DVxur7gPxlpmI6xyj1K6RtllMpFth1n1UJuazpN+ORimJHPtj95N+v ODcli X-Gm-Gg: AY/fxX7m5qiQ183/5/Lznag8/NBO7OL8eSu5WmhPARy4mcnoaZdF5RSOgmbKT5SyZ4e Ujkt15cnpY2EFXWFpQekqNBcSfukG2xHRbJ1ilgOsFWrHz6jvLE+tES7O1tJh5oAGpyC2Z+grgg W6EDifU8/Xskyebk89VrFsKWk5H28K+isrvr8CBmZtdx5zXRUj95QQ389UHyf+PP+5+An1Za1me 2Bx8H7sYGvQ4sxDxf95c7r8QoGepE992dqmlXPa/dTyDKglERZMYiSnZnULzNQ8Ry6oaZE01N/L yUYX523CfNs9EtxUgGsHC+4j9u1mB7lciGR9SFv4jOIOBO01DBbku67/A4/MQgkRnLkaWlxrdmN jwjWoAm8aFbgSJ0USRRppmSptb6uc+GMjGeu9o+jhUwXLssrpm8jntpJu8RU3m0DO4cA8Pfa0/Z klRjc26x2mK3ro8FebM1BF0SKL8lVAnWZxYBneoabVS/G4dcsWM1WXXCgRWqg7OcoJH1sEGimus PPyxw== X-Google-Smtp-Source: AGHT+IGIl6zDPcaMabha87p4zxnchXK2Md3KfugTXh6klJNVTsZH2VgWQOQ+SZkoU8GD8kuAlnM5mQ== X-Received: by 2002:a05:600c:4e56:b0:477:569c:34e9 with SMTP id 5b1f17b1804b1-47a8f906ddemr168578565e9.23.1765965724563; Wed, 17 Dec 2025 02:02:04 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:04 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 18/26] libcamera: software_isp: debayer_egl: Make gpuisp default softisp mode Date: Wed, 17 Dec 2025 10:01:30 +0000 Message-ID: <20251217100138.82525-19-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" In some cases the GPU can deliver 15x performance in Debayer with the CCM on, reference hardware Qualcomm RB5 with IMX512 sensor. Given this large performance difference it makes sense to make GPUISP the default for the Software ISP. If LIBCAMERA_SOFTISP_MODE is omitted gpu will be the default. If libcamera is compiled without gpuisp support, CPU Debayer will be used. It is still possible to select CPU mode with LIBCAMERA_SOFISP_MODE=cpu. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/software_isp/software_isp.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index efe44e393..7fde57aec 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -123,8 +123,15 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, #if HAVE_DEBAYER_EGL std::optional softISPMode = configuration.envOption("LIBCAMERA_SOFTISP_MODE", { "software_isp", "mode" }); + if (softISPMode) { + if (softISPMode != "gpu" && softISPMode != "cpu") { + LOG(SoftwareIsp, Error) << "LIBCAMERA_SOFISP_MODE " << softISPMode.value() << " invalid " + << "must be \"cpu\" or \"gpu\""; + return; + } + } - if (softISPMode && softISPMode == "gpu") { + if (!softISPMode || softISPMode == "gpu") { debayer_ = std::make_unique(std::move(stats), configuration); if (!debayer_) { LOG(SoftwareIsp, Error) << "Failed to instantiate GPUISP"; From patchwork Wed Dec 17 10:01:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25592 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 6D537C32F0 for ; Wed, 17 Dec 2025 10:02:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0E89161B0E; Wed, 17 Dec 2025 11:02:22 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="avbjOAZ4"; dkim-atps=neutral Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5CD0161EE6 for ; Wed, 17 Dec 2025 11:02:06 +0100 (CET) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-47775fb6cb4so39074095e9.0 for ; Wed, 17 Dec 2025 02:02:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965726; x=1766570526; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MPqMdgKkALoqu2kv8QWwW4WzZZNyfJxOyfa02dN1G2U=; b=avbjOAZ46CakfJ/V0uzCrRRm9ROxbjyp4lTHmrYMKte7V5vhuEmWhDycINiu93u1Y4 Mz+8f05sWi10OWKTfXRJ50t+hDt+pkR6Ny8vdB4SBcs66vT2ms8Vrz1RGHvgHLkyu9LQ GbRsZv/KBiSdsoCcMxt8gYEkvEuSTFUqaV3muxfSwOsl8xtN8qwbVFVfZejhp9Q7rJ+2 UswqTZsTuxMJhUEpcYmI+5BZy5PNXIBDQXa7ooLcLdxelbzm2aGE8Jl8aglG4KRCmm/I O4q0kylAY3TkiyHrw7NgvO5wDvEprdr/3EsqGfb5sy+wGKtLNOUM9r5DT/qAnjb/4VOD zA/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965726; x=1766570526; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=MPqMdgKkALoqu2kv8QWwW4WzZZNyfJxOyfa02dN1G2U=; b=I4f9C23EKzelCvMzZZNKff/cp5WSqt/2Elw5Nkdxf1zJR2Uq2DaS59Bht3WNjoObmp rah/eYRthVfs2ZC+XOhY4pmrF8npl1XtxQPTtunaQFbHuN1QIhq+SEyqD/AYPE7fuc57 1tdwVlLaosus6AdpGSTD196s4YTSRzfZS/IZlyDTQP2P6iVKsD2EycC53q4XvnOv0sFm ehZgXBLdLYgsSxjDECVZuQDL8bgP3p79/Ey/zvmKAreFZnJhNaRVITMWBRQYzm+S2qzM eOrKHXXRqbjqPOUi5CVx+Oly8uS1T8WMC2z6ovt+es2zJZPbns9as28sVdacEpOUt66q rPlg== X-Gm-Message-State: AOJu0Yzx22MMuAs90RFNbetrVVIe2lHOEFzQUiW1ZqLmB+srOjatOriZ REsQmL0kHVqucX8qQg6q7QZFFjYMs2SaH8c8YpwR43TXQIdLuKtn7e2UrliL0bO1pF+4hNIamif DHn9u X-Gm-Gg: AY/fxX5Ee3TLzee0qTGVUNYyLRJAbK7P0gExNfRVmu4nvDL3SXLAHLaCaum4PCLZREw bAJdfXdeUNohkN4hFzju6bXLrlKE78W7zIioURlgUkj6QmQEu79qcuw+Pv5Ql5jIwB+J8mfTfE+ Y0LKxTOrEeiODCAW2WW7o8KLzC3ySwG4upKC3pUUXRX697rGu0avg773S+nlf6mcHBrs/vEqC1u pVNZvc/IFhm5MzQO45QN2G/1UG3vzdtNoSGwyk/h+G+gXu1LkxxVFPw1NBKOyoeztJg9I93jQcb TB3M3pr61MFaPEobmfXZTCB7LFugkkPKPbaNcQ6virJSLO0KSgN7d2q9jmkvxfNd/uLhpOsLZyx qLQnrXAOi7lful6dgu5JjHgNBcqmLfpspqsyt5XRyQnRd/JAuH/eU/6tZ3xRII+M6uOrrzqsFHP 83UzJni55Le40fL5XJU1fzj83x42CDxWruJ9yIT9s41dH63npR9FQvpHO9YLRYjFKFOdo= X-Google-Smtp-Source: AGHT+IHihhjki/ltk0nAztTOe6HBA20k5HaZyyuLhYMK4OFHdCaHYpjMawqDB4/qzrtulNW8IHOaZw== X-Received: by 2002:a05:600c:3e06:b0:475:e007:baf1 with SMTP id 5b1f17b1804b1-47a8f916aeamr142941505e9.34.1765965725564; Wed, 17 Dec 2025 02:02:05 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:05 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 19/26] ipa: software_isp: Add a selfInitialising flag to IPAContext Date: Wed, 17 Dec 2025 10:01:31 +0000 Message-ID: <20251217100138.82525-20-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" This flag when true indicates that an algorithm should self-initialse instead of consuming YAML data. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/ipa/simple/ipa_context.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index c3081e306..03d8007ea 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -103,6 +103,7 @@ struct IPAContext { FCQueue frameContexts; ControlInfoMap::Map ctrlMap; bool ccmEnabled = false; + bool selfInitialising = false; }; } /* namespace ipa::soft */ From patchwork Wed Dec 17 10:01:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25593 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 19464C32AF for ; Wed, 17 Dec 2025 10:02:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B6B7561F5E; Wed, 17 Dec 2025 11:02:23 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="XKAtvUre"; dkim-atps=neutral Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A109B61F0A for ; Wed, 17 Dec 2025 11:02:07 +0100 (CET) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-477563e28a3so2283845e9.1 for ; Wed, 17 Dec 2025 02:02:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965727; x=1766570527; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zyb9LZ6PT/7D8hWeLG03useXOhMS8JpWGPj51LZZTbo=; b=XKAtvUre/ReoZY6GlKI6BcVXGYQ7aJukiLLF1+z/LPJiLdoEHjckC5Ww+O1rSlo0qW nvSpLtcRhA/tU/a4+f+L4P3Qpl4Q8UXppC9ggGFQ9BM+tdp4esTFI0DxwwBptvsG5TfE aFfwT9YuLwTbxlj9ZpMn7U3KiNVUjF7kiZ52OLwG1wsvZ62mWLgitMKkicgsODepz794 KHElSNY34BfuuctQ8OvKa6nJAH8M+3i040WjDld4ms2/w8tWcY6zYG01IJRUT9i+ORwL bocj/PC6D1o6MvZsLYRNFiqSeYqIsH+aAVtkHNdrI7Y1VqT5Gqy5ls+yM0JJHf28lEUt VK4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965727; x=1766570527; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=zyb9LZ6PT/7D8hWeLG03useXOhMS8JpWGPj51LZZTbo=; b=fwlOl0ijehAYM66FVtb35kcAl+oVddECJ43IobKHVB6mNlh7gZ/uILNi0BBsVzlwPE PmkVsq3azC+cOMb/TgclxAI3ClVCKu1aqXo0eOOTgHTi5/2qvAwwUfSHhg5FvqZxKWFF vCG86pggY/by2S4DSrA+bJIO89LoRtFkxcV/ZbW69jGdVCc+ikOKIywWzqgB8nb18irl xxqQEtmgZMBWct4wSxiJFyp+cEDOvbvFsnRKg3T2Oj7GIjjZCsy2wlNAgF30TksHzFLS jDAKHKfLSf0KqesqxvClzyubTFFCHs4JDnAsq6q2es8x2P1NqbHHZcbykq3Vz+7bxJUh FT2Q== X-Gm-Message-State: AOJu0Yx9kMWXFUqtc/XTRROsddznILUe/RIAS0M9opa+unxDMBpJGBVT eXyD5uunpOBcwcDhu9UfPc0Dgc416cyp7YOjoPJ5QohdxjjB62BQTEYRDAxzFQCN7sXGjmbYvnT 0l+XX X-Gm-Gg: AY/fxX7qbVcJ3vU7Cbn8/GwCza46v8yLcLvnQT/VKYW/GlJBXVy2TdTC0spRU8KG3ob WLee8EYj/2D75JLyLuxCzkk5p5iARw1MaYSYlTI8DZAVQETj2To377NMGg13ZCmYncP3pievU+q BpgSSLWtashmIrkTTNzjV5WTgUuAOpM/Qeq2M8Cz7hG+00D8gd8oiLhsmlm0rnafONoypf4kT5P 7iSoTG1ZtJdyo/fk51SOleuv4NtBFn241XohNcIVPDVnL4PJk69K7nHP/QDdz7TERQdAjqQVc8a DSZtZEhdha36G8KnLEUhRAWul8iDCSHOVqPkLtB/4bR1G8KDDh+OKKYImHxy5yA7tp/ZVmfgIu9 PD65S04c+sxG31lV3pQ86v4BUYHm3WoOL5nRB8ZLZrFHFUnIdyL8DjebSatU9vL7P8i1hbj2Rx3 9zFd3fzGwzLwdp2ypUCvn5qLoON/4hrEDPurHh30v3UFxEdkse3U0AUmYMwLsjz3jH768= X-Google-Smtp-Source: AGHT+IF+MhhEdhAhHf6Z9gSyPKht0rm207sOPO9friyguSF2zjMMEN5CzXajgWwS5x4eRnR47aYmUQ== X-Received: by 2002:a05:600c:6290:b0:46e:2815:8568 with SMTP id 5b1f17b1804b1-47a8f1c1e65mr199453995e9.10.1765965726650; Wed, 17 Dec 2025 02:02:06 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:06 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 20/26] libcamera: software_isp: ccm: Add self-initialising identity CCM to Ccm::init Date: Wed, 17 Dec 2025 10:01:32 +0000 Message-ID: <20251217100138.82525-21-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" We have a need to generate an identity CCM when running the GPUIsp without a sensor tuning file. A preivous patch added a selfInitialising bool to the IPAContext structure. When that bool is true generate an identity CCM at colour temperature 6500k. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/ipa/simple/algorithms/ccm.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index 0a98406c1..ac1ce1685 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -27,13 +27,23 @@ namespace ipa::soft::algorithms { LOG_DEFINE_CATEGORY(IPASoftCcm) -int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData) +int Ccm::init([[maybe_unused]] IPAContext &context, [[maybe_unused]] const YamlObject &tuningData) { - int ret = ccm_.readYaml(tuningData["ccms"], "ct", "ccm"); - if (ret < 0) { - LOG(IPASoftCcm, Error) - << "Failed to parse 'ccm' parameter from tuning file."; - return ret; + if (!context.selfInitialising) { + int ret = ccm_.readYaml(tuningData["ccms"], "ct", "ccm"); + if (ret < 0) { + LOG(IPASoftCcm, Error) + << "Failed to parse 'ccm' parameter from tuning file."; + return ret; + } + } else { + /* Initialize with identity CCM at standard D65 color temperature */ + Matrix identityMatrix = Matrix::identity(); + + std::map> ccmData; + ccmData[6500] = identityMatrix; + + ccm_ = Interpolator>(std::move(ccmData)); } context.ccmEnabled = true; From patchwork Wed Dec 17 10:01:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25594 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 9CCE8C32F1 for ; Wed, 17 Dec 2025 10:02:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D14C061F3A; Wed, 17 Dec 2025 11:02:24 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="q6FqmFZi"; dkim-atps=neutral Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 22F8861F28 for ; Wed, 17 Dec 2025 11:02:09 +0100 (CET) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-47798ded6fcso36050895e9.1 for ; Wed, 17 Dec 2025 02:02:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965728; x=1766570528; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZK3P0VzssNwl0WhBtRyk+w7dSYasdHalDGrt/ye5fgo=; b=q6FqmFZiUtuSp//3vCFW+90PAiTwIXGamOK7tWKlNf6SMLzaH4EGo8ZKV4wUPrvBN5 DAWH+MzmgSGqW4qHa6dH9g8H+trUQq+d1Soyo/n+13iqqsbCTNv/8qMzLyDyM8z+gevY qf+JVMoL64QXZdNM4SUM/pQZc/BDXYS9l2/xBzR+Y8gLH862YVDweFO8L2KeWsfHrhQ+ ZuAzGaYFFr8n28ZpwqP/u/Sjht9SzojzbO05vGPhJRhLoU3VZm0yMRbM8UMpL/MyZFe7 TLD5cxMkit3c78ysMfjNlCaQ0+rkw45lUKeBLPiPPr9V5DP2PaccqF4FwMwNw7eCv3wz Ma/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965728; x=1766570528; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ZK3P0VzssNwl0WhBtRyk+w7dSYasdHalDGrt/ye5fgo=; b=rdD6STNi2yuNXWucLveMpnc+xxvHf2ZwETH+x8rKLRO7s5jwIQAHN7HOftxVK318fI qwxrS2eaVqMomsCP9pR0e8Wrb35ZipKBCIz3cVjnnsCoBbIBgTs3qqcvG+ZlV2u/adDo hAYo0eKblTcQZh7z9pZONfO7IexYkt5v05XT59enWu/WQ4i7szRkrKTIwo9EBj+sPHAH g4VPWawJR7Ux8tISmhbeuqVPXjlToPr7dWPbb/3zHz91ViqtkIEMhXqdw9ByzHQa3816 kL0CdQHP42SFBc9CX+i9qLw6k7oSh30KGetIq6fd5MZaHTXDPkcYB1ocWagjvJ/jEvcj 4y+g== X-Gm-Message-State: AOJu0YzO3XvAuzys4lgxeVeJS1myf17T1qXGBVQI34hUj4H64j0kkCOr xUc2BZzBorkotuGZpYNJAsbk5R2ysw5BLI5XC5sbMAy0lq+HJgGbGxUkomIIqJtSiJShPwB1Tjh yGAPE X-Gm-Gg: AY/fxX6iU1rawaGRgZYjrN1aaG4Xa46uxHzVnbeN6DTkFvoIzpTYIfYuH9W6Vmqlivw 2OZi99FGlwPBhuxD7XOpFZchX/tOoPj8Z4EZ5/SyT/ryGVSy49+k3VTjvjiqCZ6kCQ4QuES0h+v uxthO4ZxDr3St9qy75MucT4SDjBNcIwWgsgqReULoRsO1dhexcC/znHxHsnXFvlKhlkCWIzcLXt OBrAXmCc9veDdtYmDMtZ6XOpOGWltnJzu3ja6kNhwmW6kXeNrsCX49ammwcObnbZkUsAwzr7MfU 7rEDj8o6bC8IhNr5bEgb25dI+YTo9NhGNuP+C9YoAdkge77Tb0g/rMeS/nbxOaGewOR3tGsuMG5 QK0M77rjg+jAmtdkPWxn2MQAOTLVRila/nGHF8CRYz1JgPaoP8fKJVEgFrqTujtLwjZ5MLoLZYh uQ8GtfxjLF2XWISAL/QzQNIszvACrPYnfT1SgKOKHtcKPI73PPdq+zLcTgKG6Kt8mNtyg= X-Google-Smtp-Source: AGHT+IGYDq5HAP3rkh+XO8HGsPp8VVlBUSrq2YQSUXbsvOMcv1MqKlZY0CaNGNeJmUD9PHM4KSclBA== X-Received: by 2002:a05:600d:b:b0:47a:94fc:d057 with SMTP id 5b1f17b1804b1-47a94fcd555mr125619335e9.2.1765965728179; Wed, 17 Dec 2025 02:02:08 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:07 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 21/26] ipa: libipa: module: Add createSelfEnumeratingAlgorithm Date: Wed, 17 Dec 2025 10:01:33 +0000 Message-ID: <20251217100138.82525-22-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Create an algorithm without having YAML data input. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/ipa/libipa/module.cpp | 34 +++++++++++++++++++++++++++++ src/ipa/libipa/module.h | 46 +++++++++++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/ipa/libipa/module.cpp b/src/ipa/libipa/module.cpp index a95dca696..8e86ca823 100644 --- a/src/ipa/libipa/module.cpp +++ b/src/ipa/libipa/module.cpp @@ -83,6 +83,40 @@ namespace ipa { * \return The list of instantiated algorithms */ +/** + * \fn int Module::createSelfEnumeratingAlgorithm(Context &context, const std::string &name) + * \brief Create and initialise a self-enumerating algorithm by name + * + * This function creates an algorithm instance from the registered algorithm + * factories using only the algorithm name, without requiring YAML configuration + * data. + * + * This is useful for algorithms that don't require external configuration + * parameters and can self-configure or use default values. + * + * \param[in] context The IPA context to pass to the algorithm's init function + * \param[in] name The name of the algorithm to instantiate + * + * \return 0 on success, negative errno value on failure: + * -EINVAL if the algorithm is not found in the factory registry + * Other negative values if algorithm initialisation fails + */ + +/** + * \fn int Module::createAlgorithmCommon(Context &context, const YamlObject &algoData, const std::string &name) + * \brief Common helper fucntion to allow createSelfEnumeratingAlgorithm and createAlgorithm share code + * + * Worker method which allows sharing of common code in the Yaml and self-initialising algorithm case + * + * \param[in] context The IPA context to pass to the algorithm's init function + * \param[in] algoData Yaml object + * \param[in] name The name of the algorithm to instantiate + * + * \return 0 on success, negative errno value on failure: + * -EINVAL if the algorithm is not found in the factory registry + * Other negative values if algorithm initialisation fails + */ + /** * \fn Module::createAlgorithms() * \brief Create algorithms from YAML configuration data diff --git a/src/ipa/libipa/module.h b/src/ipa/libipa/module.h index c27af7718..d309606f2 100644 --- a/src/ipa/libipa/module.h +++ b/src/ipa/libipa/module.h @@ -70,22 +70,25 @@ public: factories().push_back(factory); } -private: - int createAlgorithm(Context &context, const YamlObject &data) + int createSelfEnumeratingAlgorithm(Context &context, const std::string &name) { - const auto &[name, algoData] = *data.asDict().begin(); + YamlObject dummy; - /* - * Optionally, algorithms can be disabled via the tuning file - * by including enabled: false as a parameter within the - * algorithm tuning data. This is not an error, so we return 0. - */ - if (!algoData["enabled"].get(true)) { - LOG(IPAModuleAlgo, Info) - << "Algorithm '" << name << "' disabled via tuning file"; - return 0; + std::unique_ptr> algo = createAlgorithm(name); + if (!algo) { + LOG(IPAModuleAlgo, Error) + << "Algorithm '" << name << "' not found"; + return -EINVAL; } + context.selfInitialising = true; + + return createAlgorithmCommon(context, dummy, name); + } + +private: + int createAlgorithmCommon(Context &context, const YamlObject &algoData, const std::string &name) + { std::unique_ptr> algo = createAlgorithm(name); if (!algo) { LOG(IPAModuleAlgo, Error) @@ -104,9 +107,28 @@ private: << "Instantiated algorithm '" << name << "'"; algorithms_.push_back(std::move(algo)); + return 0; } + int createAlgorithm(Context &context, const YamlObject &data) + { + const auto &[name, algoData] = *data.asDict().begin(); + + /* + * Optionally, algorithms can be disabled via the tuning file + * by including enabled: false as a parameter within the + * algorithm tuning data. This is not an error, so we return 0. + */ + if (!algoData["enabled"].get(true)) { + LOG(IPAModuleAlgo, Info) + << "Algorithm '" << name << "' disabled via tuning file"; + return 0; + } + + return createAlgorithmCommon(context, algoData, name); + } + static std::unique_ptr> createAlgorithm(const std::string &name) { for (const AlgorithmFactoryBase *factory : factories()) { From patchwork Wed Dec 17 10:01:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25595 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 8B6E2C3257 for ; Wed, 17 Dec 2025 10:02:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 24E9161F63; Wed, 17 Dec 2025 11:02:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="blwBRU2r"; dkim-atps=neutral Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7DB7161A4B for ; Wed, 17 Dec 2025 11:02:10 +0100 (CET) Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-477aa218f20so37299185e9.0 for ; Wed, 17 Dec 2025 02:02:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965730; x=1766570530; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vdieV2jp4Gung7/4hWVYp0Lav9rda27DBFfiiAcRIr4=; b=blwBRU2r7XJATb8u1M6QgZc+b9WalB40SwMqoj8T/LAWm+fnyFxzEXTBewaXVUqV4L 62KWr08w3Pji/TOBVYqFhBiaP7BqPr1LLL1u0oNyS0O8TCaWD9vdHIMsqIy7XPfM4pHN qQ+6b/4QTt8iSjIti21SPCBXe5HBhpP3NhTAhWC8FPvh619VNgnt8LPdFGoWnqxFL5aD rb0izc67QGuuGPkMGtF7AGduwK2tv8hCl1G8uy+vZOIbbf72a3pw2iegYT1Uqmu5UJmZ ITzgVTkr7buNzieRogo96kVRV5STCjACLAS0KT++lDUAaabih7TcteRNIkesE2R+G/LE DuSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965730; x=1766570530; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=vdieV2jp4Gung7/4hWVYp0Lav9rda27DBFfiiAcRIr4=; b=NQfwpb1/F5GhDSYdKfVAQagxf4zqpiK6AHkathOWxVZ1eIkVsiWy7rOtDRW6wUk22j /rpkzMpU1Daj+6bMz8E7Ly9agOr8dFd3Z52kr5LnbkUGWgUWmdy8P0SuhGoqUwkK0NUu rcK7RxthOr8e5idQsHcHSM7lIkfwVynB1yV/I25cjhOlUB9YFHw7uyG0MWu8O2GjDp+3 6gIpIdaehaDSJ6pfzaE+c/2ttSEER8WNjmoeDZo+94oF3b39pBz+1z9rwDNIS+8+ExZ4 ukmT+U1hjT/fGzYGAAjvsNOkxXsOPpyIAexZTx6thA59EmXn/GzA6MpfqGm6IIHgFzvc OUvw== X-Gm-Message-State: AOJu0Ywm0XI6nzFSI5wEJ9Sx9dpOvRUe2dO/lONetWjJgdLwnGO9zqNz VFeflM3akGrzf6aKTEn71bXpu694UmGnWrDsRMQFGNG2xeVzgL81AOAmhczIMAiIGJcLHqG+IAJ xEIsN X-Gm-Gg: AY/fxX6WM7Ns5Qk4Zgc/w8vraL+w7EzRi5XYDHYxExcZNsVFoJpQWlx8V18f7VW1JWL 8b+gPJ3N1pzdc0CTxnKzcAqRnBCdft4lIsP1iCWRicQ8bFMsKOF0MQFIgLPY2erRFvgu+bc2o6w Q2UPvApD2u0utRRo8OaLBT4ojvi82wTrMfVNOWxGC1PGSYINByPeWKNHXfvkWId60DholCHix0y DI6W/klEtTx9vFtWZNLeLWiZpUhrU0+t78onBAX6WimjLGSPXp+N9Eo2t2kM++1B9YuLOOl7VNO QzJ7eo/VqU1dKxd5R+WqoWMnoYh4YFX56wtrrwPz55feurgDTgNkUvxUMdjdkjFuKK9bodbjFgU 3Z+4SsxfZSimAzRu626MrsGMSUI8DA/Mav7pVAuQMS3URzzT+9Ymkl1fwKYYip0Z409LXQV87qO VwOwwbO9RPHEwKrmYnrlBEtpv9ooFrCn1bZ2gGhxf96jtyj0cJj2UD2ZoDa9ueaf1ws3bq5iaEI Ks88A== X-Google-Smtp-Source: AGHT+IEaVqNhnq8D117Qfkm3+apb0IZjEoM3nrxsjtOLpNIOZzK5kKo9L9LoSsDmbhqpL7wRX0bYKQ== X-Received: by 2002:a05:600c:524b:b0:477:bb0:751b with SMTP id 5b1f17b1804b1-47a8f90d716mr184082475e9.27.1765965729593; Wed, 17 Dec 2025 02:02:09 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:09 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 22/26] ipa: simple: Add a flag to indicate gpuIspEnabled Date: Wed, 17 Dec 2025 10:01:34 +0000 Message-ID: <20251217100138.82525-23-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Flag gpuIspEnabled in the simple IPA context. This flag will allow to selectively avoid some calculations or to generate a default CCM. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- include/libcamera/ipa/soft.mojom | 3 ++- src/ipa/simple/ipa_context.h | 1 + src/ipa/simple/soft_simple.cpp | 3 +++ src/libcamera/software_isp/software_isp.cpp | 8 +++++++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom index 77328c5fd..aff8fcbd3 100644 --- a/include/libcamera/ipa/soft.mojom +++ b/include/libcamera/ipa/soft.mojom @@ -17,7 +17,8 @@ interface IPASoftInterface { libcamera.SharedFD fdStats, libcamera.SharedFD fdParams, libcamera.IPACameraSensorInfo sensorInfo, - libcamera.ControlInfoMap sensorControls) + libcamera.ControlInfoMap sensorControls, + bool gpuIspEnabled) => (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled); start() => (int32 ret); stop(); diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index 03d8007ea..20c75de4e 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -104,6 +104,7 @@ struct IPAContext { ControlInfoMap::Map ctrlMap; bool ccmEnabled = false; bool selfInitialising = false; + bool gpuIspEnabled = false; }; } /* namespace ipa::soft */ diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index b147aca2e..2bbe271d9 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -55,6 +55,7 @@ public: const SharedFD &fdParams, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, + bool gpuIspEnabled, ControlInfoMap *ipaControls, bool *ccmEnabled) override; int configure(const IPAConfigInfo &configInfo) override; @@ -95,6 +96,7 @@ int IPASoftSimple::init(const IPASettings &settings, const SharedFD &fdParams, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, + bool gpuIspEnabled, ControlInfoMap *ipaControls, bool *ccmEnabled) { @@ -106,6 +108,7 @@ int IPASoftSimple::init(const IPASettings &settings, } context_.sensorInfo = sensorInfo; + context_.gpuIspEnabled = gpuIspEnabled; /* Load the tuning data file */ File file(settings.configurationFile); diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 7fde57aec..5dbb0e3d6 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -121,6 +121,8 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, } stats->statsReady.connect(this, &SoftwareIsp::statsReady); + bool gpuIspEnabled; + #if HAVE_DEBAYER_EGL std::optional softISPMode = configuration.envOption("LIBCAMERA_SOFTISP_MODE", { "software_isp", "mode" }); if (softISPMode) { @@ -137,10 +139,13 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, LOG(SoftwareIsp, Error) << "Failed to instantiate GPUISP"; return; } + gpuIspEnabled = true; } #endif - if (!debayer_) + if (!debayer_) { debayer_ = std::make_unique(std::move(stats), configuration); + gpuIspEnabled = false; + } if (!debayer_) { LOG(SoftwareIsp, Error) << "Failed to create Debayer object"; @@ -177,6 +182,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, sharedParams_.fd(), sensorInfo, sensor->controls(), + gpuIspEnabled, ipaControls, &ccmEnabled_); if (ret) { From patchwork Wed Dec 17 10:01:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25596 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 1EBA8C32F2 for ; Wed, 17 Dec 2025 10:02:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 90D7D61F6A; Wed, 17 Dec 2025 11:02:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="r9fUE5Ir"; dkim-atps=neutral Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D9F5361F3A for ; Wed, 17 Dec 2025 11:02:11 +0100 (CET) Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-47775fb6cb4so39075285e9.0 for ; Wed, 17 Dec 2025 02:02:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965731; x=1766570531; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6NGx7nrnGQs63AF6qiiVewUWKS47LzoGmU3o9iY1/W0=; b=r9fUE5Iri77LzP23ZPTjTGJJFdFS9zt13v/MzJ+OVqj0yWQcRuZixPlbBhzRV0aFeU 8FJ6EmVHZCVm9+d8tjpTBjWMy7HOycuE8u44cJDHo5SjnOzO+lfmruYHfGRY67QZEWNt CURLYKZngHb5zrtSSq8xggpfzmmAo0S31NhjKGLq/0E9hR8qwEu1zZ82euDyNyht8Doq DGFfiB8966CoxJ0+iQqtM3fU68aVN1+m9bvLmzmvwcBEGaJ9X3bFMj9+0VbwCC+PeTOV vv+NVY9wmAoKyQvZMPV0LHp/Y/cLDgqYupSpOcBr4yKHxhsH3XveLQ+BR6VUwoc7v+Cc d+ZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965731; x=1766570531; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=6NGx7nrnGQs63AF6qiiVewUWKS47LzoGmU3o9iY1/W0=; b=XEAHIP5LMVgodtQEsAxg9TnNVlHxYC1FV9YU0vb/ycKbbAVpK5iX6SmBXqvDUPtNsL Ahn5OX5Md6IcWyfBj8DPxqx871FI+ludiM+PskLTXpPVRoYXjiAF6iaS5kkE795Va6Kt CQYR1VlxKeEacXxTn72pfjN5s0ZIDCiXiF2g1Z1SbSTFh3r8DwITf3RmiEiHhTpCtetr UwzZV77o40B7PPLitu+2IS4DUGbT6Mz1VWa7/qGhxOtOgFmrfi/GcP8rKxdsU0s4+JuC TJoD9GNvP/+XnoVkOPDC78HW772Z6oG9xBxYGL5ksH1ADf4b1LI7hIYpM7guZUg2Wv2h YxYw== X-Gm-Message-State: AOJu0YySJVj5Yd+4dZiSuA6w2mZaoWMXXdR/kD6LkGCPI/4zp8zcch8B BKjm+lHQe9NUjnOkzdy67B2ngtz2we1Cexlm9Aw5UC0IvojF33+i72YYOrT6phPLyVus1IQiaE0 CIpMr X-Gm-Gg: AY/fxX6h1bgT3OldamYxcJOmJ09O7K0fwYVGeAbTVgy8xACC5gpBJhjJsLIioxwJ81M s02XXPg0X2oOtR+IHYB2NnYICuwTGtjiP/XO54b92Moanjrl7MP9XhfsrlPa7pIC9l2OGBc0QtL Kfnj2ZEhuz4BxjlTXMtqQZnXXuHS/A04aQTyXVmMxUy42mh5+QCKSP30nQHVW5CVTdZ8Yn/UNKC VnBjUD71gUPgVGAzh7lwMPeay+qGBd76Ivfx3iW0peF6oHzdFYZEQEMwPIkoHdZEeK5txQcYwbs lqcrY0Zb0+cHWnOlScApyd97oFNykDwaheSvTcde/BdI7JLLySsXLNqdQ1l78gP90zbl5qtWJpS HgQPXH5aabdx3fzdR2SmhmKCu7OfAjzYz77v2MdDR1WOkyCJMaxvYSkFVWsGdbUhS4ravJjQEQC 1Bs9a6vWq1+e85E+pdHsfgSpQxyOQeBLFujXgprzGVVW0oRBgNkBrf4Mk2mvLueIhZzeo= X-Google-Smtp-Source: AGHT+IFlwf4r5BmtVr0g1MSw2YLt8vFQWbLFjQsVnivkBUhbosqMSGitFn3Sm9zvV627eRrqdbq8RQ== X-Received: by 2002:a05:600c:4e49:b0:477:aed0:f401 with SMTP id 5b1f17b1804b1-47a8f90653bmr160869375e9.23.1765965730867; Wed, 17 Dec 2025 02:02:10 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:10 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v9 23/26] ipa: software_isp: Call createSelfEnumeratingAlgorithm() to statically instantiate CCM algo Date: Wed, 17 Dec 2025 10:01:35 +0000 Message-ID: <20251217100138.82525-24-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Check the algorithm list. If CCM is not included call createSelfEnumeratingAlgorithm() to have CCM initialise itself. Signed-off-by: Bryan O'Donoghue --- src/ipa/simple/soft_simple.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index 2bbe271d9..cc263dc1f 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -137,6 +137,23 @@ int IPASoftSimple::init(const IPASettings &settings, if (ret) return ret; + bool ccmLoaded = false; + + for (auto &algo : algorithms()) { + Algorithm *algoPtr = algo.get(); + const std::type_info &info = typeid(*algoPtr); + + if (std::string(info.name()).find("Ccm") != std::string::npos) { + ccmLoaded = true; + } + } + + if (context_.gpuIspEnabled && !ccmLoaded) { + ret = createSelfEnumeratingAlgorithm(context_, std::string("Ccm")); + if (ret) + return ret; + } + *ccmEnabled = context_.ccmEnabled; params_ = nullptr; From patchwork Wed Dec 17 10:01:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25597 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 B0EA6C32F3 for ; Wed, 17 Dec 2025 10:02:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1801461F57; Wed, 17 Dec 2025 11:02:29 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="BMQhyfA5"; dkim-atps=neutral Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B0F3361F3E for ; Wed, 17 Dec 2025 11:02:12 +0100 (CET) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-47774d3536dso3952965e9.0 for ; Wed, 17 Dec 2025 02:02:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965732; x=1766570532; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0x9sYofuRKBarctBdgKuhUSV0fpuyAnEk7YI+eA7X6s=; b=BMQhyfA5VEFVSeASPLCTfSLHdNy2VOrayMuzyI0xwbsaR6s4y95mfKEY5dvmL4PkgE VAejpWlj1uT2t+hU+8hGJgb5IHSz0/dFb42HqnpKnxPy08twN0P+GWwXd2U+x/zftZyR fF/4WIbDXpIjSwwWSS0I4GyUbABYuNZR8YqJyCtnsJkiuhH/bt+yWjGsiQDLhpi6jVTx SjjwZfU3Rn9awgmmJMcT3Yg6wSG+1TPpI3SoCpZJhA2e2dr7tNgivvagIhc0qHFoqgYa k8kjKBNYJidroYO9XCNu5JyTnEESqR7M1Ae7ofhZppPf9Nu3XFgbsT2Vw/5ZO2UtgU7u blNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965732; x=1766570532; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=0x9sYofuRKBarctBdgKuhUSV0fpuyAnEk7YI+eA7X6s=; b=a6Ktby3CntsJUu8KJZJOHsC9NjfiYLZKtJAB45Qc8irNFQl88LUAEYt7dCJhBYHitS ZiayJYLVOwnsP5QBzj9KkOmP2u+sw3ISxjh5gnPA681HMzJDl5u5CDIqkq4xclcgpwBs tWxyK+av005Sp+zgqxs1YU4tZqvgaxo6gIvMfMhHkazOEA+rSl87fjo4HQEnVKc7/UC5 mqctMIuuoIT4ju7bPenoH7b9I+nqIf0Y1SZNmTATYO6xr4CwpKF57951AJDl9gKtRhSu EF0bV0KMicPvrzcPibrL1fcqhViV7kYY41llTuvU5ouZt0PfqueitDiIFPV0hSgSvso5 z0yw== X-Gm-Message-State: AOJu0YzV7cey+yCxO6Kf3oWuCFBVg3PkWjvK/0ZM4ntgqOiNvqcUMYvH JJ5+WHY/D+N1YmSuxiOiKrpx68dQpkTCUJZdYwcD0wRZKuNTE0yZ8PzVA9tA00GoHvZNXu3emK6 mP93x X-Gm-Gg: AY/fxX4cWXXYZ2inMlNfEXsrYA3+ZZM3UsTLYLekXuAUusQbOi1YldwR7HnI2gFFiyA 7VUMxzTqj5GQSUw7OviDqFJJBisyAvcIdMVafAV2xO+5ZMjOmAZlvf6NRANeeOsWKwKWmxTm2l0 d0lYCCcIu3rv6Deh/B/2aAQ4q2T/nxP7/KxPRpaOnj0QOae9/1tader1q880yDgwKFKVFyhX2r3 MFXp9Zy8kM2vjyfrmO9G5TvvUZc2uYJ5Wp38rF9aWD17H8I5CypzTGlpeS0Fhbdb3gUBqOJ0Nfq EKlUHidT4cBieritgPQSba6HkG+OPxcNv5DVALihrQRnC0NBN/oRuy8k/42l+CwVO4ceDqhafbE YunRR/Hu07IEZjvO7gViaWmn2Ke/0dcDwO7lUI+K/493itrsV/7v8VbjO6NmHHGc51+uijPcx+V 3SZBeueTfuEZReL9UOnZW3oKfenA87Xbi2S3ztoeD3SErAeN6Ybs36OQgaBWaVhsJve48= X-Google-Smtp-Source: AGHT+IGmxqKxLY4833F+Cuxw21nkY+BTpI/aTuShjG3Ea8giSSlaKckFVxS1DkneA3EnVj9iMd8Egw== X-Received: by 2002:a05:600c:4e91:b0:475:ddad:c3a9 with SMTP id 5b1f17b1804b1-47a8f2c2f62mr177622105e9.13.1765965731920; Wed, 17 Dec 2025 02:02:11 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:11 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v9 24/26] libcamera: software_isp: lut: Skip calculation lookup tables if gpuIspEnabled is true Date: Wed, 17 Dec 2025 10:01:36 +0000 Message-ID: <20251217100138.82525-25-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" On my reference platform Qualcomm RB5 sm8520 the qcam application CPU occupancy drops from ~100% to about 95% of a single core so this one change sheds aprox 5% CPU usage. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/ipa/simple/algorithms/lut.cpp | 70 ++++++++++++++++--------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index 9aaab54f1..adf411768 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -56,32 +56,34 @@ void Lut::queueRequest(typename Module::Context &context, void Lut::updateGammaTable(IPAContext &context) { - auto &gammaTable = context.activeState.gamma.gammaTable; const auto blackLevel = context.activeState.blc.level; - const unsigned int blackIndex = blackLevel * gammaTable.size() / 256; const auto contrast = context.activeState.knobs.contrast.value_or(1.0); - const float divisor = gammaTable.size() - blackIndex - 1.0; - for (unsigned int i = blackIndex; i < gammaTable.size(); i++) { - double normalized = (i - blackIndex) / divisor; - /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ - double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); - /* Apply simple S-curve */ - if (normalized < 0.5) - normalized = 0.5 * std::pow(normalized / 0.5, contrastExp); - else - normalized = 1.0 - 0.5 * std::pow((1.0 - normalized) / 0.5, contrastExp); - gammaTable[i] = UINT8_MAX * - std::pow(normalized, context.configuration.gamma); + if (!context.gpuIspEnabled) { + auto &gammaTable = context.activeState.gamma.gammaTable; + const unsigned int blackIndex = blackLevel * gammaTable.size() / 256; + const float divisor = gammaTable.size() - blackIndex - 1.0; + for (unsigned int i = blackIndex; i < gammaTable.size(); i++) { + double normalized = (i - blackIndex) / divisor; + /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ + double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); + /* Apply simple S-curve */ + if (normalized < 0.5) + normalized = 0.5 * std::pow(normalized / 0.5, contrastExp); + else + normalized = 1.0 - 0.5 * std::pow((1.0 - normalized) / 0.5, contrastExp); + gammaTable[i] = UINT8_MAX * + std::pow(normalized, context.configuration.gamma); + } + /* + * Due to CCM operations, the table lookup may reach indices below the black + * level. Let's set the table values below black level to the minimum + * non-black value to prevent problems when the minimum value is + * significantly non-zero (for example, when the image should be all grey). + */ + std::fill(gammaTable.begin(), gammaTable.begin() + blackIndex, + gammaTable[blackIndex]); } - /* - * Due to CCM operations, the table lookup may reach indices below the black - * level. Let's set the table values below black level to the minimum - * non-black value to prevent problems when the minimum value is - * significantly non-zero (for example, when the image should be all grey). - */ - std::fill(gammaTable.begin(), gammaTable.begin() + blackIndex, - gammaTable[blackIndex]); context.activeState.gamma.blackLevel = blackLevel; context.activeState.gamma.contrast = contrast; @@ -134,17 +136,19 @@ void Lut::prepare(IPAContext &context, auto &green = params->greenCcm; auto &blue = params->blueCcm; params->ccm = ccm; - for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) { - red[i].r = ccmValue(i, ccm[0][0]); - red[i].g = ccmValue(i, ccm[1][0]); - red[i].b = ccmValue(i, ccm[2][0]); - green[i].r = ccmValue(i, ccm[0][1]); - green[i].g = ccmValue(i, ccm[1][1]); - green[i].b = ccmValue(i, ccm[2][1]); - blue[i].r = ccmValue(i, ccm[0][2]); - blue[i].g = ccmValue(i, ccm[1][2]); - blue[i].b = ccmValue(i, ccm[2][2]); - params->gammaLut[i] = gammaTable[i / div]; + if (!context.gpuIspEnabled) { + for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) { + red[i].r = ccmValue(i, ccm[0][0]); + red[i].g = ccmValue(i, ccm[1][0]); + red[i].b = ccmValue(i, ccm[2][0]); + green[i].r = ccmValue(i, ccm[0][1]); + green[i].g = ccmValue(i, ccm[1][1]); + green[i].b = ccmValue(i, ccm[2][1]); + blue[i].r = ccmValue(i, ccm[0][2]); + blue[i].g = ccmValue(i, ccm[1][2]); + blue[i].b = ccmValue(i, ccm[2][2]); + params->gammaLut[i] = gammaTable[i / div]; + } } } From patchwork Wed Dec 17 10:01:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25598 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 CF7A9C32DE for ; Wed, 17 Dec 2025 10:02:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 447DA61F5A; Wed, 17 Dec 2025 11:02:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="sik5haFq"; dkim-atps=neutral Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DDA7E61A54 for ; Wed, 17 Dec 2025 11:02:13 +0100 (CET) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-47775fb6cb4so39075605e9.0 for ; Wed, 17 Dec 2025 02:02:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965733; x=1766570533; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dv4cy5fxw2jNEgaQiYOpR6yYlxmXPnqUWJMBmxyFgi8=; b=sik5haFqjcA6g9YA0gDUULji8XXdJxVGAvnXoqDEsx7g/NOyDa0bIyutW1+/JPbOg8 ndvvUgAbf63YlhA4oe8wJj2M7VRR7gkFoiPQjgt1ISgW/6Jp6z+aVvLCt7EmAPU1zMMh q6BEH9VWe+9JcU0z77oUWywZJVbv7zh+dfDryLDcK9Bl0luh3v92n+T5W4nsa8awD+QL RuslZQbi0HtcESitsatR1uMBUdIGyxpNYS4NN/M2Za/WApTIjNAnJ+q3c7ZPcOdFHvqC UV5Mzx6hVWOj92KbVLjHZZDN2602UL1FNLYHSr2UOKsfmLgRvZQzywORLQD29NVtAT1C Y5Vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965733; x=1766570533; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=dv4cy5fxw2jNEgaQiYOpR6yYlxmXPnqUWJMBmxyFgi8=; b=fPXyRj7fxM9JyTabZVXh922ew9aaPQsUegm4C/NGAUQ0eHBU4CAdGasBhV60BVzc6W 0m2pf7NU+Popx+eY/vR6lkE8tk0nqAzQku464beCCRHauq7iuJ0pQ3GcDpm/j+o0C+vA 3sM9RoWE/Y8EpLKLrxJowLsiMpY41PpfVww2FWkLAx7C8wlfhY8FjCKlqzwKVm155rvf aTTYZoCJmJSbHHX+exFyTub2PpAU1zWyPB4KUleBcJ0aVVC3GYAAC/AiVrV0/mk6AEwz EQYeGHCaK2k79rjirnH4BRxCwFCX1qHIcrd5XHoHO+U252tUZ5e4hO2VejW3YKoY4Z3x MF5Q== X-Gm-Message-State: AOJu0Yzg1oUghwppMLta5XW8InWJqLEsnmc10eV6T5VlaTZpBrMPhlDe q2Q0KERclJWHsR3q9q6B2ysBQ2JpRBt7xj1+KvCMiiz8XtS9dQ/bgTGOg+BxegfLjNq59zDApAk 9+P+y X-Gm-Gg: AY/fxX7GcW1KBIxAzoHntnzert227IcFjrFrD20gC13KAPpZN7vucBe317TxYowMQFk K9nlgSq+VTPy0skaHQmsROoWblyYGw+1HvyObuuR2LkCYMiqzUzAiOdnPvPjeBsALK7uXMqA+if DReGwFQnbSz+9vjeL8Tp5RVqEFgmLMauJSG2aiU2ff7M2eHQJZto6IuqpWZy3D4hHCyps9D81iB QvNqquBeYFSPM5SAW2De4RLTF1VjovV8DgroyZ4gbHpjXg2y/k06G7Qzo5og7PkEg47poUPrjf9 TXEaAywS3sFcuakJOEZPkw2sIhM14mhqz8TiN38NQbFeE7KoG792qRJbh1SBCFbJvMLjOC0ooCq fa6LFBezy0AJZwqn9qcjlJJP+vb1pOTnH7M6SegaLOS6u81LTLj0fJ/kU3OCqyWP40p1pkhewKv FFDHWan3wlLzJii19XMoGW6sD9uXvj6wkd/TNjolh+mGHMGUOJqpdTHBq2L7bMnROr6wM= X-Google-Smtp-Source: AGHT+IHHb5uctYitgSjmudwxlmvinHb5H7A8+DjerE7tpHy0ePGw65+2w5yD9cdEEup03erS2gw93A== X-Received: by 2002:a05:600c:6912:b0:479:3a88:de5d with SMTP id 5b1f17b1804b1-47a8f91dac4mr190464535e9.36.1765965733086; Wed, 17 Dec 2025 02:02:13 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:12 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Hans de Goede , Milan Zamazal Subject: [PATCH v9 25/26] libcamera: software_isp: lut: Change default Gamma to 1.0/2.2 Date: Wed, 17 Dec 2025 10:01:37 +0000 Message-ID: <20251217100138.82525-26-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Change the default softisp Gamma from 0.5 to 1.0/2.2. Reviewed-by: Hans de Goede Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/ipa/simple/algorithms/lut.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index adf411768..bd0d308be 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -35,7 +35,7 @@ int Lut::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { /* Gamma value is fixed */ - context.configuration.gamma = 0.5; + context.configuration.gamma = 1.0 / 2.2; context.activeState.knobs.contrast = std::optional(); updateGammaTable(context); From patchwork Wed Dec 17 10:01:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25599 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 20CC5C32F4 for ; Wed, 17 Dec 2025 10:02:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BC7B561F49; Wed, 17 Dec 2025 11:02:31 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="S5/QDaUc"; dkim-atps=neutral Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3ADCA61D64 for ; Wed, 17 Dec 2025 11:02:15 +0100 (CET) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-477ba2c1ca2so61367405e9.2 for ; Wed, 17 Dec 2025 02:02:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765965734; x=1766570534; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lSpaxpbZDestB7ujTLNf/WLvzRiE05FDL1njdNGYR9o=; b=S5/QDaUcbpGJS7i4DZN5WclItWkVB5/v7G9BlO8MTIswyvzFC5vLO1DxnKI3Rby9Sm AvWNvbQcSW+2dPCJ9U+jrWylCxfirwH1ewESZ1fFJjejau3YMDMeQS6zEWvAlagNCytm /rmeDI3ZyPjTu5qZTctyQRCseYpieFopd+OTd85lP4yYGIKbubO23JX/yFons9NKrXxR tNG0ebAnl7QIUV21O9iScOuO1XOWgE/Zh/J7wlYrbFc6/901oY8SF+W8w76UfQivkos1 WQlT4VvLTDEFu3FOF86ibVQDTN3n4jRrFsDGe2m+omHEW7lXndjI9kolCrDyDH8ppyoD 8GFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765965734; x=1766570534; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=lSpaxpbZDestB7ujTLNf/WLvzRiE05FDL1njdNGYR9o=; b=WxID46TkmU2q6JqsJLYpdmmnLjxbCQujHC5V221FumYEkZ1Pmrd2lQfIsyftZAtTCo tYl3bSfPyKfme9iBnGWbRF3HfVBJXkocitiEZiTCRiUQjeXZtIen7ve22dvrkt2nfXuh A8uGhIi1C++baedXwoCZXQrJFsIXEH7dmr9TTf64KHKr1fJ4fY52hh9Us+vjc6b7otzM Z3VHVEDBL0eNdPNnIHIDlUqtUaonPmiyW45xWhBnIKqBZYTUYO/ke+wGu9AXApZVhmBF kOSHOjsKHOHla/rlEqICpTof/I1Ff+QW2s+FrQQaQKlvK40LEWXMITVvt1noMcTS49Qg cRVw== X-Gm-Message-State: AOJu0YwAQEA/jWwX3NtKde/ZF2vCBLxAooCTyPgXMEoN8Xjsuncv1K1l DrPw3fuPKif+Ou0f1f44puZDdYjwIjoP7Bf8nG4V3ijZH0cxhQnd9b04BycVjaA60ViVLHkD3LA GQjRp X-Gm-Gg: AY/fxX58MwZIRVzeQz5a+KyGOX0fxo48gZb6gmRpg5yKyuFVLnRqIMG3HGjaKG+hxMI MzJfVIcNDauCxQ4I1mNmqyd7wJoa4wB/Nx1VdEvy6WttUt2F0SOmh3/H5GS8uc4EZTvclzZ9S5j H64ui4D0o68tc/egynZDK+MwZVZXSDY1nXLDgQYuBP89g0iy0MRujyULuvLuqnljeWa4/Zgo1ts +2pOu28YhjfNLBMmftl7nWIbzs1D1r39+Wi0CPReqHG6NKpsvUCa4WVhSrp2b0B6HJTIXMEl4Ys ns+8FsZjsQ+2z2dCa2m5Ss1MC4hVDHlqYGETefRUFIgw8nFi17aY2w3ISxxoA3E8cpd82zuoxck udxpLNlD59NnQqh0XB1n1iICMP0jKq/rggZ4bDxb0Ji4CRnoq/v4/1myCmkinCkqZIKa3TDOyXu vG8HwQtbNwwd9a41uuyR22yC8tJwQp5jfOP6NDaUVHgKPXTxT1M9Rv0Gj+MP5VGxziCM9XxrOYX A3BhQ== X-Google-Smtp-Source: AGHT+IF+IaDexqClf/OVgH8iiVI+VxXMhKPwyS1lIagkV7fauMy7XH8Em9ASOTY261wOQd6SsnfFYg== X-Received: by 2002:a05:600c:4ecb:b0:477:7991:5d1e with SMTP id 5b1f17b1804b1-47a8f90c03bmr181039125e9.25.1765965734109; Wed, 17 Dec 2025 02:02:14 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47bdc1583fbsm32292585e9.0.2025.12.17.02.02.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 02:02:13 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Kieran Bingham Subject: [PATCH v9 26/26] libcamera: software_isp: Add a gpuisp todo list Date: Wed, 17 Dec 2025 10:01:38 +0000 Message-ID: <20251217100138.82525-27-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251217100138.82525-1-bryan.odonoghue@linaro.org> References: <20251217100138.82525-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" List the series of things to do in GPU ISP in perceived order of difficulty. Acked-by: Kieran Bingham Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- src/libcamera/software_isp/gpuisp-todo.txt | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/libcamera/software_isp/gpuisp-todo.txt diff --git a/src/libcamera/software_isp/gpuisp-todo.txt b/src/libcamera/software_isp/gpuisp-todo.txt new file mode 100644 index 000000000..8930da120 --- /dev/null +++ b/src/libcamera/software_isp/gpuisp-todo.txt @@ -0,0 +1,40 @@ +List the TODOs in perceived order of ease. + + +Denoising: + - WIP + +Dead pixel correction: + - WIP + +Lense shading correction: + - WIP + +Use dma-buf handle to generate upload texture: + - eglCreateImageKHR can be used to generate the upload texture i.e. + to feed the bayer data into the GPU. + +processFrame() to run in its own thread: + - processFrame() runs in the context of the Debayer::process() + thread. Robert Mader suggested and it seems like a good + suggestion too to run processFrame() in its own thread. + +Multi-pass shaders: + - This needs some rewiring the idea is to have a list + of algorithms as is done in cpuisp iterating through the + list in a for() loop. + - The logic managing the loop has an initial input buffer + and the final output buffer. + - The higher level logic must then inform each of the + algorithms either to generate an internal working buffer + or pass the final output buffer to the last shader + in the list + - This will allow for multi-pass shaders with the final + algorithm presenting data not to its internal buffer + but to the final output buffer + +24 bit output support: + - Need to implement compute shader to do this. + +Lense flare correction: + - Not WIP still TBD