From patchwork Thu Oct 15 19:43:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ray Strode X-Patchwork-Id: 28464 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 1CF04C3358 for ; Thu, 15 Oct 2026 19:49:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EB3B568E25; Thu, 15 Oct 2026 21:49:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="h7eMFUP0"; dkim-atps=neutral Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7001C68E06 for ; Thu, 15 Oct 2026 21:43:49 +0200 (CEST) Received: by mail-qk1-x72b.google.com with SMTP id af79cd13be357-93e515769d3so485449785a.3 for ; Thu, 15 Oct 2026 12:43:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1792093428; x=1792698228; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=WdaCS6Me9+EDOfggmdbddTpHPzRokVqnY8F5ni21u8Q=; b=h7eMFUP0+ChhB+MGZS/jQHWu0LO8P95+DAmZafANdDdLWHShjSh7umrI8b0i4vdvNc WfEupKsAaq/bGSLNMs1X6YAxGvqC074jKjHyPSSit8+di6vVyux7TaG6Gf/5amAeC7dc tcU9CAy+K3GaachYQBEqzrV7jZb4DEsDujhuZ5kh7yu5EJnm7tLkk27KRYaQs57JFSgg Z0mL/GC1BYjCwCpIkKcnw2s1r2BTyq9ScDR7zQ2lNdvh0Q/tmaq4cJllsBGrOxq+rmYZ OraUWCt+8xdD4NWddukMtefoQtT5KeWwqmW8GJO+LsUN4Zv3i1bhl0c6ye4Xxoq4+aqh DfMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792093428; x=1792698228; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=WdaCS6Me9+EDOfggmdbddTpHPzRokVqnY8F5ni21u8Q=; b=bY5LgIfLbL8UMm+WYWspKF4lC6JNW5OsZzhnL4eBR0oLJZnLu3Ra4oVjXbUgA2+3t+ 6r2N5pjzeLXnpvM1hPffkh7ybzQzGD4CWoALXBIAO42scH205RUdCr54ElMiyA0IFa7V 1neyEVEHzFLmv6/WqSrMzcY4PvG4uLC+xLhu30pIl1AkFJQGt4UEpWLX57swV/ryjSmr G1D/SWDmAlRaeJ3Vl5ZI89eRL4b683kEQQ5EBKBzqSxDEs3dp9GP3DOkWuAYOxutmNGr 23p+bf9ZOxvvLUhDapBlnQfKFSxjVOu8XfVx5QExNpO1ee5zhbX+ICH2X1AGsP97fWHG pMNA== X-Gm-Message-State: AFq9FYKaOBmVmX5YlCaHYkKsQHkJaOBPdiBfX1vxhP7ktl3yxi30Rj0q szfBU3BJmwUNYQvzAVQl/996nPgjzuPGYIhi7w0eKC1L9BowkAG5FtOy/nuea/zTFMg= X-Gm-Gg: AYBFou1GpBWf1E3ckSVmcVE9k0dtiRNC4tJAPA5czgDuv9ty54BO8YlBJs7f3lDB7r5 uXCAZRzWEYC6VBgx6i1VzPSBbpFfnPgpbMDsRSCsweFmqe/zXFfqD4XnXKLMi8qa3mBeSSfWQZe MNOd6nT52b5SySmyZzGVFzrmNrrn8dHj/VlFqH8cQ8fAEuyYAELIsoX9F1saC/4NGy+itxdB2YH 8OYWVzwog+Fve9rAq5iXR50lVO5y7kwtYgd8ruZeyvR37sW/C9gKsNaPiSbccgfh6vKJswjPT53 J9CB1MSAIyWGGCqG002xPDa7xj8/zoqmLOn8xEqXP90QCuEyTOJJIJlmCyWNNiJZxKWZArQ8WSw rVR7y6OGCPofHvCRkiODLFg6f4NzhuRFwZhgi5SuRAY7XhbvWoOhlzP7HVZBVXUNFgua1Z6GUoX E5APCW7t9AWkLuF2Nk1Oi2vE+/pf4UEhph8trVMRrPTDJx43hRNTEzewk+FE1y8Blt8PoQFupA+ 0JC++kMhL9SEvyS8ZYvg1yw+A== X-Received: by 2002:a05:620a:45a8:b0:93f:290:c217 with SMTP id af79cd13be357-93f0290c79emr1115306085a.50.1792093428117; Thu, 15 Oct 2026 12:43:48 -0700 (PDT) Received: from localhost ([144.121.52.163]) by smtp.gmail.com with ESMTPSA id af79cd13be357-93f1a18176esm15370385a.20.2026.10.15.12.43.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Oct 2026 12:43:47 -0700 (PDT) From: Ray Strode To: libcamera-devel@lists.libcamera.org Subject: [PATCH 3/4] software-isp: Meter the visible sensor crop Date: Thu, 15 Oct 2026 15:43:34 -0400 Message-ID: <20261015194335.287960-4-halfline@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261015194335.287960-1-halfline@gmail.com> References: <20261015194335.287960-1-halfline@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 15 Oct 2026 21:49:41 +0200 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: Ray Strode The GPU debayer path draws a centered sensor crop into the requested output size, while CPU statistics read the original input buffer. The statistics window still follows the output dimensions, so metering covers a different part of the sensor when output sizes or aspect ratios change. This commit derives the visible crop in sensor coordinates and centers the statistics window on that region. Signed-off-by: Ray Strode --- src/libcamera/software_isp/debayer_egl.cpp | 14 ++++---------- src/libcamera/software_isp/debayer_egl.h | 1 - 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 0f515c5e..3335eaf9 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -295,72 +295,66 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, 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; } const 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; nativeOutputSize_ = outSizeRange.max; - 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. + * The GPU scales the visible sensor crop to outputSize_. Statistics + * consume the original input buffer, so use sensor coordinates here. */ - stats_->setWindow(Rectangle(window_.size())); + const Size visibleSize = nativeOutputSize_.boundedToAspectRatio(outputSize_); + stats_->setWindow(visibleSize.centeredTo(Rectangle(inputCfg.size).center())); inputBufferCount_ = inputCfg.bufferCount; outputBufferCount_ = outputCfg.bufferCount; 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) { diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 30e51a47..52b8aa07 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -84,41 +84,40 @@ private: /* Shader parameters */ float firstRed_x_; float firstRed_y_; GLint attributeVertex_; GLint attributeTexture_; GLint textureUniformStep_; GLint textureUniformSize_; GLint textureUniformStrideFactor_; GLint textureUniformBayerFirstRed_; GLint textureUniformProjMatrix_; GLint textureUniformBayerDataIn_; /* Per-frame AWB gains */ GLint awbUniformDataIn_; /* 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 contrastExpUniformDataIn_; Size nativeOutputSize_; - Rectangle window_; std::unique_ptr stats_; eGL egl_; uint32_t width_; uint32_t height_; GLint glFormat_; unsigned int bytesPerPixel_; uint32_t shaderStridePixels_; }; } /* namespace libcamera */