From patchwork Wed Dec 10 00:53: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: 25418 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 511EAC3257 for ; Wed, 10 Dec 2025 00:54:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0A6E06142E; Wed, 10 Dec 2025 01:54:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="gYqLgZHm"; dkim-atps=neutral Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 256E460C8A for ; Wed, 10 Dec 2025 01:54:18 +0100 (CET) Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-3436d6ca17bso6272988a91.3 for ; Tue, 09 Dec 2025 16:54:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328056; x=1765932856; 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=UBzd3bPYq1z+FSzalswMcsz5+qWYsGqRnVaooRo7brY=; b=gYqLgZHmQl5SCSyAoTrWIyUJf7K59TqbXF8g+apKHDC/58ys8mLYbgw0OW318evdD6 0LYuJj6S6ocn647P6Jw5Hlczm0Ihil2skGGzIkAHX1Kzksrdb5J9+GE2vrU/hofkCmZ4 c0SmPfeNo2LYJ9jl7tKeyTahraLlqIkkYeG6u1LTlL68eWGQ1MoxrPCi4pj45s5P9llw 7+nMZkIsimTZFHxliRi5MEzzGC9gIR+XHW2dZH3qV8rBPXTYMzeVtK8ZTyh8GCnvHQKj cLQLB5e3jZVmTpuvNN+GsTDC9jeCsh4I5ixBob/eZVbDBNvrGl0EvTRgKy6QyNGT+KLT sLnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328056; x=1765932856; 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=UBzd3bPYq1z+FSzalswMcsz5+qWYsGqRnVaooRo7brY=; b=EcIUqPWvTNZqEgfFU63rh+JS1aLSRLRZusb9Pr5QDUjmmR9cJeoLGW6LfsikmKAiV/ YbLuZ/smMeaOrO/7qQSUhmMYjGMnhQcipC8zQiMbjxvXLFVj9UogqE3jus4no+8IVkyt WNWYKSjfpNlASakj3qla05idgOezs5UHSpPDNPZiSLDcyGfP8ihF/jD/+sdBD2Il/3Ax Et4NqyuuXr9OnOfJCquiMis/wkpE4Cgp0p/FPBmlDNnPzyIL1phshPkoj6Re99t/UI5y pUKyWqJBnlHI0N5GtS5F+nvMQW0koc8eD9x6cPqUpX7t8JfZKv5pL4iFIGUFjjv+r23R ysow== X-Gm-Message-State: AOJu0YyIBNx9NNywnT5hS/dStCXsGBhlccwQpEmjc+GC9Drjj8LGu/t6 JCUFOiHGfMy7uT5feGmGNQyG5v2SdDtTIpFptZcJgCGv8k60j3t/ggktXBclZUrG9U19GEf1piQ 90WMm X-Gm-Gg: AY/fxX7ARX2n+3a5Ab5phlkEWeka7zDqkUGWkbvecWUqPGSQ9C9vvbDJba/pWJpghL4 8XVrQWKwy88kc5UewgQ6YK4tDZpEZHMe8VpW68SLVqa8iW4hjqrAS1fLLZfnereqaa8wPMLO2S/ JMa/5qp3T+jMl8Ygg0JoUnJKaLwX8pAcwIaQm8v3+rWwQX1rkAE+XbCoNj7+Uu8d1kkSSXXfmYF NPUxGzjEiHeVZvLnaQ/5qhojkupQ2xq5Ep1usDpARuD7LYpkbsR4i0y9iQtkbsd6y4LrbXW7ClG pbW6vR5e6iaXCVOwEalL9eudKKDzi+7gDv78hxleWACO1FM5/zL4EfpBb0KHtvNpRE/Ybk6J8MS BxRHt59LOb/REVFe1E/NJKt0PkCut7t6qWTsIqXMvrxPMNXgevQKIl8n8wfs6I4ZAppsJmsuLk2 1D8N48mmE6uf2a4jVx7AHqQOJXITC1yhXPw+DnXIBTX5x4MagSQnO63w062AxkvwstLAAVdemDY jI= X-Google-Smtp-Source: AGHT+IE/1D8bnPQBO9mzbWfWfuFe0bC4IgpxJDleoFpaw7WP7lXYr5BWbCb6PNHLVBXNbExvjHIZgQ== X-Received: by 2002:a17:90b:2808:b0:33b:b020:597a with SMTP id 98e67ed59e1d1-34a727159ffmr632116a91.0.1765328056515; Tue, 09 Dec 2025 16:54:16 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:16 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Kieran Bingham Subject: [PATCH v7 01/26] libcamera: software_isp: gbm: Add a GBM helper class for GPU surface access Date: Wed, 10 Dec 2025 00:53:29 +0000 Message-ID: <20251210005354.44726-2-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 Signed-off-by: Bryan O'Donoghue --- include/libcamera/internal/gbm.h | 39 ++++++++ include/libcamera/internal/meson.build | 1 + src/libcamera/gbm.cpp | 130 +++++++++++++++++++++++++ src/libcamera/meson.build | 11 +++ 4 files changed, 181 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..fcd8dd53c --- /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_ = NULL; +} + +/** + *\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 + * + * 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"; //TODO: get from an env or config setting + + 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"; + goto fail; + } + + format_ = libcamera::formats::ARGB8888; + + return 0; +fail: + close(fd_); + return -errno; +} + +/** + * \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 90d434a5a..4eaa42062 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -70,6 +70,16 @@ 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 + config_h.set('HAVE_GBM', 1) + libcamera_internal_sources += files([ + 'gbm.cpp', + ]) +endif + subdir('base') subdir('converter') subdir('ipa') @@ -178,6 +188,7 @@ libcamera_deps += [ libcamera_base_private, libcrypto, libdl, + libgbm, liblttng, libudev, libyaml, From patchwork Wed Dec 10 00:53: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: 25419 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 E0A67C3257 for ; Wed, 10 Dec 2025 00:54:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 96E316143D; Wed, 10 Dec 2025 01:54:24 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="uWoPtr/U"; dkim-atps=neutral Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A967760C8A for ; Wed, 10 Dec 2025 01:54:22 +0100 (CET) Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-7b75e366866so2734632b3a.2 for ; Tue, 09 Dec 2025 16:54:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328061; x=1765932861; 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=SXcmigsVXdUpbRe1YX6KkXB2lAedVFpsPgAcymXXKk8=; b=uWoPtr/U3tr6RtvEmc5Jzxwedov1NWoPXG7wpLUA8SfqPAInZgWIktMMl9yEYg9CbH t5nXVWE9BBcHEGpY3wxEGhdjxClGz5DrFAJqRU9vOKyAXuv/oQMcRiZS5LWgU5HSrwji fY8olAGt6LZQ4PIQH3fCrZyHqlpBCU/bhmulvFmWaRjI27qfwV72e/BwAmgNBbC3/aA/ OeGaRml4MZJPZ7Cb4mab+Nvm5H08QWuH2uVy0iOvogTXIUXqBtW9WOm59WZ97vjTIcnU +Xq3WnO/wBH3P11EaxjcuoArJ5fxkkGnGFo2ya0Gj+p850vCaQB7OExPUqgmUwt51iG+ 9ZfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328061; x=1765932861; 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=SXcmigsVXdUpbRe1YX6KkXB2lAedVFpsPgAcymXXKk8=; b=Dy0bWtnQQKsGOMQV6g0+rwAz98x0TcSxwpaMoxZBapa7GEotOwcVkkJ3qES9qHrkGf Zhhw5m2hADzp6KDcJ87NvqMXFKjIlnH/KI0LB4IhAac2NihMx2AoSeTn8KhR0aKCqzdf dXw+8kArAPl+K8Iqi+6wZDsxeRxVtcqmiWN4crzJIYL+lUgDxOOUN6zc3iHa5/JSkkkS O2lnHBtWgtLN2p61/GJhuNey/Yt8j8TFNG+W/ayIFlIB8qQHu98V5XvE1wt/T9tTA62t jlqqUCuzhLG7SEBW4WiYFCg38scO5Gpy7/slO37ur8ZBqmsihAzKkXeYlzhiiPDfd3D+ wuuQ== X-Gm-Message-State: AOJu0YzlOpkwn1i8Xa/sr/L3akagcg0e0NbKj74P4UxJFyuZdyr/CSHc ZzaAMLuMuxW3M57evSD1JR2173IRSrDcl/Vp6fqAW1HD8YweHnsCHuHzaRIvjuH+htCCuBBgCn8 ibF/+ X-Gm-Gg: ASbGnct9XLGT2u87ojASrZBRe33hDyiHFxuKXS2vekYZhui84H7lo2OqdUzkCN/ue5V 8lUB1jrEHpdGTfheIDA9A5m8Qlg13usUW7fuVKw4N0lpJbcsUm+nfiMCKRV9QA7XXN7CuLXRcvQ MeTSQVqTmk2qAxdA6j0GM3ayj+VWC9T6jChxFO0UgKCNm51Ch0r4b7k/0lDN0qlrx3dI8jRhRrA QPvKFdivq1ktzvr5xtdWFjdGxs2s4y6D5OJPTOZWumU8rkuxwZgAXxUUT28SnihotegbTtetGgf CfnZwPzCP6zH3r7xr52V8Fz3PZ+ZxuDHCllR3xc0DrR9hKNflsZ3/cM5nxJz1TnoQfg59tOqB6f Hkye6hi/HqTl8DMRn9iXW1wFhcwiZFOclwitStv6xmeUWCkMLH1OHRKB6x84wJHB1IQZzt02KJ6 rhVCft4BpY1nTtZyW+vGN2hT6GW/dpBm5fs6YSazCca2umNsUx+YdbsJQfWDAzyC6H X-Google-Smtp-Source: AGHT+IFpOtsws3WxSAtRuCr8KekNc5H5D1XeP6MdvauXKEdwjTgJw7BCIVXnKdAKhNwttWL2I4WYFw== X-Received: by 2002:a05:6a20:158b:b0:352:3695:fa64 with SMTP id adf61e73a8af0-366e2450a28mr437928637.37.1765328060649; Tue, 09 Dec 2025 16:54:20 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:20 -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 v7 02/26] libcamera: software_isp: egl: Add a eGL base helper class Date: Wed, 10 Dec 2025 00:53:30 +0000 Message-ID: <20251210005354.44726-3-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 --- include/libcamera/internal/egl.h | 186 ++++++++++ src/libcamera/egl.cpp | 619 +++++++++++++++++++++++++++++++ src/libcamera/meson.build | 23 ++ 3 files changed, 828 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..542787dc5 --- /dev/null +++ b/include/libcamera/internal/egl.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + * egl_context.cpp - Helper class for managing eGL interactions. + */ + +#pragma once + +#include +#include + +#include +#include + +#include "libcamera/base/utils.h" +#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); + int 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..2ef1156eb --- /dev/null +++ b/src/libcamera/egl.cpp @@ -0,0 +1,619 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + * egl.cpp - Helper class for managing eGL interactions. + */ + +#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. + * + * \return 0 on success + */ +int eGL::syncOutput(void) +{ + ASSERT(tid_ == Thread::currentId()); + + glFinish(); + + return 0; +} + +/** + * \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(void) {} + + +/** + * \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(void) +{ + 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 vertex 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 4eaa42062..e19898a0b 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -80,6 +80,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') @@ -188,7 +209,9 @@ libcamera_deps += [ libcamera_base_private, libcrypto, libdl, + libegl, libgbm, + libglesv2, liblttng, libudev, libyaml, From patchwork Wed Dec 10 00:53: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: 25420 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 A8C8BC3257 for ; Wed, 10 Dec 2025 00:54:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 680CA61433; Wed, 10 Dec 2025 01:54:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Q3OMJt8A"; dkim-atps=neutral Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CC2226143F for ; Wed, 10 Dec 2025 01:54:24 +0100 (CET) Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-7d26a7e5639so7067341b3a.1 for ; Tue, 09 Dec 2025 16:54:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328063; x=1765932863; 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=nKh2R98CltskZ5B+8q1efHLRqihcypTsWoFDV8/z7vs=; b=Q3OMJt8AciliIdJy17m45LVyNFRwpJfm03i0uTOJ/HJnbBiDDVaqTQiIj1cgvc/pwt q2RN5UFy0BMv9NKbsxGFsHkUax6H8z8fP7WP8F4PeXMzp6/jWHqkK/u1Qh3RrNY+xfaN 9/tThB23AQ9PZ4veuAD4cilUZ8UHPmZL4s9WeEZvVhCHQLmi6t0UoVWzT8tqmWlmSmIS 5qyJFheZ4djziro6KKuydR05OtvK91C0nB0oa2PF97O+xYt8j6Ja762w4nYyv6jYYHis JuY6+beAjpSL7O86abB1rm/Lx4AIwV7WIrc/a7RUl1vbE6S3RmX1svTjg24l3F4loG6N uStg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328063; x=1765932863; 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=nKh2R98CltskZ5B+8q1efHLRqihcypTsWoFDV8/z7vs=; b=DzxLmlzpfzSwG5OA9+3T5bqNJZaLZDw9LwezcNqNq1GJh1L1K6bFJxfa00816jr6MU j0HF6vsfJ+yoGIoI13Lv4tuzlVnZf8y/d3NGLtnWzI1LJelQf5p2LwVz6fB8dGQ78HB+ 76N+ePOgRHBWc6VTf8NkG+T+vHE8BmFspeGmRx+o99o1BhJ7kYLKjv3X5v/t0uj8qiXI ucjcm3kJ3WAP/pEXaIVGeq1i2iFrlZiz2XJ3oXDjmdI9P/EoZBnQjXacvwhAQZ5VnRwP dPCGw0NmxQZVzDkocm1lUlACf52oMtF8hFK4Ccen5t15cw9FdMEHyRonhjtE2qLqVfZZ 75BA== X-Gm-Message-State: AOJu0Yw/9eEejn9VD1u614ckCOtLThl8Ox80A7CM0YJDYkd+jsqElPRU D1uCGWv+mBQ/uPrQ+UzK+yQVaYPoU+rt2vg9CXUttnPQOmpbfPaFnqxrZo2Yd9IxpPE3QoSYn1m yQ40k X-Gm-Gg: ASbGncuLuEV2s9NlcgWC/gtu0GQeF6djdfFcl+eCa6iI8Nlx2JHZ3vdnfWiWaCHZ4Ta 936cTAr+iPVJybj86J3193uOSOzwENH3S0lF6s0uBT3Ym2v6vlnw//fmjvdKPR5y1r7VKmw3k9D kkvAj0WPByuqGu6CLMtg5qiAj+6YCTEIAYUJ7YZFwWaUFa3F/MtzVCRaXw8+Bt6wSP/UKS689uv ab8QxnHkVTmZ84OEe6kYWuvZC+66QLA0Z0BkhiC96IO78Ty4cxU3zdBCfoWevbAO+g7op8xniRr P1rzN6Xx2H5+rr+IhTueHnaMQ0uCYzxg339rh0VMyFOeAvs7alweF3apC87LRu+m3XufBeSNsBq KUFRQctyN70s2caD1mnMKKGWq8kxzPP6mxne6ITW5+Mie+lxXaiSZ7wKxFPf1wnqIMFcWbNDDh3 GO3j4byGqx63XWBYC5gLimJsrNO1rmYkeqO3eVsv6iILQIjZz9Ydcxrfiej0pNzWPy X-Google-Smtp-Source: AGHT+IEz93e1CK0fP1bBoZBpnWosaStK6vQ5f3Lg0dC2s2LSt7B97AQCggyRorW34QSmzV9iDARmyQ== X-Received: by 2002:a05:6a20:3d0f:b0:366:14ac:e20f with SMTP id adf61e73a8af0-366e3ac8ae9mr530157637.77.1765328063126; Tue, 09 Dec 2025 16:54:23 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:22 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 03/26] qcam: viewfinder_gl: Set no-op Bayer shader values Date: Wed, 10 Dec 2025 00:53:31 +0000 Message-ID: <20251210005354.44726-4-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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. Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- src/apps/qcam/viewfinder_gl.cpp | 25 +++++++++++++++++++++++++ src/apps/qcam/viewfinder_gl.h | 12 ++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/apps/qcam/viewfinder_gl.cpp b/src/apps/qcam/viewfinder_gl.cpp index 1554c94d5..69b7c6e59 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,15 @@ 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 +801,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..c1b2d9d51 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 10 00:53: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: 25421 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 37204C3257 for ; Wed, 10 Dec 2025 00:54:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E745D61438; Wed, 10 Dec 2025 01:54:29 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="KcfVW8Cr"; dkim-atps=neutral Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 244486142A for ; Wed, 10 Dec 2025 01:54:28 +0100 (CET) Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-7b22ffa2a88so6325164b3a.1 for ; Tue, 09 Dec 2025 16:54:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328066; x=1765932866; 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=lV+JLx0+P4aigKpifcEHa5VvxL7Qodjjb3+3JXtFVoo=; b=KcfVW8Cr9UwoPV+/tSjMEEl+oghMGsa1mYh4MT6wp5ETKUN+0nc7DD5GLCHzJu9gXa 9iVhHMY12ZqyBAXDvIn6VaLmjgfEd57KdVLn/ZqNADpIz474lyyAdJCK4Tg8zdCHe/ad yic5IuMwnq4Jwl90oaFVOTSNdNh58VOemyqwLGgPrz1pAyBCQ64m4N64cVneAwLYl5Xh UYr5XBdhTrA/gNgw3fHJ2PdhAiQGePVx+b+wWfCoVjthlQNOdVCheM2Zt5DYDtHhhY76 8d2KN1hNpRMba4aKbNWrlignpS9dJy/5fQStYSNjOvDEyMY653TC/d7DMli0RZ9E4CvP Mhfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328066; x=1765932866; 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=lV+JLx0+P4aigKpifcEHa5VvxL7Qodjjb3+3JXtFVoo=; b=R1ol3augjwsPaMLKJ1OSEQE3qIfeWcRxdk+QorvjCNspkQOPy3BalPz/Bk0u7UaJSU 1YHhYbx8T25Acrvr8Sdg0tMF79/aTZnayC9SLGQUle/Cft1yN3A0WX7cmNLCXZJHlZg2 NAiqmhoXSo+rCE1PXw6ge2YlWrHvimVGXExpTnIBwOXzr2qNOP6B3iA7oMfqsCPeJuBk Jk1ItTO0tGiE7R+Wm8g+t9KFXZQLt/4UMMgLEXr5vPaaGv9c/4ZsKbtoflixLl1zeSaB +ZhPK/Bjho9jZuWThdWrH+QfwY9kKPOPWdv12aZuNljsk+43o4GrwHUuTxf/EAN+onA0 mveg== X-Gm-Message-State: AOJu0YxlXlRb97N9YumKpOgpST2OEeHDDgsfkvMoLTQX1XC4OlCMWwkt RQVp4prF85LELZXXXJ4tL7r2O0G5WDh81euMU0eFNvw7X1Bwg773Z/Mh+o9rmo7wAzj7v7JwqBV 7Dd15 X-Gm-Gg: ASbGncukLrF4maFU8Pe5nvlg6r3LJU59JzSPD0vlTRhY4HOdMAmmzxFBI7qS2S/iCct r5DXJ9ejWgblXkRU0gUc9/K3vo3oTX1XJQ7EtMSHiUFXeE0JfD+sETTgIYJD0kmsfOROyfeWKXC pg+t9VFmKvZplhqGEQkzLYaZv4krr8hyTafWGbhO8vEiqYTyEic8PkA5x3SaZ+S069w3T8hPzZg dbt2ZNgwm4zeJChlF/Jq9Goa5sAa7Ywp0a3eExMFDj0QkcMNuBUh6GKu17XoSwN+wLsoBo4Z8w+ Sj/3ywIctvKj5oWFOflYGC3WGe/AIIAO0YOnBGfd1/RQAiAXLwWMB+2+l5Ae25Iek29jSPtqkGq K8/mwUhDhGCYUxLXSpF0ii+RO9w8MI2eEQ8TnPHGx3fwCsiYWUZKwsGwVpAOEdcPBosykmCLIM8 WZEL19JLLoHOMlymIlcU5akUchdYOZn/5NAThndGHCcrp6XKV6FXBi4Q8clhEVYYwf X-Google-Smtp-Source: AGHT+IEa+ThqQkEne0bq4bINYcuOZi8k6mk5ZdK3wn+AxSfy2oHT/hMChGX7KSXEXw5T33F6/C6ZIQ== X-Received: by 2002:a05:6a20:748e:b0:366:14ac:8c76 with SMTP id adf61e73a8af0-366e288a36fmr583660637.76.1765328066455; Tue, 09 Dec 2025 16:54:26 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:26 -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 v7 04/26] libcamera: shaders: Rename bayer_8 to bayer_unpacked Date: Wed, 10 Dec 2025 00:53:32 +0000 Message-ID: <20251210005354.44726-5-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 69b7c6e59..ea957dc65 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 10 00:53: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: 25422 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 A6AD6C3257 for ; Wed, 10 Dec 2025 00:54:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6E17C61442; Wed, 10 Dec 2025 01:54:34 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="r/Ww6sbi"; dkim-atps=neutral Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DAFA36142A for ; Wed, 10 Dec 2025 01:54:32 +0100 (CET) Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-7b9215e55e6so4135553b3a.2 for ; Tue, 09 Dec 2025 16:54:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328071; x=1765932871; 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=r/Ww6sbiRIgoidaWP8XGknzoRKqgJI+pEL/2cM1E7EOP37GDbbImdSMQLAmG/9Snid mBCFwsqYWl5fhdOGq0vS5OWsKcwneHGfi+1/PIS7G+oUD+exDVASXU8haG8uf8i+zCVi TncVFvXfaSO3dBVKD+8Bbrmpq+9TLyzE6q1oRG5VGa9bmEz8Fpszg+NgH7KNy5FbcAix E33H2LnkIIrf1RpijrHFwdQYjHUlMwuNWT7gBvkHQtGQf42zslKjsLUsmmdx7XXN5dp5 Bd/VIUB5tFy5HBcWZlcQDLRMJDGnPkqwvVJDlpR6FdCqWTtXv4SHcOhfqWhqY7PjhIfo ePAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328071; x=1765932871; 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=LBPkoXYEEClqi+yU70/C9Wfwq/uitpsnoNAS5SGC8ZAzPkRybIqODAVGnI84zjqZsd unUXYcR1kcpeD9bdirlm0LZGJj06Gj2Yfavp+QgNwYBA+DgvZJac3nr7zgEsFqYZz8M1 6VuDhNxPFNfFvDYcNZZnMimScTQf+sU/9gvLqUaSZvKdFzIVM5Bf9Eocf1IxVTM6wIaQ iUGFJhRMOmDiJurcVd0qp9U0m/7F7ejxxbkKUw/P45GnYUjHv95j9yLi9bQIcCHHMrmF /scQ4gqzNZH+4JplGUwsN/8hEHKAqWDq6qdNKoNeA+JHb/YHxd3yP9mdHhJj0ovLl47f 0Yyw== X-Gm-Message-State: AOJu0YzVDowwyxsW/UZ7qJ1RtSgkicHcXygI2vaFYYzhzm64i5uo3VJf NXx4ME7L/WKSsp6EF3tuvjls21G2USg9WaJQLubf8qLhV35EQO65ruLBYgkZmxOfIsBV66EvwNA VfI3V X-Gm-Gg: ASbGncvhChvSa3LclYfuvu0s2/96w5jKXaT09J0JfnzuM0zLoyHwqLcZRbHdLYXGWJz oKCkewNzAbcBrDxsVaz6gNV0aQLXYc9TBfxeZFh+R+GjraxrAkLHMl41wD9gwdl8l5kaVfK1atO qAGHit3x+JLdH4iy+yDohnXrwqAYiz0B1jRjxlQo8uyHeoM+NTWZTjEvGuV1TEgmtnRfPU5e5mV J29NjAva/i/H/sLPA/kVHCI8XjAnsLuc2Jq5QXm3SyrtyrIj/hWWBJAbklvX62BUjYwjlbnU2li vzvOdvK6/FtSOeubPEkyhBFMUvZ+ZC7gDyK2j+oa0x1wj4R6kChE6kY0zdmF6LQKETCy7J/86uP zJ9FtTkOlG3z3fSeWhYfPVwYXAH82QAGeRDIj8BRvoMP9d+rMshbppPxHfDv32UPNqVNpJ2M4zR DN7gqbVNv6hkPHTPfVhJTgTr2I+pPxAX40Smzt9wXSdLpIHDKlsHd925SXKFSvV7Tl X-Google-Smtp-Source: AGHT+IGe2E1ivJtJvkM4EQRKSHR77a9ZuPj+GN0vmrHFo8KwUR2bR9MQ+hcYnPIHhYuVcO/o3pd1ow== X-Received: by 2002:a05:6a20:3c90:b0:35d:8c8:8ab4 with SMTP id adf61e73a8af0-366e2999d7cmr538889637.44.1765328071123; Tue, 09 Dec 2025 16:54:31 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:30 -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 v7 05/26] libcamera: shaders: Use highp not mediump for float precision Date: Wed, 10 Dec 2025 00:53:33 +0000 Message-ID: <20251210005354.44726-6-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 10 00:53: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: 25423 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 7E29FC3257 for ; Wed, 10 Dec 2025 00:54:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 37D7A6145B; Wed, 10 Dec 2025 01:54:37 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="VSAwhN5Q"; dkim-atps=neutral Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B9EFE61455 for ; Wed, 10 Dec 2025 01:54:34 +0100 (CET) Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-343dfb673a8so6347441a91.0 for ; Tue, 09 Dec 2025 16:54:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328073; x=1765932873; 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=VSAwhN5QX9uW4aUsbeQ3VNTKywC/gzNYoUCNntTFQyhBrz9JUTHeGM0nlQ6NaG5eKE AavCsjbUKFwY1PyRoOKZSKJ2f3lE/mPvW5IC2xGhKmNJZ523tmOTeLqd/+6A+DAkoTOY 5WUDIAOpx4TzW8D0z0umHo6JvbXvDFB1o4Swp8vVogyX5ixWJbxwaCv3r0GNIlGbhnrv 7GYDX1wUvIHullXktt3S7HexpOjTrC/TnwW1tv+XGQ0U/2mRgxLWQzX0JGXid8ZFFgYV SOcrHMOesl4Smt8JrryoKFQT8CZnVzVweTr8/awrcrfmEJwHvG/XyJUwZ8QCB+JvI1tS 14MQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328073; x=1765932873; 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=A0QRIRHBIb4TryBwNfdp+PepFahjkB/ElC9snyWC+MNiHzbUGDvWkpTK4M7A590qS1 hmG0zJvkZHmkQSuab7f0zobLGU8HJOzDtzSlSf6NJvSg4K9Rf/fUDJRflackNm80YZ8o aS1D6BFWDh+8QmGCCvHMM1oA0RKQMTAp8RWyPtzzQwFDALrist65SIesqq8/VhITm3BL n23G4Wl9O7A/tB0yua4KRhsNkuRtpgQc8yW5Xx2gfGOJzFUrLbCFpPBD6/mcGHqKw+B6 m8yylhhDMeV96LvV2lQU4vgWxbfKKNNpdP2r75GwoEaDOywmQq6peW46H00icE2HwmMB LkIA== X-Gm-Message-State: AOJu0YzqMnDHvnsCHzywaJQpSW1AevWhZZ/TowADzz2Z2ToUMIQ7toBe kl1s3vx3+felrcXkgHWlZhbLgWNgU4L6GeyUeJLTtefkEqky2MKsBVgI+/24bgrURIt6nGQ9X8d ZyFmN X-Gm-Gg: AY/fxX6ukqeURvy27MKC39SPVCqEfyPvQzfH63PjePmECkezzGTUYELG9zKNCxkdzOB 3aoTdUSC9sq6l0rfck1rTsl4p18kOpRyqBBh2+tjmb9FhFEpF9WzUa4ANGNqVWn6Hin2MeXGiei e8ucyZcodITTCoSASPMiOylleusagUSujFgQBX17Wphh1Y8GCq0DD4aAtc3najJfWhEwwRKdE0T 1yofyMJDUPVmZT1ouCY4epafrgP5vaHltWWVhs4TQYtKxX8Z1CrjzF7u3LijR6flDVBh0JWbpED CSGeesMPO2J2Kn7AZRqSSROOXQovIzjEaK1RkA7XTNIxo10fP6o4R1ZpYKTwZupCap09y+Gqz6/ z1FFlorYmab3g1dbA/isHsMG5ZNwRrPNWjT3PMF9RfVYoc1AOYljNFkFzLdZ+zsBNR6A6c8NlA5 XflwqEK6SRJQzGDiB6QbKOpdrzVT3Dk6GqUt8S9a62rnj9F92tQbDpBur6CR/0WSx9iUfPYWP2+ lQ= X-Google-Smtp-Source: AGHT+IEpuFdNxVm32Uuv18a5IWYh2q1CtGDKWBV4FlyYhV34uV/yU00dkbpa/nKaoSOO/Mkiao0iqQ== X-Received: by 2002:a17:90b:3fc7:b0:341:a9e7:e5f9 with SMTP id 98e67ed59e1d1-34a727161b6mr543228a91.0.1765328073020; Tue, 09 Dec 2025 16:54:33 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:32 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v7 06/26] libcamera: shaders: Extend debayer shaders to apply CCM gains Date: Wed, 10 Dec 2025 00:53:34 +0000 Message-ID: <20251210005354.44726-7-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 10 00:53: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: 25424 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 29290C3257 for ; Wed, 10 Dec 2025 00:54:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DAADB6144E; Wed, 10 Dec 2025 01:54:38 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="W5DhNGHS"; dkim-atps=neutral Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 15C676142A for ; Wed, 10 Dec 2025 01:54:37 +0100 (CET) Received: by mail-pf1-x432.google.com with SMTP id d2e1a72fcca58-7aae5f2633dso6813338b3a.3 for ; Tue, 09 Dec 2025 16:54:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328075; x=1765932875; 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=W5DhNGHSyV3I996uac6M2zL2cLbr72nY+syXoC4fZd4w0zTxlLWRPyUCIggMI0mdqw hKo5GDrA440tRGlYBOAqgFv0AcCKoVzgB71NJBj/KLLtlEvc3NtBtmWwbNALoSIO4A6Q wR3SD9FmKWU/Iy5o8ndiSKfL6fjqLCeSmRRx5Evx0D5ovZAsXp3djBN8RowwZlJrONlK qj83pkWivP5FldwVWd1JZPfbW/Dft5vH6OHfyRUxTrQMnidQFkbpx9VP5uxtdyL63Uya uo6w5FA0lhmWBy/1g/KaA/UqsqDfjlRaxVa4ZOCL4atvxKwezkzQu9wdu8WOT5jHM6b7 wUJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328075; x=1765932875; 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=vTe1U1mw3xihSkoj3UsL8WaIgB/Y/wMlQS3GwPovbM6i0wmoxbjSfytYQCX2w9i3Ep HBWRiYUNOo0rpiSXT/agQRUpTm9/nn3p0gjKNjMSVjzLQ35NIpKXJsCWVCRF9u2fTTqC Q5wD3VM818bmDDCf81kAoLGcs5MhLeu9O+IuJwwpBsPyGPPaQlxBklROn8yHIdna9k9F ow8KY7vF4KcedIcc5Ox7c/lvZsKiWVwbOok1Of0a4SN7Gbu0JTai+VCgJVCJTGecoDJo a62tX864i1k3R97hjL4VwKo04RpaTQtu8xe+7qQ+ZYD4LmNq50Lx3gxqKLr+UJs3Vfkk GXVg== X-Gm-Message-State: AOJu0Yzq5tdSRjtAUDwVl2I9sKg12G/05Yg4ORwN3j4r992vcPabrS0j 3C+KskPsqMVhVO+NgH7GGq1ulMLCBO+bypYiyGZdNhr/jleraYiunX3C+ySQD5hoKw9WwbD/4lF FQqQs X-Gm-Gg: ASbGnctHvzJi+AiSsrAlrhZs6YjTUm20Tk1mev050F199Ly0FCp9DoL+GmKxF7Revh/ O70VAI0C8ZiAr9yQ0TIVcT8C2DHCjXlRoK2JSqtzZmJyfE+9s9wIm5P4Piv2bm0iuZXjyc05Qaz +A9QrwnPB5U6aP8a0flZPS0Pxdh3nrLVVz1chUosbQtuwY/4TOrAKQFG4hmmCXmFNxYZTW1rJYy nHX240ekOVvp2J1BP7dB764RYf5tyPfciptZ6nEqILa1G2y7+sg2le4yNz87TnNoiA0tKLBG6fw aG09pvhrTg29fDrpMyWZRrkPDHZeGZJp2dAQJ6Ku0zUEpXcqjkrDk36GwVkGhWwZ+zKPFVC6yOZ AdhbfHOvyZ923IH1v08SgYOVm1agdUsL19YOun+L9TNJC3opJR2+0gAesfnIIWhedK2QSEGoEnN lx6zWl2uibho6wNrKakAUqNq5C+5RoJXHHYg1ZGswnBdk8b2jIs+A3a1SgAk2wTHoM X-Google-Smtp-Source: AGHT+IEnVttcMbF7FXioSmUcmZF0H41PerhuSkePWMhn7/xE+RzVl+4oGsYBBwJhvAFEzC8XHyxEdQ== X-Received: by 2002:a05:6a20:9188:b0:364:be7:6ffa with SMTP id adf61e73a8af0-366e1217ed6mr518599637.36.1765328075335; Tue, 09 Dec 2025 16:54:35 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:34 -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 v7 07/26] libcamera: shaders: Extend bayer shaders to support swapping R and B on output Date: Wed, 10 Dec 2025 00:53:35 +0000 Message-ID: <20251210005354.44726-8-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 10 00:53: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: 25425 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 AB43FC3257 for ; Wed, 10 Dec 2025 00:54:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6A67361455; Wed, 10 Dec 2025 01:54:41 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ZbWK0lwk"; dkim-atps=neutral Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5059D61453 for ; Wed, 10 Dec 2025 01:54:39 +0100 (CET) Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-7acd9a03ba9so6766826b3a.1 for ; Tue, 09 Dec 2025 16:54:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328078; x=1765932878; 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=ZbWK0lwkizK94sUUasc4goydeS7Ke1V2j/3/T6t8HjjRekND5blYkHv2CM1BMxr0uD NCmNCjzPaSEPOjimpLUPOiOgmwhlf9t5Y7BBSpuZhpvTsu1uEyZS02oogMuSalY2Vz7d CvRMHTnVWQrk0cdiHPwXTL7CiGOcs0ad3B4Saq6m/bnQGiTP3EJbHgXg9kZSH7FNN5bw hxJEGE0NMseXVBxxiLzqzBhwv4CKJJqcK7PlRMKrnzlHTzIBrv1Cuj4ZnFFpStFzqZML 1WZgzWqm44ZjZrBFk91JeRGeTf244AtRWi4cGc8M6NPLRli2LlGSK9ZgQ5RRv5HTNoH4 QyDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328078; x=1765932878; 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=vB/jh4r+3GbCyS/sDXKFnWwEWKsIQu4iZeuAKgFXj+N52Wh7j4sJOIsDMOpLU3vdwt 7FZ9Ru0xsI7ZHXWHy434yU28Bfc1wALqUG7gT+J7XbrFjJqmL3LgMplqXMHHYbxeVFpi S1jFKpdaUcqJfXUS3V1yBbvIPhNH+ZjVJAYH1tSZSaxVcz1khI15qDwQJ/XYcrovJPmy ST3LqeXOXsD8tChAkSpPFca6fm0QQtpeYWXIRirxiKXkoXVDdqipVWJGjlaJG0fWxTwt KAMvUSqKyBHXJdUzQlqGORNvXhm5tEj/ojZU7sbMistuhKQQ/w5p3SmTQzXTBm9MSQPi o5Kw== X-Gm-Message-State: AOJu0YwSBWf2U/4Wuypq0w+u8XW5LvyBfb3A6jV+7MAgu0lBSzDpjeHs UP00JkQgPCzsbs1x2wlu0tI3XvPV1z2m7901nyERo/klSXqJW+Oaz5tUgogHRgW3/x9eyKDuBbS D5RlA X-Gm-Gg: ASbGncskO9wFVvaK/X10otKg6p/NvzGQvPeQZKq7dpUxImvSmCYu6zCrrTvHjnqh0NA c9OVkk7AmcTvsUEvA6qob4SImxO90H/EEwvHh5hx1rDuYUJ2f1G1Tql1D5qnqS9b/Wj6LLndIrs ePG+OGv40gVNVL1P/6oM3zuW1325hcbUOSJVqp+EVqKj9cgAe7bmDm4jLDYT5MCn6H6rZ4eq3P3 p6KsxwTxKfPi1EF5z4Q9aI/jhIrnWgCAwJ7YSKhlOzXAgrOD0kf9ii5kQtbqCgN9Gvg/yG1rpIk 5U4mTWXk0hf8eooqkgGciqMD69GD/sf/ebUbJPNfsfNriZZC7KlAo58jm676ecnHAnEJ7QBZjG1 GMjN7813wkgYcvM5RULJFII0M1wQocIKrwWPyZPCQkaCBOr619tyOqGMj3FBEl02syXJQtuAs7O PuBTTgHFtx4xMc/+8iOgD17BOzbAl6INJy+++gjc+ETPET+I6q4TlrzWAF8yblmYxC+WZY0vCrM Is= X-Google-Smtp-Source: AGHT+IEFGiHk62rOdCVtTC/0xCtxKO5OXIimajmsyfRCaStOd+1pCyujilFuNl+KrJeD+jA5U2gGrg== X-Received: by 2002:a05:6a20:72a7:b0:366:14af:9bbb with SMTP id adf61e73a8af0-366e35c7511mr610211637.69.1765328077657; Tue, 09 Dec 2025 16:54:37 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:37 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v7 08/26] libcamera: shaders: Add support for black level compensation Date: Wed, 10 Dec 2025 00:53:36 +0000 Message-ID: <20251210005354.44726-9-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 10 00:53: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: 25426 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 38FF5C3257 for ; Wed, 10 Dec 2025 00:54:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0085461473; Wed, 10 Dec 2025 01:54:43 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="AOH8BfSc"; dkim-atps=neutral Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1D5056144D for ; Wed, 10 Dec 2025 01:54:41 +0100 (CET) Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-34381ec9197so5405066a91.1 for ; Tue, 09 Dec 2025 16:54:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328079; x=1765932879; 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=RJJStRXEZYCXo1I2NiOJvRenJYpqtZFEk2eWTmXAnZI=; b=AOH8BfScsydTcKix+Sg/vwMZM0MTxfCmqLKgazUiUWyJpkpcjeKSJwh6njm9hG/aUU /LTM+gb7W3cOL8Uu+Cm/FhJIUA+TmXo/+E678gj5CDCLE9mZ+Irl7Dwzf1osHauVU+rN dEVqzmJNAWlt2/963U8ahUnzbV9sj9Jp0xME10ZvVQFqGJ2mDV0HZE+Pq9wgg/1Uf+hu ocJxM2icFTzN8XdnsTup0aURT9x1RvN9VeZery2QwHhL962DhdtMidZaYYv5Py4ekgV/ 0OwB7zXLe+/UCIXqEHluouzCnQK9XzZF5DNPk+6eRRXZLRV7i2kNJni325mzR4GFI1+5 UvQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328079; x=1765932879; 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=RJJStRXEZYCXo1I2NiOJvRenJYpqtZFEk2eWTmXAnZI=; b=R8KnPAI0053zUsDatMLMaCMPlfgs/wwPfbnIvUMqZYbPmFUbF1J1OcFq1DmUTnwFBA wQXc6axG4fW06sxHed0ZhcQCDAF1hMirretBj6iF7e1uldYQT5LODQzA4/FAfieb63BE 7a5Rb3EtlQ59QBdiijCq+1b4drvEUGMElEF71DsrJJ4ou+pCB+Sk9apXF/9oNw+tfj5P i82o1CqIT+T+9Hk7AC+yyW4Ypyo2Ss9GHknqtUmNcDzohQovPliUzw+M8SRtFH3b/4xj JNL+00Ns8LDM8LC5TB5ynRreQezFXeqswwVfbDB1889UY1i8MngUHKPmtDALVwZUrMOE oHXA== X-Gm-Message-State: AOJu0YwmU/vdaevLFAryPf0LWg39j4PqqdiRtJIQoIKGDprtePD803vV ZvjmV8stN6piEBzBZVLtg/SQCU9XooyQQRkWStBr2vFuF8G9eIGfVSDBHmM/Wzcn9X5CWTJakTY OZorH X-Gm-Gg: AY/fxX4cVtA/XMjnPeAjs57G878MoYnlwAiGlM0pEPhIx+n2MxgblFdlaI7iByZG5vc ZKhnwDMU/BKyuX4/0xfmUiXIvvoFnwEsl7XiOHTg3U5SVZQHUnfM+jRRvThFbigCbP+0etk16w1 6NBahytUN8/JKZ3cCErye2GQphRdQtF2j1ixOrEs1IaNTuTex+2I2YMgRmm/0+oQ8kehBjvBiMV 2DV/B4YB9YIW7y22Z1MsvKGcUCQKsOgt3dORp4pmNnNJv0MCOSfSHSTnW38XhAbFfYQnhK7yZdh vzHWusMUvuSCSLIAdIiBhvn6TQ3kcbo1e2hw0m5njLxgao7csIAyMretKIsPtQ24ZeM4yQJRjjE kLAbHL/ickhbOyM3Y4qYqzAWX6stjPbev4uAmCSxZzjoZqcS2oRyuWgPTKNqshD95AjzcG/Nd7g LiFT7XU/BQu29cE0lXuIHKupXxQVkj9X8tkCi//3tEENS/qjwyNHXp2hezVgvAqJKo X-Google-Smtp-Source: AGHT+IHERH7FkIpRUMhsXyTI2AwkDTxPd7kwURcn8LdsMuHsL38B090/HW36yr1nDws/7N/Jja2CBA== X-Received: by 2002:a17:90b:258b:b0:340:54a1:d703 with SMTP id 98e67ed59e1d1-34a728d52ffmr566068a91.35.1765328079482; Tue, 09 Dec 2025 16:54:39 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:39 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v7 09/26] libcamera: shaders: Add support for Gamma Date: Wed, 10 Dec 2025 00:53:37 +0000 Message-ID: <20251210005354.44726-10-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- 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 10 00:53: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: 25427 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 DD732C3257 for ; Wed, 10 Dec 2025 00:54:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9DA986146C; Wed, 10 Dec 2025 01:54:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="S+/bpJv0"; dkim-atps=neutral Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A33756144E for ; Wed, 10 Dec 2025 01:54:43 +0100 (CET) Received: by mail-pf1-x42e.google.com with SMTP id d2e1a72fcca58-7aa2170adf9so5242854b3a.0 for ; Tue, 09 Dec 2025 16:54:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328082; x=1765932882; 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=6jMRVHzcG6H3MVoD6kRHlh/HsNgMJfbon1fvfVhm+Ns=; b=S+/bpJv0OEzTE5t3znoJuAg5MgDY2uR6LTsg9lRsVS/vJRHGPM9vH3iZhB7x5MNPLo qUR8GDVDpa8G41Fh/cftK7FxqGiE/Pseuq50W4zAGdipULnlpZTc2QGGTUvrEs5Q9OP1 KwCxzn/7U5O+pFiaD8HtCYlnGNv3cTfWX1SS1NpkQUdEi/bp4pkOQnsVIRoMOhApDLMU QLDXmpaf/uRRWLlkWIuIBHbBquQCMGAHdFsCkNJ6jKAihW5VetweFeYdTeP9makR+IvV COlMZyk218jF5ISyeIhULgnlqfX4xgImvgGYalqX2v8ph7txwIzdJ5SA9U9PBvwu0LhA 3GRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328082; x=1765932882; 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=6jMRVHzcG6H3MVoD6kRHlh/HsNgMJfbon1fvfVhm+Ns=; b=dB1Xo1NTK29Za9HPRs7kLeRwEGQ6s6qRj66AiCqn2whzA02Sg6++WYHLde4Q6UXMhc UmFtprkcKxoCdLAgG61ez+d6LHaUoXCLcfZG5O2u/OdjjSVhUM5H3e08mQ/F729dvhp/ 9oKw9p81p032cF6AS2+4MZp2MGzp9RNKYAh2DF47f8RRBQNbQdwk3GTqHatTlLUG+uAR bUqPhErFo8/D8x8TlnVTP/c94NDL5TWjzIMzGJnfxTaOHnmKYbT00ZgCpl3bVBTneN+m 6qif2Wq1Dg+GHE60tj+Vb6IBjQw8CJyt6mwGmZ2rNl3KEw7bDE5jjYtlPM7naA7OZJI9 amcA== X-Gm-Message-State: AOJu0Yy9tZrZhEGMgKbirzSCJpo0BuacL1dpbeWTJQr0g9OU1alvczVc g/cSZFF3JvTDNJMBQNck+iwam2h2S6Upejqd5o4/VhuhfIYXoEClUck8np8sLsCuE6Bd6hCMCxj kOBkx X-Gm-Gg: ASbGncvjsRcJmeGwty/yrrJI3HKOrLYaStOqHotF3Lq5Zf4MUMeT3XPJqz7aB3SBCgW euAkRpy1QTgN/jQVjej9jZeiAwDmh7zcGrjeRP66d8fs/RczReXbw88cEEMC+QACFoz7gidxXru 0ozFuCO0w82QCtcQEG4pBnuSw7XwvamOKEPZeklQRZYOvM820Ia0bV8o96D1n+1aVjL5PrGPdbV 4hSirxUbtSwiKdXEBRKMsw2+qh4ltPYkZsNAtwx9cvM92bx2gqiI1azfBt2G1Rlv3Lpy9UjETxp zvMDPhX0E/WiQoAyY/0v6FPAejkNXfDFCJsZHi3eAy2bY6B+sEz6CERMcKoiyW4XMwU7ngrwz3B DQMaYwyjLnFy/R5xdF0UZ3O7TZ8uBaZv0ST7aQTvNiOXlZCxYOev6nDFe8/aNvBsvAnYIZzSOVs 4x9CBqIyPxuRQ7Y2TmBUIjCRFmtQC5voXwo3VkrZubvGvkzJKP8ulhsW3QNnz5o1+j X-Google-Smtp-Source: AGHT+IEeSPSpK/rguyjCKRW2kAwlC7govDR4w678Ro82xhEEDy8BEmlUGZZG6CBFtMNs7l8C54n2uQ== X-Received: by 2002:a05:6a20:5483:b0:35f:6e12:186f with SMTP id adf61e73a8af0-366e07dacbamr530449637.23.1765328081907; Tue, 09 Dec 2025 16:54:41 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:41 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v7 10/26] libcamera: shaders: Add support for contrast Date: Wed, 10 Dec 2025 00:53:38 +0000 Message-ID: <20251210005354.44726-11-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 --- src/libcamera/shaders/bayer_1x_packed.frag | 19 +++++++++++++++++++ src/libcamera/shaders/bayer_unpacked.frag | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag index 77d9fbfa7..eea237dfc 100644 --- a/src/libcamera/shaders/bayer_1x_packed.frag +++ b/src/libcamera/shaders/bayer_1x_packed.frag @@ -68,6 +68,19 @@ uniform sampler2D tex_y; uniform mat3 ccm; uniform vec3 blacklevel; uniform float gamma; +uniform float contrast; + +float apply_contrast(float value) +{ + // 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)); + + // 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 +274,12 @@ 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 + rgb = clamp(rgb, 0.0, 1.0); + rgb.r = apply_contrast(rgb.r); + rgb.g = apply_contrast(rgb.g); + rgb.b = apply_contrast(rgb.b); + /* 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..1226fe075 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -27,6 +27,19 @@ varying vec4 xCoord; uniform mat3 ccm; uniform vec3 blacklevel; uniform float gamma; +uniform float contrast; + +float apply_contrast(float value) +{ + // 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)); + + // 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 +169,12 @@ 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 + rgb = clamp(rgb, 0.0, 1.0); + rgb.r = apply_contrast(rgb.r, contrast); + rgb.g = apply_contrast(rgb.g, contrast); + rgb.b = apply_contrast(rgb.b, contrast); + /* Apply gamma after colour correction */ rgb = pow(rgb, vec3(gamma)); From patchwork Wed Dec 10 00:53:39 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: 25428 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 5B944C3257 for ; Wed, 10 Dec 2025 00:54:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 25CE761473; Wed, 10 Dec 2025 01:54:47 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Ic7AuhRa"; dkim-atps=neutral Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C590B6144E for ; Wed, 10 Dec 2025 01:54:45 +0100 (CET) Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-7f0da2dfeaeso1327938b3a.1 for ; Tue, 09 Dec 2025 16:54:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328084; x=1765932884; 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=Ic7AuhRaAotFmUBEjLiS1xt/fE3r8QXWyKsM9MIq3yku8ovEBed5ZLtY4bIxT5sr11 5MDPOvEilwbuAzAcCUZxlQfECpj7863BI2uHsfdTG31HlESpm3UmkwN40xnb2DhnA0Ng esKGVQAT8hN25uxpOkapWKhFhlxTPQ2w9wb5M8JFPgRxFDa1YjunD6SYDVvy/F/6+gHj zft0iPFaoDhpyQwM8dprSOs1u2VLFxmTQo+x5JoYlXUF8nEkwCdlH4Oj+Dl0s6TaZfaz m97lRg0gGw8ipMmJvm/QAb9THr5u38FuO8f1QdPm6wDI/kncyl9Z7YtnRuoUxSV7luCR 3eQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328084; x=1765932884; 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=aBycxRuyNc8FM1rMT4ca6DXs1zVDZgZ+UkTKlbRnDH7j+SYHAmJH64ZkxGcDKbUmoI cxom3AwGPM3ifIk8Arjz4qJ8xBx6YN+PVo1XHZrM4BPyBdZGdWGN4qEtVvbmpQbEdUWN IRgYUi7uugboTOH0UXinl2GDxo1Mpyz9oRO/CO506YqXjbANJ7fbHHHJjvzpdqED8gqw Tn1cwfVJzLMtIMjZl8GKExLMj2+/rATw53AW9iEqoqzOcSBmzWiWtOe3L9yke9T74xzq qLYbtZKMOzFjM0SQoPRFGI3/TC7GcTGDBew/yLua5HEz14KDBNKlO1fQ9mGaN+gnQ456 kbYA== X-Gm-Message-State: AOJu0Yw90C5wKOAou17/717FuKnbNgjJgSoavrzSNtVQ63RhZ6Ius0TV m4gZAe8Exoqo+ujrL19AOcnlJYq+4+olHpVJk585FwMgBGqnIr+uXhLdQ7ZgMl1ElSJv8aHVZl0 Wkzmw X-Gm-Gg: ASbGncvBha0wmpaNyLAkEziyFHY/Bh+Nx271wAfuvSoEkO7LNqogFS6mKvVA4+T6Ctx QqtrK8NZQkXS+7YSStthB4pKMgq0jF1gQYwl8m8aZpnO3I4MhgJk9oWIfwzltEBAL7FFahZz0Nm box9/zRgS8rrZbBnyjss3WsFAfX56mgGJol2weMlkKdJtgkypjKeMSQY5zfH6zV6bRvDCOVAhjG 2yxCwnWgBJNvaVx57z8Rt4PGnA7t2j63ovLotV9UXhtMF/NYReLT24thtiRG70bX03Nv353EWXo FTTj2xF9C7sOI2f8yVph7hBQW4qVSftV3bq/OfvBqXqnjReG0GoArjYlvQJMrBqyf+I7IzuN724 vSBIB0iEJDRvMMxUiZBTtYmeXyWxn7RvgwMMZMJ+AQbldN9XWZq5rZyg4RHaleSPddqUgmONlef J/btUvLITb/Jj9HGZtX8q4fwdYb/IBosEcXXxwjUN83dwANq+nmCjVDwZ+5E9l6sEO X-Google-Smtp-Source: AGHT+IEgnkBt55tcUHxAxpLwzUQaHO5HsAYqJEUwyEq5AJrRC6IZriATljCHKE6bvewu1tlau/V3vw== X-Received: by 2002:a05:6a20:7fa0:b0:366:5927:6a09 with SMTP id adf61e73a8af0-366e03d6b9emr542265637.12.1765328084118; Tue, 09 Dec 2025 16:54:44 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:43 -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 v7 11/26] libcamera: shaders: Fix input sampling when width != stride Date: Wed, 10 Dec 2025 00:53:39 +0000 Message-ID: <20251210005354.44726-12-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 10 00:53:40 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: 25429 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 E90D7C3257 for ; Wed, 10 Dec 2025 00:54:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A6A8E6147D; Wed, 10 Dec 2025 01:54:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="hYMEXUlP"; dkim-atps=neutral Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A4F5961472 for ; Wed, 10 Dec 2025 01:54:47 +0100 (CET) Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-340e525487eso4965013a91.3 for ; Tue, 09 Dec 2025 16:54:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328086; x=1765932886; 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=yBXY86g8lO48WNEk1CRWNS0al2n3xfeUVM+ASK/7Rxw=; b=hYMEXUlPE+1ap5nQCILjylVoH69lSDFfifUjISfTkzeEWGuh6mfw857HVX+KqqtWOI 0O8q7LKsNzxBpa1qiS4pUeJ9MpzsAmTuD/U823AAM19za4OpCQtqqM39zb9GB3wCGi4z km04mflMP4k14oyi3IPHlLH30yxeIIm9RuIM4mkZsKi7hTQXYsbW00oqhdEc1X9AYRjl XStHOILA/I7dtyMtzz9jnnrz2Q3zHO1Y2Uznu+tPoTELmkK85Riawe5BY8YCmtYl1pfE ULNoJFLoX2ZhA5slS7YI95gHxs6EyULWAT464cT8RtVdIOvAa49liVjtiOadFu+FO/IF cuJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328086; x=1765932886; 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=yBXY86g8lO48WNEk1CRWNS0al2n3xfeUVM+ASK/7Rxw=; b=WlC6LLy9UdlOHSGqVWyZyi/0KJXz6L2RiGnZ3huliwijlF6yF/jr9GLFgfklZHTZW0 /RW6d5wJLaREG2IqxWN0w2TZyl88qd9GviRWC5maOXz3nPIe3be2yxiUIzpm2atho0st Gsf1pZaDI8A0TaxvUH4/hj/IIiSXT9BGi9vl8vz3htBCU+n2jmmcOfAsQjLdJUqN5Bhj 5fULZ2fnXmDeHyDDwGyeOJzfEKw8dAgitJQ8UznJke1VS6q8ZFDgi/W0bkBouj/+W1/Y q9CK+ryUPOIB74c+4+XklZyoimWaSy9U3QaKjeRkUlvMQfUnUQfW9rB9fgUQGu/ox0AP 9Clw== X-Gm-Message-State: AOJu0YwD0rC6tHktfYfW0nCHUChyL+on/IGcu40gHw1IQACQEf6OX/gL cg6Icctq++mPfrYTECMQHrs3RwbZ4gCe8WpCAtqfl7aTQs4PoijMmcck4Pu3R0GYE0nvFmnIBeZ ajBQ2 X-Gm-Gg: AY/fxX4vgjxF2eDOtTHeIO6hkzdfvj2UEtDq/ChIHa1WUm9Xc4MqsNME/COVQhw4us2 t0rFL4c13hR6D2SmDY4+WW9FV7YgDjcufLt6hGPLo8+y3gKiNPZoYkcftEmC6DqAhS2Z+kUwpfX 3ZxPVHDayFXayrAwxXsjZem9UAFv+sOZH+TWqdKYyRW/fVaJeyIKe2P3utItsdykfakLwq/Xtqe fL9WnzXSsr2Hb2O7a7CBB9z3wCY4SLzvJCrUGbHMox+iWdGiPUDq6BcRmxkNBo59AVQdtRa4Wcv T/fINQk/Vl6aL9pbioZnNLFY97hevkSX5Mv1gayG7KnydT1oZmdDpfeyBnGaIAmc6rjqFro5Ns6 BTFZ/CWMpCRcyNG+0qc+tGnWMtTHTXFwdtD9qZDZ2ULa+GgmJLnllFjHrsjtajLQu+St3PwdsSJ pMVM/YrgzcWX+SMX89j+VaW8HlwMNN+oG+edpsEyV8BC+GbRMT/RqKP2yCxlQQ6kur X-Google-Smtp-Source: AGHT+IEjCREWwBfHNqGxGIEAQcZ+8xVPdkGLwUACtyPxoAiKbaJ01Jg+4m9mZGw7VeF4ORhygOpXsg== X-Received: by 2002:a17:90b:5790:b0:341:d265:1e82 with SMTP id 98e67ed59e1d1-34a7288c12amr537865a91.29.1765328085942; Tue, 09 Dec 2025 16:54:45 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:45 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 12/26] libcamera: software_isp: Add member variables to track selected input/output pixelFormat Date: Wed, 10 Dec 2025 00:53:40 +0000 Message-ID: <20251210005354.44726-13-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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. Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- 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 63a61daf9..ebd3e3a8b 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 5c0cb3914..4a2ec3e53 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 10 00:53:41 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: 25430 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 B0CC0C3257 for ; Wed, 10 Dec 2025 00:54:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 60F8C61489; Wed, 10 Dec 2025 01:54:51 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="kWZTCeu8"; dkim-atps=neutral Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6650B6144E for ; Wed, 10 Dec 2025 01:54:49 +0100 (CET) Received: by mail-pf1-x435.google.com with SMTP id d2e1a72fcca58-7f0da2dfeaeso1327976b3a.1 for ; Tue, 09 Dec 2025 16:54:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328088; x=1765932888; 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=fUPG83V9mPoRg1PNZsAJC6IGsSjjlJPVgd9Vl0+mcuo=; b=kWZTCeu8RwPY6TcDT3mPBj4DxlKelaQkZGEftOyFnDmogmLKMn+Nno02xSm+Ko7pXM Xdq4xjXuVcWS9Zj2L8vP9Dsweo8XO0Mg9U0Ra//w3hoMXnF47TBZn7LwHt5eNsygNmsv +09W3IZ6u2rDaY43g9AVLcBvkDMKkBEzd4Al16CQe3Qc/dTXUHv7bj7xYEUDHiis4K/7 RPu/7N/ihJkko9xtQkK1mAYjST38EqgpJFyOqhF7edfJxKJJUQgxpzmBjVOjLpY3hA4Q YvaB2zQynpG2jVUh66g8q5grdwGNHZ99BCYyXI5SS9hTHZJohPzDQ6UDv1Z2+99bsx6a BfbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328088; x=1765932888; 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=fUPG83V9mPoRg1PNZsAJC6IGsSjjlJPVgd9Vl0+mcuo=; b=HpacX6lOQiTbRoKpsf51fS2hxhAMTaMinfFqKCICQyEl7NTwOIlrX69uszyeeeHRAZ sudIwzspqvyfxGF2WmhmjwCLOPh5AvPQ5qEvG5GL4C6JCxn0QD3d1XxotUTY8KC/xBg7 Aa2UqPj70vLGimRPQwAkZKjyA+MvADDeT68GjrmX/y4WK8dT8iaE7coC3BAqAvuj06o4 hzgGVjLyzHLK0AdPAseMv0whGeToyqTxn50EGRvKvdH57rD6ZWzrsiMQA7SGkZLVD+aM bRDx4thwwHi1TqiGXbM0FOBQ8irknQTBPojl9Xb2IPaArGhi5qClCrnbFAPQ9QanqAs9 11HQ== X-Gm-Message-State: AOJu0Yzavo294iKgIGBWM9JrDf7PRgXtf+VTWFgzbqpWb6TzfdE5cFxX fhXX9/sHJNfFxaBEbzllozwB9+BsDA39jz0rUJTZZYjq9KJurOSFAvMX6oARdZfiZfz3ylnFV4+ JsQT5 X-Gm-Gg: ASbGnct8TpfXII/3ERjAS4bHkbkMGw6gtbXJObnb21CYicZIeeoxlBjoJsDIOVdNdqV WvDkk5x3MSFWlInF/J3ie1arD0PmZqCtQ0vJnRzjhnRpj6Xd4HWGDCVUafZYNAS0IogT6uMqeSi rjUxrm7M7hrQQlrFfFWCGUOsjrwH4+y22wM992PIKJS93yS3cD/OnKyqaZBWkyRv5BGoM3zhU7e Yqpy/zyXzW0w8bgD2ctZr7h35BrORI8vThlSKj8SMtIzZ1oIqaVXrTBGqqJSPk7ItfKS/2jAoUk X/cc6E4F5HRezr+ngNWnF2QuqfX4Avgf5IeflaOMVKM/mluZGCdNI93MAAlc82BabawVpE8qzVU eZBzR/xLQPz1+jBKXoAqtiPRYjtmcT7QwtzAaP8SMKxm15/V1Qv36hnTBzDuIuykXnaLftdUKIT sM8wu91TVEbuFLk++5zlvFV5uTswW1CxDF8A7y+7pWgjWpMKQWI+LYnaIwz6gM4W99gi5Yno7mx nA= X-Google-Smtp-Source: AGHT+IHht4LQZky28X1hluApAX81YiIXGMlWklmi1eiXn638Cw+7cpnStxPgVbChjLGC6VBUvOB5jw== X-Received: by 2002:a05:6a20:734c:b0:366:14ac:e1e6 with SMTP id adf61e73a8af0-366e36c9510mr554971637.76.1765328087778; Tue, 09 Dec 2025 16:54:47 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:47 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 13/26] libcamera: software_isp: Add a Size_ member variable to pass to eGL later Date: Wed, 10 Dec 2025 00:53:41 +0000 Message-ID: <20251210005354.44726-14-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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. Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- 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 ebd3e3a8b..4e7b61d6b 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 4a2ec3e53..189b32930 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 10 00:53:42 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: 25431 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 2F971C3257 for ; Wed, 10 Dec 2025 00:54:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EDCD661484; Wed, 10 Dec 2025 01:54:53 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="pdD504u3"; dkim-atps=neutral Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 26DCF61472 for ; Wed, 10 Dec 2025 01:54:52 +0100 (CET) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-7a9c64dfa8aso5062830b3a.3 for ; Tue, 09 Dec 2025 16:54:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328090; x=1765932890; 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=RQa6EYeW0m0FmWOvvOH0Twk6IpKVvczdGv8r4Du2Cik=; b=pdD504u3xM74UC/vW9Eh5dfS99ku415O9va+9tL2qKSHWi1F7PCel0OK946Ij5Jcs4 1yDocBgSDbGGGXVLfa5+JXuSorHj0c1tZwPOheSLzwSHB/9y865iKg32+qpSyDg+syix z3djcA1QBTIZtKwiSCIbeMvh24P4dxXSJNpt57Kz+m4Pl1bTYZsL83WueTuquTBQHUc/ iO6EhHXWb0bbAhrPm0S16p0lsiM2e0v5mfhoaPmqE8ScgBtwBS8RZnT9CTjyghQQQ57Y GwLjC5EBGHjctiWs0kBlZB4Aszasfv5+ZbKgkMkk8XU+mxrQFLZBFt1fPCtVlxFNeYXy +F8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328090; x=1765932890; 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=RQa6EYeW0m0FmWOvvOH0Twk6IpKVvczdGv8r4Du2Cik=; b=v3qr/NbwaZLKvyM119aGn3HXhuKYFSj2x8o++Nod56TFIJST5xeoTQyYyxRVRpsGCk ZFLTObxGJatziVZoolABULyPPFVGn68H9MTlCtpKJhsre9OM1JesTXnwrHewq/9gchJL w4VeHYld64fbwPFzq0pghId27uze5wdH6kHCAad+aRA09CF2HuIQO3EilNgjRukB8T/C sTgExDtl8uLEZa5RQ973T9R3rK20Zb57wc2lzgjP1osSPvnpFuBUpkoUYqvRQvSBtl0J MPmbt0FbaFt25apM8pK7IaJg91wlOVzxg9hmM3WiKYhXUlxqSxBZaUVW+7GyyuzbPhlz 3Vsg== X-Gm-Message-State: AOJu0Yyoxqw8Pi2+sa+yDNS42MtTpGlTjsuGBpXRe91W7jS9s34cgkR/ QCNfuo+UDMWMQ3rnv9FGm7HrIr+pw0xU+DboyWkewtY85bWjn7XDEgqkSiqV8wSRoqymPzQsvyR rzotF X-Gm-Gg: ASbGncvI9+cPX69eDs/mqge90rN8XdGIafozNX3vPqpZK9oT4kH8qgnAikM0lVShNU9 42iXXUHiQrMke0lLWgc/EeKHmD9oHjFUKgfzMWtWc4+GZ2NpTCAp6YNT1RzqVh3MKK0PgD13Pi8 NN247sdB/+uzYeRcAPUqRi6zlplHdrYtPipICKLw9r1oQjQjpbbIq3RyI3ks+UuS07X1FL3zCmY Yxtbz1jTOoPEnHv0gMjhs4I2mpGlYTGlYEfaxTXsHouQ6YSPRXZALFd8BbvjeO5aUv+nnb5IEkQ SSK8+abh60im/4biKN8lG1Ok1ZlALCewUEGQ47AbvH8n57fGQJaSL9ogAVl5IfxB/g9WKob5AAe hTsEDD8tAM1xMgldqt14BzqFNFEorzKnTZOAB8LY/OVtekV9z9xqftx9qZH8a3wpId9BZ0a6yzG LWbDKQEWggRlOls92z7zt6GqhgBbxzdGFKIYjvtAafOJcen+BkZ1NwtrbP8U/uPgZM X-Google-Smtp-Source: AGHT+IHk0P0uX5RpGlsF4fLDYhkT5wVskv8fUvLa4jhCIMyj78rHrlgp8Yefboi5ug7XhkMrmdgI5A== X-Received: by 2002:a05:6a21:e083:b0:35d:53dc:cb52 with SMTP id adf61e73a8af0-366e01c2996mr506422637.11.1765328090252; Tue, 09 Dec 2025 16:54:50 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:49 -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 v7 14/26] libcamera: software_isp: debayer_egl: Add an eGL Debayer class Date: Wed, 10 Dec 2025 00:53:42 +0000 Message-ID: <20251210005354.44726-15-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 --- src/libcamera/software_isp/debayer_egl.cpp | 641 +++++++++++++++++++++ src/libcamera/software_isp/debayer_egl.h | 142 +++++ src/libcamera/software_isp/meson.build | 8 + 3 files changed, 791 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..cae7cb227 --- /dev/null +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -0,0 +1,641 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Linaro Ltd. + * + * Authors: + * Bryan O'Donoghue + * + * debayer_cpu.cpp - EGL based debayering class + */ + +#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_); + GLfloat scaleX = (GLfloat)window_.width / width_; + GLfloat scaleY = (GLfloat)window_.height / height_; + GLfloat transX = -(1.0f - scaleX); + GLfloat transY = -(1.0f - scaleY); + GLfloat scale = std::max(scaleX, scaleY); + GLfloat projMatrix[] = { + scale, 0, 0, 0, + 0, scale, 0, 0, + 0, 0, 1, 0, + transX, transY, 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..1bbae5234 --- /dev/null +++ b/src/libcamera/software_isp/debayer_egl.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Bryan O'Donoghue. + * + * Authors: + * Bryan O'Donoghue + * + * debayer_opengl.h - EGL debayer header + */ + +#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 10 00:53:43 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: 25432 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 C907CC3257 for ; Wed, 10 Dec 2025 00:54:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 82B7F61489; Wed, 10 Dec 2025 01:54:56 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="hj1neJiy"; dkim-atps=neutral Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4B40561487 for ; Wed, 10 Dec 2025 01:54:54 +0100 (CET) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-7bf0ad0cb87so7346426b3a.2 for ; Tue, 09 Dec 2025 16:54:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328093; x=1765932893; 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=hj1neJiyk0pki55u+lEY42wkfhmOw/qNFrzFOAecHeFye9WvBMJttlbs6dplJk63B6 sClRcbIvlVNEz7NCTVeNfQ4dix5NuuTzmYulrKK2iSHt7evV1IpHYBVMJT/IHoRcTVel /VhPjYTYavfTC/rRxA2SQWAKeGlhhUFR+UW5Uz2L3Yfd4o3h76cIGs7h7o0EOM2tStHF siSVoMyJcvK1xE1xkl4aDiibd4lq2sHgEffmvolIp5AMDkb4xC9Iafwa57To2allh+8B /iG5sSHfWI4ymkdFwqT1qvcfNtKcCFrO2DRWfvjsZdLI3LggoNuDBeE/MOqQ8S3CRFQW IxqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328093; x=1765932893; 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=SLi1vwJdpphw+fbA9xoj4+LWyz3bVcur+fQLTvjRt3x8Q8os5a4Fw2G2DcnnmFqB3L LUaJ9v9cRpBygj5h/ZGqbixT5K+C0PmjUPmXXipLNvVHB9gxf7yTQGP8aZhkZw4g/Xwt iVG6ZrZiHkV3K4aSHOIoYfRbQTsK5pO6belrYRReYzNtaPXq+kAA6HnjwHOhh4EtmpYY t6Psdj+9KEuicczM1Y+xVK1juOopKbwd+sp3wsmDS1x2524NsrcJA+zCkgbw/zqjHXOz zrzHsICjXEnvtDBiXqjU9fDSH/LBkHI8ckQF2mTcvlI3KQzy15IUBDGZl1B7Y/53/xw0 RptA== X-Gm-Message-State: AOJu0YziGqY4AfiYbG8W+l0E9rRNG09nm+QeCf21oSdzchB5k+0/z3tg V0oeVl890M5BjQDPXXelHA4W4XABRkEYErKf6Gj6bEo5y4H7Sd3mmFkIrZos0++ENE39v+4J/6k m7Ln6 X-Gm-Gg: ASbGnctIedH4fLBfMsQhp66T0jLEdz+/MOKjwMz36bhg/whxLJoKvDse+0VmgGLQfl0 nwtSzpjzXhCbT9uuiuxhVqCrag4d6Si0i3BZA3fv1JUPSO7IDKNXKXlGN0GI+dOduodHjrgYIgU QSsV4sWwMswjVX9WzfMEITIjGMIUTLRmXnUZ+aUkqKeLQ8Aqe6OCr3Pc6U6LBM31JUC/KPi0Hm6 m2OwAWzwaj2YlCuIWkoDVJ1zQEDLWY73gTo1mJJcPaRn7I1ALsYWWO9ZPew0eA1cB/ui8nEc190 tBUZ1vH+iSnggsby01prDjspgB1KoTUHR9c2p6NIMfVFT3DEU21PAp6gamJ72nCYurKq7jIQhqI ECMooBRoEoCohoz1+Sq4BjQ4uhVrGn9OiGlzZm2vMGIImjykiPdZoZjyGLgEYzVGWsYzEs5HJ8y 8Vci45XlWTa3ckUy5QsbCkBBhjPzuDU1T6j5ktkahHCRvZLH/KQS9DykqMCzyV4rL7 X-Google-Smtp-Source: AGHT+IFS3r0aXGeuQX+5WEaVxsWyUys5Lez0i9IFe8KIleC4zLzTDOfP3kkPk+c8hs8CgVq0w/xptQ== X-Received: by 2002:a05:6a20:548d:b0:366:14ac:e1e3 with SMTP id adf61e73a8af0-366e35c3d35mr428068637.73.1765328092596; Tue, 09 Dec 2025 16:54:52 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:52 -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 v7 15/26] libcamera: software_isp: debayer_cpu: Make getInputConfig and getOutputConfig static Date: Wed, 10 Dec 2025 00:53:43 +0000 Message-ID: <20251210005354.44726-16-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 10 00:53:44 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: 25433 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 5CC94C3257 for ; Wed, 10 Dec 2025 00:54:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 11D0F6148B; Wed, 10 Dec 2025 01:54:58 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="QDDPXWIX"; dkim-atps=neutral Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C2C416148B for ; Wed, 10 Dec 2025 01:54:56 +0100 (CET) Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-7f1243792f2so863985b3a.1 for ; Tue, 09 Dec 2025 16:54:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328095; x=1765932895; 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=AhQQpiz7epWKGIAzXJxlXAcg4BbDHdrjadDzBhidlYw=; b=QDDPXWIXlEG+3Pdqtz37CRpd/fdR8/x0HIWNnrK9t++S4N++u6IKOeLVAJ3uO/UWIp aoHDm3x+nU1aO1zjzggIWkiSS01NqZ46oKLBtD0y7QpPC/12LSWXYzWj0uJw3FXt5EKg TsXxbrZ7ekSF3i7tlxai9GdJvjScvWzVgVrlcaxqEBsBnwm81pv59ZoPmHAOG6bGfTUv 06bQYFWDBz4Ewg28uJDrSaaA3+Ecqcg5vwz6b2ltAebYY2vXbdeBntA0TD0nuCrpDG66 esIt3lrmAi4BSlIPVN4RoT40SMvHGmEDK6Rl3tl08VcHPry2Iy+v06tWXCTzW2FPhIKE 3bOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328095; x=1765932895; 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=AhQQpiz7epWKGIAzXJxlXAcg4BbDHdrjadDzBhidlYw=; b=TTeZ3j5TW4hu+X2M3kHAGvkg9mwwS6xsaswwQkfMCtbJiFCk5zwY5TvzbBdNBNREnm Czfezcq2rQfeIWosSkBDZyjnH6GId3Vf4dvUPXjiePJLziquylFWEoYM+k/udJg83/pf 07EaCUAfM9QrAXFeSHWiJaQQK9Th1SX+3OxGUH8tLl/toyledF6u85L5sssIT4In7Cq5 GnPlExwODaFCt80RSQ+QzxBPEHesCl+Q75x38bk06MeHghA+AqCxzC3hyqm2ummuUlxj m+4RQRZgaP3BeiYQLZBwDTnx50ISpVysBxuy/+4qsrZuUMyfIXTt/Iy1RzgzVE64djrt s6IA== X-Gm-Message-State: AOJu0YzRETXGLNfCgYILUoxstQ8uSuJr5TX18JjnbpgbAlEnP0TVdP23 6T7PRFvSpST9H1xeRVBM76ObBWcKS0p+vzOcCtXoMlHl7WqpVOKSi+QokzP9Da5beClLuyAC/bm he2uF X-Gm-Gg: ASbGncsIGfvHyMmB5pQH4mWFp1dDhEchAqqrpZCxbTjZUnlMpRUWhVnXu+eo8vqMBXB BVBMDacWQWelkOm7cYcm0QNn1uAKSmz++YA93vCzkVk3QDuorudRhUTi+4uoCfIWurZLMfTIgQK Y3egGRSSs7a8SIESVwEQEWRBexWqfCQuVODDLQ4gLFVR9qFf7k6dDP62LY3vt94aTQLfpwKTRok aErpmw415YGUlh9mLRhq58+aIMC8qIh43TRyE3ZdpAk572JdBJ43Dy1zoSrQqMOVX+8ynjD+fsS yiqmiu50DY3VAR69KaVOxwYUVexbhjTHosjzOXZfse3iJtQ4WxAqQLNjbPK6oYGOgzW1k5bXtsY rhm9Qc5tCiB/W8KcfhmSSO6JdN7CQyV/xlQhSH84/jUJvEMjxXV6xgvnURAl+dOWUI38dumxTQp AQjEyupVZr4mKMsR2OAJQGw+q/fKXZoiwh24CQ5BzzjOJaoDYUGOzrLirB18ljSGtR X-Google-Smtp-Source: AGHT+IFtAzD6l82rifWFUw0i9S9dciEHo0EzjMWopSnlb4+SPG/kmFv0ShPSjoOo3wNGaezkliPckQ== X-Received: by 2002:a05:6a20:729d:b0:35f:fafa:a198 with SMTP id adf61e73a8af0-366e01c0f82mr491789637.10.1765328095115; Tue, 09 Dec 2025 16:54:55 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:54 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Milan Zamazal , Bryan O'Donoghue Subject: [PATCH v7 16/26] libcamera: software_isp: GPU support for unpacked 10/12-bit formats Date: Wed, 10 Dec 2025 00:53:44 +0000 Message-ID: <20251210005354.44726-17-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 --- 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 1226fe075..ec9f1921a 100644 --- a/src/libcamera/shaders/bayer_unpacked.frag +++ b/src/libcamera/shaders/bayer_unpacked.frag @@ -44,9 +44,17 @@ float apply_contrast(float value) 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 10 00:53:45 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: 25434 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 00BF5C3257 for ; Wed, 10 Dec 2025 00:55:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B36F061424; Wed, 10 Dec 2025 01:55:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="xSf2bPqr"; dkim-atps=neutral Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1192961424 for ; Wed, 10 Dec 2025 01:54:59 +0100 (CET) Received: by mail-pg1-x529.google.com with SMTP id 41be03b00d2f7-ba599137cf8so136085a12.0 for ; Tue, 09 Dec 2025 16:54:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328097; x=1765932897; 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=jTYJymtzCsAowl8rGw3I7fYJccogJGKzN/gwiM7FOBQ=; b=xSf2bPqrvTu2CEERzEwM2oyIpIoVEJDhTIwJLytvsB6CGa5tcF2gzCcE7eZfqhSIM5 oPI+rs2mRp8UkJWBZci00Dqh3UxDRzhpZ+hgHuQqf4TgExC9VP7B723+THPpBcnQZTUS KEgFnhShJVLJtIF7aBlTz8IWc9uKnTtpNjMwozTPYHIxBkX33wTG58CioJjpZ6DP5cTl s7IwPhJJMoX2DWkj+1TD9egqzqAfucKMi9sUMOXsuAObhLP2Na92/zuIEMrDt7Vo/P3E XpKtNejr/kXVr/wWjfLru5RJyNTXlYMrVemhQlc4CfKM4r3qQTZJjSgBx4W05axoM6hj f6dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328097; x=1765932897; 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=jTYJymtzCsAowl8rGw3I7fYJccogJGKzN/gwiM7FOBQ=; b=PBsUKQ/Y9QVcDlYj0ZW/LVVjHt4lZL+40f1d9bRlgZxFDBX3dr3RbfqvE4ZlfoukMs zuXsfkYemVgJIxkoF2atHNYrS/wIG300n9fTxfL0qvebDNBJuRHCyenIEDeDfTBQ7IJI mifNrpFHqJMxNW5b2L8V6RWupzkH+FEyzeQqlytDVD9xILaBguAguLKc88yqnKWkHOKK h53VFe11a/ySWYUXAQwD6/RfPj+HPi2MQAJJggi2BxifhEKnG3tQQ3xFbCAwVWnfiCRd //P9cWwtTdF48hHTqiyp3Shnd34USxE2ZRXkxHUmpxk4fG5U8+ICrHlyzFfGMu6WFyA5 WzhA== X-Gm-Message-State: AOJu0YwdG7w7XfBpIM7puNhrEjav0PTfiEKHGt9oaN2y+i/brNG0A/9D 8TvvZ/kWnnguGRetGkVJD5O65U/VtkFm92qR3YstrBnSCWs9sO0Udeg+DRJDoQ5xYvc4bKsQm2L LB7ft X-Gm-Gg: ASbGnctt28b9jCItflNJkUK87M33B2CVlUFKu7T8aakskC96XIkWCWTaxnE19+EXbUu OKIeRjwOQXjwLTxNXTb3tF8EaSphKGRswbgDhCiWg6US3k90MhIsZqnwUuDoGQp+G8n1dCCs2pe b5y2ZG3rDpqOFlgOfuiLxz49SPv1hPAOpk/l2IqXAV4dmGrb393s8GYy9Q/PWLuTk+h4OmCPpBZ 8ZDCuI2dYr897VFQPITZfrOubOxTEYU/eFcPLNW4ed+RSOsBLi8dBQ5ZwxaHT+vuR4+k/YGpzVy IdUMq04CLWi0pJkGqt9+Vi8Gg0G/uC3p95FkYvD/bSMpu3688aEAV6IajgYHA6LSorU1trwozjZ qr4ctRYgK92HsE9oWv50rQDJ0spAN8w9OQSMhzYW21QajCrimJdVeKSn5ZXKyrV39PBieBpTBvh 2i3JTWrmqMhvm6HhGF++SfbDez+lJED3szZkfVel0bpiJIaMFTBLKW2BPpNF2T2KyM4K/ArU22r wE= X-Google-Smtp-Source: AGHT+IEU3W3HXMVS2I/E0KyX8rep6aN5YVZW/R0NdvJ974rw8rN0CrbabZYu8HYePTsaM+kM7BXlog== X-Received: by 2002:a05:6a20:e293:b0:35f:84c7:4012 with SMTP id adf61e73a8af0-366db3fdc6fmr556527637.29.1765328097408; Tue, 09 Dec 2025 16:54:57 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:54:57 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 17/26] libcamera: software_isp: debayer_egl: Make DebayerEGL an environment option Date: Wed, 10 Dec 2025 00:53:45 +0000 Message-ID: <20251210005354.44726-18-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- 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 10 00:53:46 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: 25435 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 777E9C3257 for ; Wed, 10 Dec 2025 00:55:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3291D61492; Wed, 10 Dec 2025 01:55:04 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Uuvl52MZ"; dkim-atps=neutral Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3F96561487 for ; Wed, 10 Dec 2025 01:55:02 +0100 (CET) Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-7b9c17dd591so5757379b3a.3 for ; Tue, 09 Dec 2025 16:55:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328101; x=1765932901; 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=7oua+zu5TdyXrsQakdxruWuygiutsWPpfC/ccVXxgyg=; b=Uuvl52MZNQ7xQdEfP+MK9PiiYuXdlewWkg3upcO56moJcDfhogeagpQkVF074RkXfo QN2hQMOJrdScWTFQolT0P58Yj+Vkm3XiwpiIZyD8RPjn0uXPHTyTTfvQaslRDOtCASla G4sqc18Jlep9qXkLQM4+HQF5xPzQMQh/WV1nYwo34M44o816PASDyaGIt4GYBNF3sn0j gswMWLf5TsV/zlFTi2oG/OkQUU8Kv3TcKQkEHlDU3IqHUPMY3dCPSHoOdBfrnbzt9fqn aR1IiSpKxpULQeFk7Lnytu3gybZ/Yi9kkwgFYhs/Zbj0wFslbOcM7bEtwk1jDTwgRY+o 5kqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328101; x=1765932901; 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=7oua+zu5TdyXrsQakdxruWuygiutsWPpfC/ccVXxgyg=; b=TZLofuEg2xkaT+Nu1OO+QnVSmGnq0Tr+Pq5zdRmZGaO9u8SyWgjf1QcIBICw3w2uu/ lplxOBa+L9TjdIb5jh54wZ3k1a1Meqg4YtPKeDkKXk3xYdItC3E+XV8BS0WVwpNhMJWz c9sjW8GqPb/YEct73eT94JqAIF9oJ5cxPzeZcXFeaYDxvfAp6dRZfq2h3BR//ihc7piB VfKTd7jTRCYzHPt6R3pUP51z0qyBeNQ+fk5HHUkgKQQiU0DQHstfqAXn8RqL3nAh6ZAJ RW1hEMcjU1nLyUF9YySP55Uvb2eX3wG2XZX0TsLDd983V2XdVMpBrfFmrOhLWyhC24Gt E1XA== X-Gm-Message-State: AOJu0Yz8eLMuvrYFtSuDj7jqQP6hWHeDss5QPXcBxSK0gTsiyoosN55Z U6rQOi25hH6pOboZtT/TeS1D0a8JsYhqvNY+LLbA/fqC2CEzrHM5x9CkAa7b5f2MuUsR2EvOjxn n9O3p X-Gm-Gg: ASbGnctbUl8QcmD1CPF1/alL4nt1RrDGAC45KZQ3v1rjMlhVC7rLEqUv5/ar81amDEl 881wzO2pQHXTy1C85Gr8s+H4DehmaaPee2mh/JMaOp9nXLe/f/srvTCD3BkZU41kmzxh744OdHG JNvpdtQSSr9m/BDEC3smgv+15Sz/9S/DkGB+GJYppP0n4WAqK1l+p9yCUz+gGvRaksh6vJpVdAm XKZge1snB8vR0MFlmQeXx9/7OGnjSG+tz5sPLoeugdra10Hgh3Mn3HnnMt6qit9LGoldtZMtTmI jD6n9TsBzDaXyypXQ87t5AzWhgfvV3gwvUpVphHXp18hbQAQl5REC/1rMxC43CeXBGd10rhGykt uk1mZVUR5bN1EPEcS4YgvgwPds9ZbgCfpn3Moz4QXFwNeDoyXBAuZkpKGdd2fJd1lmL3C/9ERR5 Yh3A2WC7GvvTIY1FdU/a+lXz7HQGIw/9XuHTm+QBOOX76InhKeQZ5k2oQhVFstIOL2nyv4wNzEV KI= X-Google-Smtp-Source: AGHT+IF66/VkqdYjfVTJxU5FBwbob25ZO7taa+biVvvozgY5mwxNRWEYxjnHuXtFT6kFxAQww6NozA== X-Received: by 2002:a05:6a20:918c:b0:366:14b2:315 with SMTP id adf61e73a8af0-366e35bb9c6mr587131637.72.1765328100492; Tue, 09 Dec 2025 16:55:00 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.54.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:00 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 18/26] libcamera: software_isp: debayer_egl: Make gpuisp default softisp mode Date: Wed, 10 Dec 2025 00:53:46 +0000 Message-ID: <20251210005354.44726-19-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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. Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- 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..06f93ee0f 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 10 00:53:47 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: 25436 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 F287EC3257 for ; Wed, 10 Dec 2025 00:55:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AFDE961490; Wed, 10 Dec 2025 01:55:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="PvshoE8/"; dkim-atps=neutral Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2D8F361491 for ; Wed, 10 Dec 2025 01:55:04 +0100 (CET) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-7f0db5700b2so1244628b3a.0 for ; Tue, 09 Dec 2025 16:55:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328102; x=1765932902; 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=oE/XVpE5ELGRK6WRGvKSo+IYN39TZERI/uRryvlcLNo=; b=PvshoE8/OdOJ7OcWsOMRaYJhLepqSD6ebJpL21vRNqfYyH8wO4A4b7gxxx1NqvzljO +3eOQOV6hesc2so6BwMWkos9GRS1srGFAV5tkLDTGB6ktVKTpKuECOvSQ1H5KtCzWaXK w4+q0NJ0MYrFR1gADtso4kHQnNLog4avX+aJ4yrtfJhb3gbvw0qZis+XO/MANlRrUN/n KZ3+B5dT1F/YlSOoNGdoGcYyS7rLbgZz5W/BdQ9S5bwZ2cMs8e6KuEasHb3aTLnKwL9A I8IpvFFHjI0hRd1c66d/Q1T/ugnvgSGt49wHA0J07gZSrqNXA6Dc2nTUZ3njFAg++VpC vq5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328102; x=1765932902; 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=oE/XVpE5ELGRK6WRGvKSo+IYN39TZERI/uRryvlcLNo=; b=ElxpQJbQM281E7AQYekNHwDw31XW1R8nEQrpdHLdIpZ/azhbQJnt3euqCui+kZrhkM 0gq7L7uTw/6csTitdyjghI7UpwAZAG/fDFLQV77oH5yf7exqERGrjE9P8OL7HDmgnVHs kU1nXQMUETKMqsyn6kRRviVojFgr8DOYrlyBUd+TnOSG6BU417F9ZIsp63KPgDNmrK28 lKdFKlrjRTXf7QHmjQej86bnD+7p+EhDToNsf5AHJVg31CwDaiqUuEsGzTN7tW3l8yZs 6tG293NgK7QzaxHwRa/IqHFD7THYeku0PBVp4t6LPsj5WQMz+GcztjbeuUyFCNE3jhci kS3g== X-Gm-Message-State: AOJu0YwzKR190+M0++Z6SaLcxCwjOcis/9apuv2E0fPbW4S+voX9g7pi ue6HKjZlnsobnCpuqVYzHh2stqCP4HyGzVmU0bGRe5h72OSX/uGIE9YDvaqS8k6vb6Pm3ss0iKv hTAGT X-Gm-Gg: ASbGncuarYVflXtShfyQ1IzjGVfnTljDa5kFQoHyFGAl9Z+aLDj1Zl6Ynb+sARzwwpU dzIudR2fOOG64mN37v4LxrUZDLtNGq9zkh4OU4knAHd5qB2Dy/+blOZFEhzzuEyIrR5MJvoFxak JGLbezOVrT85VeDg3rl4zj9dIq0GQi8d90bKbrCJ0tJzfp0kPF3Pa/xmcRg/vtRmYKwPPWQLcnh pJwNpktaZhgwDme5ZPqHMPf+/unUb5QwbCDajdDqYFA+rx/fUKKtBj+7xjj6ooLXa4Aw/3kzrJB Q0eS4MC2JJkdUJ9OZtZyE/qmyC6kGvk6AlpdecIV9tDpqJ0yqC3jQZdvCFIemPW4tFWm5MWimq0 iicobga0JJerA6XodTo6TRonC8e1Ko8aM2cSzHbryQy47WaxVkOz4El62KgewZ/jJnnZgzyMQ3F 7GEBAc23KwO+iOOPobwMEJ3ZyM5t9u19r4m5UTyOHS6QMGALlmbFTXVerk2YEkgVCH X-Google-Smtp-Source: AGHT+IHAvydoVdsrlPK4xVPMkv1gwz9h6eCEJeq19buXoqnsEWe0qEzshMfF2ZJ9o+OT9ZEJ56GrfQ== X-Received: by 2002:a05:6a20:7350:b0:35e:11ff:45b4 with SMTP id adf61e73a8af0-366e0dea49dmr531850637.21.1765328102443; Tue, 09 Dec 2025 16:55:02 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:01 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 19/26] ipa: software_isp: Add a selfInitialising flag to IPAContext Date: Wed, 10 Dec 2025 00:53:47 +0000 Message-ID: <20251210005354.44726-20-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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. Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- 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 10 00:53:48 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: 25437 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 B3BC9C326B for ; Wed, 10 Dec 2025 00:55:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 559C061487; Wed, 10 Dec 2025 01:55:07 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="qCxC/SG4"; dkim-atps=neutral Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BBBCC61487 for ; Wed, 10 Dec 2025 01:55:05 +0100 (CET) Received: by mail-pf1-x436.google.com with SMTP id d2e1a72fcca58-7b852bb31d9so7562502b3a.0 for ; Tue, 09 Dec 2025 16:55:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328104; x=1765932904; 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=8xTO1tBEr5dmwj5C2btCnNs2WBrUsqlzweC7y2YC3O8=; b=qCxC/SG48rEHawUIfzgkkdEQKAV7gNDul33Dr7MtgHDIMbTrwvvKUDXF7SWYoxVuvH YE77MXysh9QX++LOA4y/OZ9p6ASRUPtjEdiNjI0ff9LPIHqq2FiylcU58z61KHI+oY6M 7pOyBMkEVN1k6hKtdJZWnj1r4gRYAwoxh4GXx1bESof8yLfjvES86kfVEX+5aUgcyvfm zpgKxlSGOG9IoYGmyiw75f2GU0mbRIIOQcfegTMMF0Z7j59VbU9V/6jVg9Rjr5VcDRub rt5PZfjJXiRtymcvjVABUR0YPq6GJM5y2y2Rh5fow6sGIXS7abzJId+MQXQKjGZstmug 7tSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328104; x=1765932904; 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=8xTO1tBEr5dmwj5C2btCnNs2WBrUsqlzweC7y2YC3O8=; b=iBnB9HHw8/LhIb2vnde76mFcB5QGqfSjF9Rq0/drd2M/Wnah1mH7D1AdbzM0hTIohl wIPkChTFyIQATIJotu5hQC+efr/TJKWC+0Oi/Jj5ZctX8pzTpy4EA+9JRSGHrFCTKqd7 VCiosLLtzLtoRkzzYwj5sbJwgKSLYxbidrN/PENuPHWhQ7lLsp8vXAmk7JjNWd2W5itj zGJOfyp28zHqVT69PNVBoWZGmcoT38dppZrXxWgGq7TEWf21FFh4JN18yK3gtsODa7Rn Efd9y3K6tynvoLLQHTWJHrU4ynXbfNgOhGlzTgxJWxI/FZWR1E5k/YxJqC780KC5FQm7 /AVw== X-Gm-Message-State: AOJu0YxTLILqJCdpZyT9c54XBWmklinEKJpXcaVKhQVnbqJZsckpmu9d tryFxusqLHW1PPpBHrqpnRkOpMKEpHj7PEcB+80L4vON84TSn4OkQ2kPzh7vIPIByakqAU65Qy/ z+m9g X-Gm-Gg: ASbGncs7RmpcyI0XMeKWCKseUJnuH1/PvCSqdcJlYBRWBmhtGcn9+r6J6lek+4PBM5S A29C1kDaRXD1iCm+08x4p0s2QRAOznlJpS7IG4buT56zbyA7TtPNlvWGBXStYa0E+dlw7yVPwyI qwHjiIDx+kEvWyLLipC1Px2T/u60PAHpcmiHIunBapFguYhJcUDURFimcMDzjNqI6tO/XGUNA+z +hd+KU52NGFIUYAuAWYRld4IEK0SHQkyHIan6D/Gn1s8rMjXMeh6dsHR49ohwjxHNMHwiDUWd0W jDrar3kSHIXB+l1zMPlGUFQukt4KpEoH4Tn3h270PZUiJ7doMM7sMQMVYiHS22uKOSZBQo/edCq 5tXcHmpX1DIsX3zFsxBXe0LEgML31p8B3CA+65YIi0vZg+1Ta14mn3XWUbrd+3Bs5ElUpsAXLxE 5D3epBdQF6PAtL5KZYrhqN+uSvs12oKsbnA2GvAQWSifhJPLl8KV9pd7y0lBKdfZlB X-Google-Smtp-Source: AGHT+IHouw2Sw4C4g25ZKxNbEmHl1Mm3g+AihAkhsbn/UvdN3AT0L170iMyorpKcK0p9uD4VBgckmg== X-Received: by 2002:a05:6a20:7f91:b0:35f:aa1b:bc09 with SMTP id adf61e73a8af0-366e09e2d9dmr539083637.17.1765328104052; Tue, 09 Dec 2025 16:55:04 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:03 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 20/26] libcamera: software_isp: ccm: Implement a static init() routine Date: Wed, 10 Dec 2025 00:53:48 +0000 Message-ID: <20251210005354.44726-21-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 is an overloaded init() routine that allows the CCM class to self enumerate a default identity CCM at colour temperature 6500k. This is required for the case where we are running GPUISP but don't have a CCM for the sensor. In this case we want to generate a default CCM and use it instead of using the CPUISP's lookup tables. Signed-off-by: Bryan O'Donoghue --- src/ipa/simple/algorithms/ccm.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp index 0a98406c1..38c18806e 100644 --- a/src/ipa/simple/algorithms/ccm.cpp +++ b/src/ipa/simple/algorithms/ccm.cpp @@ -27,13 +27,26 @@ 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 */ + float identity[] = { 1, 0, 0, + 0, 1, 0, + 0, 0, 1 }; + Matrix identityMatrix(identity); + + std::map> ccmData; + ccmData[6500] = identityMatrix; + + ccm_ = Interpolator>(std::move(ccmData)); } context.ccmEnabled = true; From patchwork Wed Dec 10 00:53:49 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: 25438 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 59B6CC3257 for ; Wed, 10 Dec 2025 00:55:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1436761491; Wed, 10 Dec 2025 01:55:09 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="sHwID5L6"; dkim-atps=neutral Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D871B6149C for ; Wed, 10 Dec 2025 01:55:07 +0100 (CET) Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-7bc248dc16aso5250025b3a.0 for ; Tue, 09 Dec 2025 16:55:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328106; x=1765932906; 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=4uTWF13ovZ62aTw8eKAGAg1ulpVTnbTayTqfUI1rApw=; b=sHwID5L6eVsP8ABmZ6lTq27qVKT4EuuRwgtJloHHb+FD1b0TvQ1hvr/vjqO9m0S3cn HYw47NZK4Z1ZzxnU32fBbYQeFfdFM8k+28rvAO5u6HoDElZg0rbExYpxK1kfAvuJ1Pne jAV7JhWZ4EN5thDs0Rvoz7EDfs1ncqNNGuNhs38WdxGnX10uU/txLwfiEWN1bHKmAbNy vCXAtWBOmTMubt5Z7YcB+7RhNIg/Y5ktcDXXCeFoQKbrREL6mMfqbHqhekR7ItF4jsF/ QrGDJpCJ75OQkU36PawEWe8mzLWhRUoeCq4HpHvyxxLPEK06qHvDpomzhzze/FCXVSKu Wo7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328106; x=1765932906; 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=4uTWF13ovZ62aTw8eKAGAg1ulpVTnbTayTqfUI1rApw=; b=Jdlrv5faE/IwDzsOzG9m+VGBrke5LfaFX7oy1k30feJCIbj7N2ctAykGnNBVB64DSe ExbLZDucOg8Tas+w78TeWA3Zc+K3UoW0MGuXTU6njeeaSuTesLDpRrZVL2ZG9ifgbkdA D4fgBJrnk5+JPuAmhYbuvoO6F2h0m//LpUKKJpvOKmaD8BhG0LOH2hokA3wK9fv1vhqn dqgDUQusm+896XVtWSZaSgFruBNWE5Ik6qLRFTN/yfkPjUmdZ3ck7oE+rcIDGNyaUJ5+ h6jvCuYW1WCd+XtWsjxVuk5BpeitIa+376078H+XDInADOm8p3Jg+f2RB8b0kNMUZGFw FxfQ== X-Gm-Message-State: AOJu0YxdJA5Dew/uoufCdViXt3i7TJ+2runvo5IFK51sGy5xkrNn6Ngm 49EjGW1nCPJC1WgnZm8ud2iYRwXs+/nrEqdWFffI8QyayrdusR7aiIA11VHLuIKfhTJyCVZv8Ik PgVUA X-Gm-Gg: ASbGncuxbeaspC9r3Sc921ro5jkBdcvCh6SbWiaqKyrDm1LZfs77/zgErVDxLKiv8TX LgZwQaoxJzeLIDzqOgXiFtN+E1o05/YH66ephM+9Y3VfaRYbI2cavM3hgMnkRWeGXTl4sxT43qR +5edeBxqEVnCHmfjr9vtyNk1IwutTebTNdKXjzA4dtXdYytvkvgXxnENSmcwRqpsrUL2Hja6CM3 NyLQCGPMVkcg5CBCmHgED77Uwf0kAoYM4evbW/T8+S9PqvGucC4Tc4Ri+jQZ4GumI7egNqpQIin rBCZTTaaOh6KmPzU64XmFpw4hsrc8LJBWVcGQ84EBeRrsqSAt+WvkWs7bkKdZ1k3dcPGocQj5jb t6GmxyfgHsapvMTSf13bvRxCIyF29F7hh2edtFwND89YvhbGB1PZAXR8o0WA2g+QMmgRXqsYEzK egGzBz0bOSlB78aJaDcQ7xBWJ6bOgf/r6d5/6uXsdid2EOioWYqz6eSiy8vLlvm7Cu X-Google-Smtp-Source: AGHT+IE8Z+Wb1GRgaDF4g22WcxBQPsVvkNQvsYqfRqc1j4om1GWiQFh/HGLtISQhjrt3AKyHQ1iIuw== X-Received: by 2002:a05:6a20:430d:b0:355:1add:c291 with SMTP id adf61e73a8af0-366e0ae858amr467038637.10.1765328106078; Tue, 09 Dec 2025 16:55:06 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:05 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 21/26] ipa: libipa: module: Add createSelfEnumeratingAlgorithm Date: Wed, 10 Dec 2025 00:53:49 +0000 Message-ID: <20251210005354.44726-22-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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. Signed-off-by: Bryan O'Donoghue --- src/ipa/libipa/module.h | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/ipa/libipa/module.h b/src/ipa/libipa/module.h index c27af7718..c5767c6f3 100644 --- a/src/ipa/libipa/module.h +++ b/src/ipa/libipa/module.h @@ -70,6 +70,51 @@ public: factories().push_back(factory); } + /** + * \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 + */ + int createSelfEnumeratingAlgorithm(Context &context, const std::string &name) + { + YamlObject dummy; + + std::unique_ptr> algo = createAlgorithm(name); + if (!algo) { + LOG(IPAModuleAlgo, Error) + << "Algorithm '" << name << "' not found"; + return -EINVAL; + } + + context.selfInitialising = true; + + int ret = algo->init(context, dummy); + if (ret) { + LOG(IPAModuleAlgo, Error) + << "Algorithm '" << name << "' failed to initialize"; + return ret; + } + + LOG(IPAModuleAlgo, Debug) + << "Instantiated algorithm '" << name << "'"; + + algorithms_.push_back(std::move(algo)); + return 0; + } + private: int createAlgorithm(Context &context, const YamlObject &data) { From patchwork Wed Dec 10 00:53:50 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: 25439 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 E8000C3257 for ; Wed, 10 Dec 2025 00:55:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A8DCC61487; Wed, 10 Dec 2025 01:55:12 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RcFqvvSp"; dkim-atps=neutral Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0BC8C61487 for ; Wed, 10 Dec 2025 01:55:11 +0100 (CET) Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-3436d6ca17bso6273638a91.3 for ; Tue, 09 Dec 2025 16:55:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328109; x=1765932909; 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=RpmNx23wwhxFY8b9M7YdWQZvEEvZGAvLIcRd8AlfRWg=; b=RcFqvvSphUuLI+9nj3PNidWT8QUS1Ks0f6NonLexZ6OfcxyvIOW+rJbmjwm66RdteE 4Wvd/OkntGxmp/+cGw7LbzF7L36E92PY9ptvf41O+mju3zyIlQsGVgaM+qJODL3++Ijc ibbr4sr4exMXGeZNzcdyAFaE1EUhjskofkSp+Sdj2+cAF1N1/h/lcGeEYN4lTRaQCM3o +FKH2E++crrILqnhBAsFc8HPlhLseuI3ZwdmHddI1up1BbO8bV41z/Av8B/VBzi62ZYr zNcKgGSqp4JtqkjxvC4mTJ4wNzvYXIS/4flqlKQmqmseZ2zjw10uZLlD3Qi7WjUY6zmF ZsVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328109; x=1765932909; 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=RpmNx23wwhxFY8b9M7YdWQZvEEvZGAvLIcRd8AlfRWg=; b=FM858SsaR+DqhRjqIDMbQLGepQdS/qipidV/dBA8p0eI0XShD9p9djCc5saf0mD99o 07zWudMUXlQ1H1aJ107ru5I+MByfPLyJol46ebt/C3wU3gUHBoj3Tp84XW8k0qSsot5S CdMDJM35x12FutZRIosWq2BQPbGcJBbSH+PUfzhzEe/sm5dlGVHMzaX0K9jYT22TMaPT NgYKUW8+B11XviFW4RGPzsHpjD5xQ6jp48s9eprJAnJ2FwxgDHc8/s6g08CnllXuldL/ Ekly2abJf8vYljIgN4dG0VDKdLl/VSjB488RpF3HR9OB8vsQ4qsbhSwnV3ghi+6mr/bB 5C9Q== X-Gm-Message-State: AOJu0Yyxkx/hVM03MPV/2WfSf/2ORasKmHzW0WGX3ZzTvz+KP134gpiN BS9YsoXH2+2Xp7Vhif8YhZ04haJJ3gRuJXexG6VMU1quEPEZUtv6+JZTjB33HQ5WkeaMZApkEZx SDgCN X-Gm-Gg: ASbGncsnyl6wVDPA2zpKJElp3osetQ5b0jjeRUpEWRelms0OOpFuFXnZBzU6MKa4zLy d6oVQI1ZTlt+AkKtFyxyDde3bzVHSJm21J8L8n9cIH2FfstC6AV8vPm1yrxtAUoUjldKEj8RwL8 rMJsqRpBdyBAC9QBogCt9Til8W42D1di/2gROQNu+zUYEsEotxMnIcmVdVV8w/jvA0ipl0UPkmf /I5e051Nw7/iMbuiyA9oehICxJyffAMQRu3cAX8LiBDj48pRleogjRHvn22rN9V9NCLG2bfwVKw hFZHXaN4q+Qvm85dGLNyT0UZa5Eg7g0gJVlI5ZPyL7Xn6LW77r4mFElTB+WPWjnOlnGVXhKZrcf J5JGv1KWtIjrNBn57Awyorvy0RjOu67R65F/4ml2qnxnu853VTIvv1Qn8ZKcKmTLwfQjUuckXFS kO9QP+k8Fb8akXBSa9iWJK3iy2rCc2DDuLaIB0eNNlMeooH7PC3paI7SMnppTCnN16 X-Google-Smtp-Source: AGHT+IHPhPo4ZaImxeWHezBdiLWw0Kg5zYqNxd7ZHFHXKZ0GQdkHTZ0XdZ1PRkD6scz28JTnAtxJ+g== X-Received: by 2002:a05:6a20:918c:b0:366:14ac:e1fa with SMTP id adf61e73a8af0-366e31b9cefmr595130637.76.1765328109363; Tue, 09 Dec 2025 16:55:09 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:09 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v7 22/26] ipa: simple: Add a flag to indicate gpuIspEnabled Date: Wed, 10 Dec 2025 00:53:50 +0000 Message-ID: <20251210005354.44726-23-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 06f93ee0f..1aa4357ad 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 10 00:53:51 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: 25440 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 990EDC3257 for ; Wed, 10 Dec 2025 00:55:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4DF6C614A6; Wed, 10 Dec 2025 01:55:15 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="AAq/x05d"; dkim-atps=neutral Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 67FD861428 for ; Wed, 10 Dec 2025 01:55:13 +0100 (CET) Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-7aab061e7cbso7963369b3a.1 for ; Tue, 09 Dec 2025 16:55:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328112; x=1765932912; 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=2pApn0Ftt225wj2OFxj2PTyD+pMbuHYXyYVVwJZOq28=; b=AAq/x05drupwWeYcsdPh5R2sKb+TN2FA7G2e/1CVmkNyWgFdP6DGR0c+o8wWJ7ClZw zvS9lflN1I53kPmI/LyRpl0ECkDOZZFqjd7I6Epd8U7Vwr03SE/dzRPpdhXhE7i4Yguh Ge8yvpl7GefbLa6HbfxQk7ad20uahnffFiiV+x7gYv1CSzJnDFmHoIqdxLp26aYQcVya A0q/5uODOV3osRQs/TkNpx/ZqJArXZXT/TR+KV4ZGN8VsNejx3u4xUMB4TtEzucoPlZF gjWXkj7Yzkp44UPyKc0cbn1wPIoz0eHH1k+s9bWgraWUV5mqcaZLTx1ehb9vdrW3BkEI 2Lew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328112; x=1765932912; 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=2pApn0Ftt225wj2OFxj2PTyD+pMbuHYXyYVVwJZOq28=; b=TzW+lVUelkmsYhkNepcLfutq2xSvlmhkyDprFQxfo2/L7HWa7jdG83CRqqL4Xoqlwg EHbZxZmLxV7NQxwAZRZNsz/83RyFwRMuO7XawBIY3aCOohQPPW0LT0vV8YBQ3NaRqtmF LUOoo66stkJRC9guq7VX6iDo4IfGkIVKPOCnpM3+Gm3u4Jpl5MCRaHFK2j3m2SnPhdZd NrYfkXi9JdoWbGI/Pkw84TSbwpTmWkCnY/dw6MhmJgE4UrJKH7arwUj+jkLCN0CXjSsq 3mMkD/i6cubdMnB+bW26bqqR05o9sNHD+7rlEJ70K+gpsZbTs2s7PaeGfvJIWccyjO1D KUNQ== X-Gm-Message-State: AOJu0YzyYe3qeXLbgtiMpGrYmMD6CLMxjEexE9QdVvEsJH4gxCAfA/wo NPZR7wWfW5ZYPYv9dBsuxqdU8rqp01b9fUz5NBnzEg4/xQCZcIFRuKnaes1N1Sy/HBl30/6mu5N ZshO2 X-Gm-Gg: ASbGncs7tGfFK/xWqJzlo1aD1A9XRK+h6GzT5H0/DUF3a9B2S9SGeLiRD7HxevIfjXs le1kEgXLm7rvyw0wabVRPRxmvChskjYfqXYDQXAHX/urWmEUhcvCJXOeHfbe2bGO/4CiCWqyRnR 1RtZ6ZbKHTimuL3vDVtvRJkHmkTPQ+bcmKQmXYkqUo/Odt6tnJo83/YOvatAzfiNAQQNUJpUxm4 +0KRHPGcoG/eSMbe7ZJwqSUPHUkuy40o2Iy4hJY/j+X0Wt5o/xHy6Av428/BFjp4y6G9mZ8NgTU qBHjIHk3I0rARSPaDCfpp1gszBMNIihUnplI48bcPNNnhnxQE/f6xHo0ljegaJnbFeg4gZO9sLH chLzKbi/h/xKMzrpxptk94k1cRT77JT04Ghi4WOkrUtN+qfm0KnOsgKIYtmuzQLIqhwesgaM3uy 5pURucKOBMx1VQo6M+r531LyfFWSlFAJQj3AA8wU3TDIcJJOrUwpMGljVoRWSLht0UJE5aRkKNS O8= X-Google-Smtp-Source: AGHT+IGA06gB+1oMIloJDZVkRFnyg7ZhApxoEZ73yhbnExiP9phfWzkaoUSSpUP3iI04NZX0zspdaA== X-Received: by 2002:a05:6a20:7faa:b0:359:d00b:45f4 with SMTP id adf61e73a8af0-366e244f015mr527869637.52.1765328111771; Tue, 09 Dec 2025 16:55:11 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:11 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v7 23/26] ipa: software_isp: Call createSelfEnumeratingAlgorithm() to statically instantiate CCM algo Date: Wed, 10 Dec 2025 00:53:51 +0000 Message-ID: <20251210005354.44726-24-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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" Signed-off-by: Bryan O'Donoghue --- src/ipa/simple/soft_simple.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index 2bbe271d9..d5474bb7a 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -137,6 +137,12 @@ int IPASoftSimple::init(const IPASettings &settings, if (ret) return ret; + if (context_.gpuIspEnabled && !data->contains("ccm")) { + ret = createSelfEnumeratingAlgorithm(context_, std::string("Ccm")); + if (ret) + return ret; + } + *ccmEnabled = context_.ccmEnabled; params_ = nullptr; From patchwork Wed Dec 10 00:53:52 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: 25441 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 2363FC3257 for ; Wed, 10 Dec 2025 00:55:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D182A614A3; Wed, 10 Dec 2025 01:55:18 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="qZ0WmSzy"; dkim-atps=neutral Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 53F5A614A0 for ; Wed, 10 Dec 2025 01:55:16 +0100 (CET) Received: by mail-pf1-x42e.google.com with SMTP id d2e1a72fcca58-7b8bbf16b71so6887963b3a.2 for ; Tue, 09 Dec 2025 16:55:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328115; x=1765932915; 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=qZ0WmSzyvPwGdP5nyUjvS0LcH+CXYT433ZREIHCgYhxAhpPHX4Vu0vXdRC/WjffxX0 ndGSDM58YTkXe3++gKllmbC3AHLVtArIHjMWCG+8HYDdy2oyQb+2/ximBD72Mng1l1QU sT7FwNQWUyNWGy7rqWag+eIJxlA40yVT3FlHT688lNtuYXTuVRsRamL/NS8zPXKmq9WL qzMyvxVfWiNt8i/X0tQa6s5sLvmyaqR6WL8hExwCrYQAyKKIZmk1A24KN/pTVa1Qgi5u nFXL29LQb5dS+teBsVb9aqGLEu4yoczJskb1XDvjqCeA+Tw6UFelCJ4nsd2ZiqisdsUC spng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328115; x=1765932915; 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=B7L+wYC/3yRKq0CJZpQYhlwi1YLeQO+SWd2LU6zHgkkewlDu/YeECwt1TymMAkog6B 6HUe5NC3ZB4DhL47UewYJzFrvEdC17vpO34gM0WR0GQVQpmD8Kiw+g74o7LtQNOdvlET x8fX1ewc3kQ0Swt+4lmJreXKOF3kEz6QiA6WR8HtwyUg7yxUa5qigFbLP/ThCBL2YPdw GxryV9v5uQU3KTWJOsIvnohv526Ov9gGTInUC7wx4suc4RKryEN6bsSxvmxCyEM3i/ba 35cz3VbGxEBd4z/w3J3lx5y6aFM4SDg5nQGcKImsh8r8UpttGepxK9mKMpbt9KKKM9tp 2Oag== X-Gm-Message-State: AOJu0YzDeHQujTxRdVL7NHglUMRA4zJqoGxXcy7vJGuquLd5UtmpeJ1n GhGAm8TaS9ijXSJWj5pbAfztHlZhd3xKqj+kB0iJqERmPzy1cQnFRNFveY33UVbaxZGW3ZITM19 ypbf5 X-Gm-Gg: ASbGncsyYUaVQuACRdLzJTOs57icwEg3tkA/fCM0VScTMGmXGNb0ezRZmMPBZuEYQgu /Rob4OsCn2t/ia/9bFGA1KfaX4NAn+3TOVGUqTkTtvTUutmtvp+pkRS67kVNxTqJFDz9g4I5vuY f5MnRazvZRphjVfx2X3JRi6N5r3uHhaZAe3ysSrGsAtVBMwjaGfEoH369cNO1GHBu2DUhHfHDEa 4CTRXJRJWmwp79sMVOLeN0pVgw7EL2faLhoFfmB3tNFxeAvQnyVUajEBtRZyPfc1aSYtJOk/4RG WeoCrebqsNDhpCKn+3GfiVIYXFstEDMu6itReX4KpaDVcBvI8057WvPaOyyhXJ9yfv5YhGwCiBd xz0VTnFzZSrEhADW9nxIeFAk6NHxGpWHPLdb2ue8qktQp87EMUJf2m5ETsclqn3wdUK/IgPU9Zx jUAan0U+KE4x9aOgAD41BmN2AYevSWlPmamhbnvlVFfXsU1+7He4jJd3bslb3367Ck X-Google-Smtp-Source: AGHT+IEIhWExzt6GfB5dVk76vELMHuBy7GkUEXM4GCaeNsCmdfcAJ6rYcBEhVH0aRKVXwEwxBkRVIw== X-Received: by 2002:a05:6a21:328f:b0:34e:1009:4216 with SMTP id adf61e73a8af0-366e0dea492mr561778637.24.1765328114542; Tue, 09 Dec 2025 16:55:14 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:13 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Milan Zamazal Subject: [PATCH v7 24/26] libcamera: software_isp: lut: Skip calculation lookup tables if gpuIspEnabled is true Date: Wed, 10 Dec 2025 00:53:52 +0000 Message-ID: <20251210005354.44726-25-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 10 00:53:53 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: 25442 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 A1B02C3257 for ; Wed, 10 Dec 2025 00:55:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 586B1614A7; Wed, 10 Dec 2025 01:55:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ppoGcx+3"; dkim-atps=neutral Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 29501614A6 for ; Wed, 10 Dec 2025 01:55:19 +0100 (CET) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-7acd9a03ba9so6767303b3a.1 for ; Tue, 09 Dec 2025 16:55:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328117; x=1765932917; 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=NauU1uWfSPSZd8EiGg8FTzmSYzjHvu/p8kn7jtnbOq8=; b=ppoGcx+3drTanGQTvIM5mmL5jrQxdNvfAeGIH/XKTRmUsRlPdf3OHTc0XNvCauuzK0 JAHVC3dv3t5Z4djXVPx+jSpBSfLoaEek20Cy1R0dOTgM6qe8q7b35oO0f0k4rE8PxSmb rIX/VkT7na6i91D/2o0dH1vEO+vPT27Xv4ASAPB57AuNh4M0iJcxRUJI35tRKuLIOI4c +0ahSCiZ3xhxKLFLW1dJyxxbbE33kJxSnpemqDXUA6BiTQbpjZ8q0sgkUIp3NLCLrKG4 DM8kJjC3bQwRlTd77I6BzoviRypoVAnebpTJ42zKH6Q/26cS8xjGf0e99md774FHJiys 3k9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328117; x=1765932917; 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=NauU1uWfSPSZd8EiGg8FTzmSYzjHvu/p8kn7jtnbOq8=; b=GUuy7qsNRgcvGrnjUPocD8iBVyg1cbTLnbxpL+T0vcLvsKG81rGxisRtiV3X4+Cq+y XlOkG2LG0mMCcP1NAG74xy2dIsXDJxzn1p0GQWNpddlqZQd5oK17SrMYFoHDbOIANRgE CyylzImGjha+riyBF2sOJxA2A2xj0urrM9FB1/l5u6tK6rtC1CzCKFiCg1ib8QN25yjQ curvIMIep/+8Kdg9hqJPn9U0eTYptHY1p7Popp08kVEzNDRM4UyQCI56Fb28rE07XkET k02kYxAFMZBWEWZAvb63xrQh654+7E03mW6n4ciafQPpjhUNPnAdzWNZ39APpHgorI89 OJvg== X-Gm-Message-State: AOJu0YzHcKl10P7OyAXIkXQpD6XSFeaT5baxIyLCL/cE48BjnItFhlT5 Qwq1Rev3ec65m30UQIxzkYibzhYMEhRSn8Pfrzcxa3CNbH1HYMEhI0OZqVnNbi8cjebsWc53WKB llhb9 X-Gm-Gg: ASbGncucPOXR20djdvbWW+WgoiiKRnsyGKuuypyy5Ll6vfRYO0hoCg6QKBnkxNS/CK2 ZOCKBS0IPju7jB6Ihro00Fsr6xkpIjB1qsFTD7JJgUDkeg7R/QLg5m2PSZhSx1CxfwwMO8dwGuk EacUeZU6hH/rK4UnY7BbfquyCouY2FrtCwWEsr5ROv1rc38u7EOW34GonDLZmaTFwIxwmCR/K2k HfC9pRqKNRPhKq4pyiHs1MtuJRmkoEdKcLA0s3VzmMfJzKpzfSIuhRckiuWU1jDPFyOoqKKAlG1 NSUtod/38i2tqPj9280AAwPIeWPCy9iOXfhlKYorMy6KIKGbs8AZYZcQfKEGhjsS0tsIqaWW/ga nZwq3smLJOkX/ojyY8xYlCTghh2NQoRRJMWq2v69jZuwUkiQrBy7YPc73LctBy2yAmkaIL2XxvA jzrcuZIomXhZ9WrPcvLEzCWyCL5bGiQOdI99LeXFCStV9lC/M3Jy9X1zNYS2YsP/WNEiuaPG8AK mc= X-Google-Smtp-Source: AGHT+IHVZZwsP1tb5+PTWqnPvYS8APXQhj4+F1T8U0zmMdhF3F/BgWHbdud1pYcSX3XhlFjhZL3BvA== X-Received: by 2002:a05:6a20:3ca1:b0:35d:bb66:5ce3 with SMTP id adf61e73a8af0-366e07de6f9mr512845637.12.1765328117463; Tue, 09 Dec 2025 16:55:17 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:16 -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 v7 25/26] libcamera: software_isp: lut: Change default Gamma to 1.0/2.2 Date: Wed, 10 Dec 2025 00:53:53 +0000 Message-ID: <20251210005354.44726-26-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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..618219b17 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 10 00:53:54 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: 25443 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 7EC52C3257 for ; Wed, 10 Dec 2025 00:55:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2C57A614AF; Wed, 10 Dec 2025 01:55:24 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="XjboH+zu"; dkim-atps=neutral Received: from mail-pf1-x42c.google.com (mail-pf1-x42c.google.com [IPv6:2607:f8b0:4864:20::42c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A6E88614A0 for ; Wed, 10 Dec 2025 01:55:21 +0100 (CET) Received: by mail-pf1-x42c.google.com with SMTP id d2e1a72fcca58-7e2762ad850so6529116b3a.3 for ; Tue, 09 Dec 2025 16:55:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1765328120; x=1765932920; 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=ajdHqIYvkWHsZzgWfrEnNcPGftSQ9L7WA4FF/krfdgY=; b=XjboH+zuECeF7OTpwbDjEvFqjW9sdWDtwCbhavyB3a5QQLyV+SrsAXoFgVE4acJp+F dX9F62LkpZFpqrMiU1oofbjsDNfOQgKHadiQjOnRPuH+o9FMwJHELx7myjQEMIt2YY7I C7Lgpgei+Kv/XE11cTiemkAXb3WIQVY4NgIJny/R5KTg5Q/IRyiSeO6FkGRPZID+uJwR tQq7iiLGLe2vprD0MUrUIdGI1Lpe10WPFv5e8QqSN/JvzMDbjDFXZ5uyGP1a6r3THuaP +TKKcIBBoTCggem50Xsdo7qFRGsXhH0Vdwt9urcOGzajbGeB0eOJgPaWFCQo698QsbnB vD1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765328120; x=1765932920; 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=ajdHqIYvkWHsZzgWfrEnNcPGftSQ9L7WA4FF/krfdgY=; b=XEOSXzpZGC2j4kfYL6X26LcIk4FOOADtoLRcLOpbW/Y6PrNGbthb0q8HdyB8lVvS+/ tPi8aJdiDyr92TVAuYuxwwdWEljsZUO3TYwYCz3zgbnMBzWZq/gAW8F8eJ1zxZFLK8vE yq9U4C11h4PnQHXKTx6YN/uk99FcVvgp/d399dJ/g3kMlWdB1S8GfzVcdWmcCvFGcLGa 1Cu+WJqAUTT624dGJ25O4ddCyJCrIUm3U0CmIHdojDxaG4FAcyxf9WrSGWMUvpT7C/15 FVKJHE2heTpZ88tkHTLLifZPQPHuBachCj8BuRb0l0f0fVvdMm5r27LQLOMZVwRXg+U9 1dPw== X-Gm-Message-State: AOJu0YynSgYAj+IVGB2JqoDd1exAMF04YGkHqiJ9cYgokmy8KzaXY29h 6lKL3ijWzL15/3feRUM3+8w16LPMDZfBWoxupumnCqfT8Siw489E11+SzKtn9EP3AWUH7Q7NQzB rkDeQ X-Gm-Gg: ASbGncujXTbxOM0yLD+KHQKMYYqbSHutX90yaTlH0gpWZhKWpVuyp0yLwFn/dzV5j9f TpKQxcA7l7xdpwoU4wKIIUOgTgrcEld1CRPqDm8lTVQMuhgxbTd2aWke5sybB8Rj2qxEUm1ucVq AYj2dI95AeFrzPmdSoKW9sKfibHaUOb5DJ1t8wn6tKte0gqXOw96xC+7UApTp/db/KE10Nymv05 KMOgT9R7I4UtfMz9bYDLbQrhrEifwupYbpWYvFo7HHb921wjnCV3VzML1Juz6Q1rb77gaerWVDu AkaG0XS81kpZl8RxjqDF3pK6YBiNe+uIX4bR5Uz+uzXQEl5cCJHet4Ig4ntqm4KZR54CU8wJuMf P52q9JXNNOdw6GzMfUqEEXpZrhyCRWTA4rXe8ZjY5Xy6aI4T2aw5IYGHJcrI7vPUdwjJjXRubFA b8Z2jU/ySBh/swf+PkSPHuzDnRKmsIjxKlhf6P74wY+XNCrF5hZCDYjgnHTZA7MzIj X-Google-Smtp-Source: AGHT+IF0umI0JI9WWFj1XJfHMnHGh8J6MRIMMowI15nR/2IsdQn4VoGCjya2uexQFNVr/IA/19pBYA== X-Received: by 2002:a05:6a20:3d95:b0:366:14ac:e1f5 with SMTP id adf61e73a8af0-366e2fc1b7amr509243637.71.1765328119996; Tue, 09 Dec 2025 16:55:19 -0800 (PST) Received: from inspiron14p-linux (p96936b06.osaknt01.ap.so-net.ne.jp. [150.147.107.6]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-bf6875cc8eesm16057762a12.16.2025.12.09.16.55.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Dec 2025 16:55:19 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue , Kieran Bingham Subject: [PATCH v7 26/26] libcamera: software_isp: Add a gpuisp todo list Date: Wed, 10 Dec 2025 00:53:54 +0000 Message-ID: <20251210005354.44726-27-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251210005354.44726-1-bryan.odonoghue@linaro.org> References: <20251210005354.44726-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 --- 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..b9910d17d --- /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 rewriging the idea is to have a list + of algorithms as is done in cpuisp iterating through the + list in a for() loop. + - The logic manging 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 implment compute shader to do this. + +Lense flare correction: + - Not WIP still TBD