From patchwork Tue Jan 6 17:00:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 25654 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 980EFBDCC0 for ; Tue, 6 Jan 2026 17:01:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4014461FD2; Tue, 6 Jan 2026 18:01:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="vLUBsVcU"; dkim-atps=neutral Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6E74461FD3 for ; Tue, 6 Jan 2026 18:01:04 +0100 (CET) Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-42e2ba54a6fso452598f8f.3 for ; Tue, 06 Jan 2026 09:01:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1767718864; x=1768323664; 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=e2IR4ED7mZBKvzF2+iSu2ko6YvEmnv4sI3xsTCm2tIc=; b=vLUBsVcUHBTD0Beet/DLK4iXvhjniL6I2Pv2LokpIlXHcPb0WALOQWkK+CR6wj8iZe kD9BWdoyaHmCRD2HLNXHgpvW8J2tGfIR/Hgu9TnPsUHq0nNiARUxOuJ6MgdfIcgSN5pc le/ma5ha0tyJOxzTSTcKcourgdrvbvLi326Zd5C1B6g/uLDgiJeuGZZmrUs2vSR8WPq3 v7Sy0UJkxPMyQ70pKdgD8uwKQ7qCvNaRSoQrokei9XlpCRk/RRjOy+8LwWTUp4Zlj/JL 7n3iVWbs+6eYTJZnahSPlLDPhmyBcteAqEX6ftNhExUES7Wo+dG9JHrVnRBw7Nx1FABv PE/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767718864; x=1768323664; 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=e2IR4ED7mZBKvzF2+iSu2ko6YvEmnv4sI3xsTCm2tIc=; b=IxKbXiDylvpIYkUItSQcWHZ+EwaMR3N4SS8N4unEtSKwtZ32TFcO/3ivAwpNHy9hdW qJBTpjWwnuCljp3msfccksxQrXtL0DBcEEBv6XOt2jMbieP9c7mxdp+6zhh2/RxP95vD WIAtlRcpt1ddiwOPdJQ4AvTtNArk459oM6vO4Vs75vpff9k2e63L0mkbKqd2s0bUL0Bq bpUWQ9uP67vKPtARrebSi5T6gbCq55HRvnd3Umm7Kwxj/7ja2qcDovUhwXH7/LFzWzod LUGgpP90bSUYuDzR5GyqpLoO1wwibrXoLqy8eqMIrM52tZ6m9ZP6zqfoTEqGP08Kbp8A co9Q== X-Gm-Message-State: AOJu0YwvKjjylOWIIWP/MXagXOHe9IR3Vy2hojJVpDENVYrByHxTg+9Y tm/gpeeaJCA72u8BhAxm7gYiUGaAJFDX9CS5UYLfdN/60G2tRze+8/zGCEjo/gbRAy2PUfobsTI pMLIQubU= X-Gm-Gg: AY/fxX6bQortH9sQSl05kqba3YGpfqLa/vdjqsiWm+RnzyflH1MrHAVlUUh64ElJSXQ auwVm6XxMsQk00LeM5+j21PRxROg2ML/fbYHGVdnZC8ViwbPI0Tl8cYn3SAIMhSHx8cxxjObJjs 7UN6pjScyG8txQfiqS5/5gKu80fthufn3y1vuyRn+1MVAf+nwxQJEOpCPaFVsFL4MO3oiEdH8V2 Iw5S9ffQtxk/QWugMpLizQwHEjn8M88QZKnqsR6zPhM3EGvdDCJVuCKE1mKo3oMXaxZEIfVxuZK XM+bWdgKzIN+thHYQ7cr3YYXfiA5CCipA83qlWpa9IpAee+p0s5d9TE2Y+HTbFkgNMeZ1JlRJGJ Q1QJriwHpl2LxJl3hUrpBUgkYf5XJg1bluq3xkGjvs9zDGb+t40TDgIwwhbQSQphZ68dFK6Yp5E OZxWxbRcdGybKE6WhpwpHl5m6KE0ssY98E7smD2FtgbaatLAjvZWtLBwHLR8+RuoDIqZGKPQHvY MOOlA== X-Google-Smtp-Source: AGHT+IGsKCOZevJxuVFhiZ4nEsUD4nZvvJFjoLkfdNsFDgiKFBw0XcyaA8paUH3t4s4eTkU1FF6weA== X-Received: by 2002:a05:6000:2305:b0:431:c60:c5ed with SMTP id ffacd0b85a97d-432bca19d80mr4913791f8f.13.1767718863521; Tue, 06 Jan 2026 09:01:03 -0800 (PST) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-432bd0dadcfsm5515322f8f.3.2026.01.06.09.01.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jan 2026 09:01:03 -0800 (PST) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: pavel@ucw.cz, Bryan O'Donoghue Subject: [PATCH v11 01/24] libcamera: software_isp: debayer: Latch contrastExp not contrast to debayer parameters Date: Tue, 6 Jan 2026 17:00:36 +0000 Message-ID: <20260106170059.56193-2-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260106170059.56193-1-bryan.odonoghue@linaro.org> References: <20260106170059.56193-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" Pass contrastExp as calculated in lut to debayer params not the raw contrast. This way we calculate contrastExp once per frame in lut and pass the calculated value into the shaders, instead of passing contrast and calculating contrastExp once per pixel in the shaders. Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal --- include/libcamera/internal/software_isp/debayer_params.h | 2 +- src/ipa/simple/algorithms/lut.cpp | 7 ++++--- src/ipa/simple/ipa_context.h | 1 + src/libcamera/software_isp/debayer.cpp | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h index 8033f7d5b..256c7d43d 100644 --- a/include/libcamera/internal/software_isp/debayer_params.h +++ b/include/libcamera/internal/software_isp/debayer_params.h @@ -59,7 +59,7 @@ struct DebayerParams { Matrix ccm; RGB blackLevel; float gamma; - float contrast; + double contrastExp; }; } /* namespace libcamera */ diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index 9aaab54f1..7d015ac89 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -60,12 +60,13 @@ void Lut::updateGammaTable(IPAContext &context) 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); + /* 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)); 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); @@ -84,7 +85,7 @@ void Lut::updateGammaTable(IPAContext &context) gammaTable[blackIndex]); context.activeState.gamma.blackLevel = blackLevel; - context.activeState.gamma.contrast = contrast; + context.activeState.gamma.contrastExp = contrastExp; } int16_t Lut::ccmValue(unsigned int i, float ccm) const @@ -149,7 +150,7 @@ void Lut::prepare(IPAContext &context, } params->gamma = context.configuration.gamma; - params->contrast = context.activeState.gamma.contrast; + params->contrastExp = context.activeState.gamma.contrastExp; } void Lut::process([[maybe_unused]] IPAContext &context, diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index 26b60fb68..7837bb4dd 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -59,6 +59,7 @@ struct IPAActiveState { std::array gammaTable; uint8_t blackLevel; double contrast; + double contrastExp; } gamma; struct { diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index b33f818a7..4cb5b4da4 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -116,7 +116,7 @@ namespace libcamera { */ /** - * \var DebayerParams::contrast + * \var DebayerParams::contrastExp * \brief Contrast value for GPUISP */