From patchwork Wed Jun 24 08:58:40 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: 27027 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 7F52CC3306 for ; Wed, 24 Jun 2026 08:59:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 39B126587E; Wed, 24 Jun 2026 10:59:03 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="R1B/fOe+"; dkim-atps=neutral Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5186765871 for ; Wed, 24 Jun 2026 10:59:01 +0200 (CEST) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-490cf322ed0so7761855e9.1 for ; Wed, 24 Jun 2026 01:59:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1782291541; x=1782896341; 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=6h4OQ/s+gFr1NSlfpnHCoeE5/7D8tFJMOobc3VjW2hA=; b=R1B/fOe+2nUG5dz2edWTBmjuBLAHWEY6BsVHKYWtEZK6UMsqCrwAhvcHwkuRpTXblZ ShuNuq4V8VWx2sW2CvR8FLy5hsZXkbwb0zEh4p0qGI7WIoIwcQfEarh0CRLxavNrLdcM RaaHCcE+j8xDzlWM05Wxe6U1l2krcjfT3z/P84qUsp7HfPzBgYCoa8I29e9W4heDzxCR MUaaLmbVHVIzBFES57YXNy72fD08/DdopZ0B8NePvESdRWjprz5nbIJ9+vlb+C1SNC/9 h72BpV8tOBOnt74wIpI/A72gcIQrzS15s7osZA46lFA2KJ30WrZaBtgCOOItKnE1TFKE IVxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782291541; x=1782896341; 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=6h4OQ/s+gFr1NSlfpnHCoeE5/7D8tFJMOobc3VjW2hA=; b=MMo+za2IsLETtJPw/ogFaZHhVEwkk2RwM6oHXxBIu7QOcgZPaLhTTtMzWhKZvohdRg YHiW4uMDOV54Bq6qORd3ud3le84sQe8+5erWGAWbtzxYn4S74E5cQHcrB8xfLy18TrBr K3yXMmW2a3ImPXYFCUY6Sm1YzPToXRzAFRmp1iN5WGH6E4bkDC8u2Ut0/CyI+xZSpwBL PCKflktVtMAvsuRBqNpYeR2zQwblmXgDnw5hltPcpCVmBPKZNvGCkbe5cBNAfgxkDsuo 6Sg1Ew7iwPa1PfaHTGvWJp9xLzlkHp4CQt1sGEg0bc/ZFbbbUtkUB3lbOg1p3odmKYtP wEbw== X-Gm-Message-State: AOJu0Ywm7PQFnVYZHTvW0BczBIipH3tzgayWkR5SQ4Q5G0CeHcjZp1jR FUd1vXJl4kx0ht7eHK/rP55hGbYpvCVM3iYErc1pKT6E3RVePv+yGzTGJbBEVSEkovIJkrVLja4 Ta4JqQ8o= X-Gm-Gg: AfdE7ckKlJwO5v8aOXdJdDHcG9atO0n2wTUDOLIeCsaOF4sF2bv/VyDgN9upYyu5DxL Wb41igmbU0omeCxDSCdZJAs/vRSXkSijzmsqOt6vQUhB5cIfQpNRMKvpoyAXCh1RbqyD2jrAcZX LzPue0N9NicR17Tz/dY49mJ+SMM/nbjUUvC0PyEguAGvcFw3YDzhVkpu/mow/76tFdgCVHzVgxP rDdQpQzuP/GL/yEqskmZvwR6i9IS+MkbT3UwWhtT9ut5+7NWcJAaQfX83vVQmPGTcKYa0s1tfY0 WIopxEfP/rG0zyYG/MXdlXoTh85vLveNQO0JI7/gRkm13cgOOJ89ktA9aDig0ynJtKsU3QzVUa9 6cm7ayM8cHAbyA00RqNaF2G4IJ/GS5sqn82F4RP5kZgDdoBG2pvpBwY8daK48hm/Yj1YAaldFun X9lIZD8C/SvZT/lmmUc0086nYbGYwIPSQvW2arYdo= X-Received: by 2002:a05:600c:c494:b0:492:5a58:3c6a with SMTP id 5b1f17b1804b1-492608496d5mr29809635e9.5.1782291540786; Wed, 24 Jun 2026 01:59:00 -0700 (PDT) Received: from inspiron14p-linux ([109.76.100.231]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49261063d6esm25128375e9.2.2026.06.24.01.58.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Jun 2026 01:58:59 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz Subject: [PATCH 01/10] libcamera: v4l2_videodevice: Output cache hit as a parameter Date: Wed, 24 Jun 2026 09:58:40 +0100 Message-ID: <20260624085849.873784-2-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260624085849.873784-1-bryan.odonoghue@linaro.org> References: <20260624085849.873784-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" The existing V4L2BufferCache::get routine evaluates if a cache hit has occured by way of an internal variable. It is in fact very useful to a user of this API to understand if a hit has occured as using logic may wish to differentiate based on hit or miss. This differentiation is required for GPUISP. Rather than add a routine to interrogate if a cache hit exists - add an output parameter to the get routine. In simple terms if you are trying to cache data about the last thing you want to to is interrogate the cache twice so, a `hit` output parameter adds a small cost in the stack for a large pivot in using code's ability to understand how much work it needs to do on hit v miss. Signed-off-by: Bryan O'Donoghue Reviewed-by: Robert Mader --- include/libcamera/internal/v4l2_videodevice.h | 2 +- src/libcamera/v4l2_videodevice.cpp | 9 ++++++--- test/v4l2_videodevice/buffer_cache.cpp | 14 +++++++++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 10367e4e1..49165a565 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -129,7 +129,7 @@ public: ~V4L2BufferCache(); bool isEmpty() const; - int get(const FrameBuffer &buffer); + int get(const FrameBuffer &buffer, bool &hit); void put(unsigned int index); private: diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index ca8759830..6496eb324 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -217,6 +217,7 @@ bool V4L2BufferCache::isEmpty() const /** * \brief Find the best V4L2 buffer for a FrameBuffer * \param[in] buffer The FrameBuffer + * \param[out] hit. Indicates if there was a cache hit * * Find the best V4L2 buffer index to be used for the FrameBuffer \a buffer * based on previous mappings of frame buffers to V4L2 buffers. If a free V4L2 @@ -227,12 +228,13 @@ bool V4L2BufferCache::isEmpty() const * \return The index of the best V4L2 buffer, or -ENOENT if no free V4L2 buffer * is available */ -int V4L2BufferCache::get(const FrameBuffer &buffer) +int V4L2BufferCache::get(const FrameBuffer &buffer, bool &hit) { - bool hit = false; int use = -1; uint64_t oldest = UINT64_MAX; + hit = false; + for (unsigned int index = 0; index < cache_.size(); index++) { const Entry &entry = cache_[index]; @@ -1649,6 +1651,7 @@ int V4L2VideoDevice::queueBuffer(FrameBuffer *buffer, const V4L2Request *request { struct v4l2_plane v4l2Planes[VIDEO_MAX_PLANES] = {}; struct v4l2_buffer buf = {}; + bool hit; int ret; if (state_ == State::Stopping) { @@ -1666,7 +1669,7 @@ int V4L2VideoDevice::queueBuffer(FrameBuffer *buffer, const V4L2Request *request return -ENOENT; } - ret = cache_->get(*buffer); + ret = cache_->get(*buffer, hit); if (ret < 0) return ret; diff --git a/test/v4l2_videodevice/buffer_cache.cpp b/test/v4l2_videodevice/buffer_cache.cpp index 613e0d7ce..e41c30059 100644 --- a/test/v4l2_videodevice/buffer_cache.cpp +++ b/test/v4l2_videodevice/buffer_cache.cpp @@ -35,7 +35,8 @@ public: { for (unsigned int i = 0; i < buffers.size() * 100; i++) { int nBuffer = i % buffers.size(); - int index = cache->get(*buffers[nBuffer].get()); + bool hit; + int index = cache->get(*buffers[nBuffer].get(), hit); if (index != nBuffer) { std::cout << "Expected index " << nBuffer @@ -60,7 +61,8 @@ public: for (unsigned int i = 0; i < buffers.size() * 100; i++) { int nBuffer = dist(generator_); - int index = cache->get(*buffers[nBuffer].get()); + bool hit; + int index = cache->get(*buffers[nBuffer].get(), hit); if (index < 0) { std::cout << "Failed lookup from cache" @@ -90,7 +92,8 @@ public: /* Pick a hot buffer at random and store its index. */ int hotBuffer = dist(generator_); - int hotIndex = cache->get(*buffers[hotBuffer].get()); + bool hit; + int hotIndex = cache->get(*buffers[hotBuffer].get(), hit); cache->put(hotIndex); /* @@ -106,7 +109,7 @@ public: else nBuffer = dist(generator_); - index = cache->get(*buffers[nBuffer].get()); + index = cache->get(*buffers[nBuffer].get(), hit); if (index < 0) { std::cout << "Failed lookup from cache" @@ -135,7 +138,8 @@ public: for (const auto &buffer : buffers) { FrameBuffer &b = *buffer.get(); - cache.get(b); + bool hit; + cache.get(b, hit); } if (cache.isEmpty())