Patch Detail
Show a patch.
GET /api/patches/27103/?format=api
{ "id": 27103, "url": "https://patchwork.libcamera.org/api/patches/27103/?format=api", "web_url": "https://patchwork.libcamera.org/patch/27103/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260629163017.863145-25-barnabas.pocze@ideasonboard.com>", "date": "2026-06-29T16:29:47", "name": "[RFC,v1,24/54] libcamera: request: Remove fence support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "5df19438186bf090b6c27e0d9b455590eaa8777f", "submitter": { "id": 216, "url": "https://patchwork.libcamera.org/api/people/216/?format=api", "name": "Barnabás Pőcze", "email": "barnabas.pocze@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/27103/mbox/", "series": [ { "id": 6025, "url": "https://patchwork.libcamera.org/api/series/6025/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=6025", "date": "2026-06-29T16:29:23", "name": "libcamera: Split requests and buffers", "version": 1, "mbox": "https://patchwork.libcamera.org/series/6025/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/27103/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/27103/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 782A2C3261\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 29 Jun 2026 16:31:13 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EE3F165F62;\n\tMon, 29 Jun 2026 18:31:11 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6911365F4A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Jun 2026 18:30:26 +0200 (CEST)", "from pb-laptop.local (185.221.140.128.nat.pool.zt.hu\n\t[185.221.140.128])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4AA8E8D4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Jun 2026 18:29:43 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"dBozKsfz\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1782750583;\n\tbh=12oFyoKAW4MODUKyk8bIBhs5scOxY/rAvy72r05GWkc=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=dBozKsfzM35H/sNeSBSXHfj+KjxONVZ9VTX2Aqbn3HkEmoyYndkWz909r8VwppmkN\n\tut50dBaNs7aYBNEQgpqBpIQaARK86H+oEhgurfZ+Aqti2MK5FKrNROVDU5tOs1M1/A\n\t5kl9DQ6oF0chWbb1fk/bJcDyXoTLmmz9m33ilZ2s=", "From": "=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Subject": "[RFC PATCH v1 24/54] libcamera: request: Remove fence support", "Date": "Mon, 29 Jun 2026 18:29:47 +0200", "Message-ID": "<20260629163017.863145-25-barnabas.pocze@ideasonboard.com>", "X-Mailer": "git-send-email 2.54.0", "In-Reply-To": "<20260629163017.863145-1-barnabas.pocze@ideasonboard.com>", "References": "<20260629163017.863145-1-barnabas.pocze@ideasonboard.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "With the split of buffers and requests, fences will need to be handled outside\nof requests. So remove the current fence support, all the miscellaneous things\nrelated to it:\n * Request::{prepared,prepared_}\n * PipelineHandler::registerRequest()\n\nSigned-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n---\n include/libcamera/internal/pipeline_handler.h | 1 -\n include/libcamera/internal/request.h | 15 --\n src/libcamera/camera.cpp | 7 +-\n src/libcamera/fence.cpp | 5 -\n src/libcamera/framebuffer.cpp | 10 +-\n src/libcamera/pipeline_handler.cpp | 24 +---\n src/libcamera/request.cpp | 131 ------------------\n 7 files changed, 5 insertions(+), 188 deletions(-)", "diff": "diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\nindex 81ec359981..f90cae253f 100644\n--- a/include/libcamera/internal/pipeline_handler.h\n+++ b/include/libcamera/internal/pipeline_handler.h\n@@ -59,7 +59,6 @@ public:\n \tvoid stop(Camera *camera);\n \tbool hasPendingRequests(const Camera *camera) const;\n \n-\tvoid registerRequest(Request *request);\n \tvoid queueRequest(Request *request);\n \n \tstatic bool completeBuffer(Request *request, FrameBuffer *buffer)\ndiff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h\nindex 382ed28bca..8f570e4f79 100644\n--- a/include/libcamera/internal/request.h\n+++ b/include/libcamera/internal/request.h\n@@ -7,19 +7,13 @@\n \n #pragma once\n \n-#include <chrono>\n-#include <map>\n-#include <memory>\n #include <stdint.h>\n #include <unordered_set>\n \n #include <libcamera/base/event_notifier.h>\n-#include <libcamera/base/timer.h>\n \n #include <libcamera/request.h>\n \n-using namespace std::chrono_literals;\n-\n namespace libcamera {\n \n class Camera;\n@@ -43,26 +37,17 @@ public:\n \tvoid cancel();\n \tvoid reset();\n \n-\tvoid prepare(std::chrono::milliseconds timeout = 0ms);\n-\tSignal<> prepared;\n-\n private:\n \tfriend class PipelineHandler;\n \tfriend std::ostream &operator<<(std::ostream &out, const Request &r);\n \n \tvoid doCancelRequest();\n-\tvoid emitPrepareCompleted();\n-\tvoid notifierActivated(FrameBuffer *buffer);\n-\tvoid timeout();\n \n \tCamera *camera_;\n \tbool cancelled_;\n \tuint32_t sequence_ = 0;\n-\tbool prepared_ = false;\n \n \tstd::unordered_set<FrameBuffer *> pending_;\n-\tstd::map<FrameBuffer *, EventNotifier> notifiers_;\n-\tstd::unique_ptr<Timer> timer_;\n \tControlList metadata_;\n };\n \ndiff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\nindex 31ab59e0b7..27dae3a403 100644\n--- a/src/libcamera/camera.cpp\n+++ b/src/libcamera/camera.cpp\n@@ -1294,12 +1294,7 @@ std::unique_ptr<Request> Camera::createRequest(uint64_t cookie)\n \tif (ret < 0)\n \t\treturn nullptr;\n \n-\tstd::unique_ptr<Request> request = std::make_unique<Request>(this, cookie);\n-\n-\t/* Associate the request with the pipeline handler. */\n-\td->pipe_->registerRequest(request.get());\n-\n-\treturn request;\n+\treturn std::make_unique<Request>(this, cookie);\n }\n \n /**\ndiff --git a/src/libcamera/fence.cpp b/src/libcamera/fence.cpp\nindex 73299b4027..92d1b37366 100644\n--- a/src/libcamera/fence.cpp\n+++ b/src/libcamera/fence.cpp\n@@ -28,8 +28,6 @@ namespace libcamera {\n * the Fence to be signalled before allowing the camera device to actually\n * access the memory area described by the FrameBuffer.\n *\n- * \\sa Request::addBuffer()\n- *\n * By using a fence, applications can then synchronize between frame buffer\n * consumers and producers, as for example a display device and a camera, to\n * guarantee that a new data transfers only happen once the existing frames have\n@@ -68,9 +66,6 @@ namespace libcamera {\n *\n * A failure in waiting for a Fence to complete will result in the Request to\n * complete in failed state.\n- *\n- * \\sa Request::prepare()\n- * \\sa PipelineHandler::doQueueRequests()\n */\n \n /**\ndiff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp\nindex baa298a8e3..55ca24c8a3 100644\n--- a/src/libcamera/framebuffer.cpp\n+++ b/src/libcamera/framebuffer.cpp\n@@ -191,9 +191,7 @@ FrameBuffer::Private::~Private()\n *\n * If buffer with a Fence completes with errors due to a failure in handling\n * the fence, applications are responsible for releasing the Fence before\n- * calling Request::addBuffer() again.\n- *\n- * \\sa Request::addBuffer()\n+ * reusing the buffer.\n *\n * \\return A const pointer to the Fence if any, nullptr otherwise\n */\n@@ -203,15 +201,13 @@ FrameBuffer::Private::~Private()\n * \\brief Move a \\a fence in this buffer\n * \\param[in] fence The Fence\n *\n- * This function associates a Fence with this Framebuffer. The intended caller\n- * is the Request::addBuffer() function.\n+ * This function associates a Fence with this Framebuffer. It is only intended\n+ * to be called by the libcamera core.\n *\n * Once a FrameBuffer is associated with a Fence, the FrameBuffer will only be\n * made available to the hardware device once the Fence has been correctly\n * signalled.\n *\n- * \\sa Request::prepare()\n- *\n * If the FrameBuffer completes successfully the core releases the Fence and the\n * Buffer can be reused immediately. If handling of the Fence fails during the\n * request preparation, the Fence is not released and is left in the\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex 54ef8296a4..29a21a0d70 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -7,7 +7,6 @@\n \n #include \"libcamera/internal/pipeline_handler.h\"\n \n-#include <chrono>\n #include <sys/stat.h>\n #include <sys/sysmacros.h>\n \n@@ -443,25 +442,6 @@ bool PipelineHandler::hasPendingRequests(const Camera *camera) const\n \treturn !camera->_d()->queuedRequests_.empty();\n }\n \n-/**\n- * \\fn PipelineHandler::registerRequest()\n- * \\brief Register a request for use by the pipeline handler\n- * \\param[in] request The request to register\n- *\n- * This function is called when the request is created, and allows the pipeline\n- * handler to perform any one-time initialization it requries for the request.\n- */\n-void PipelineHandler::registerRequest(Request *request)\n-{\n-\t/*\n-\t * Connect the request prepared signal to notify the pipeline handler\n-\t * when a request is ready to be processed.\n-\t */\n-\trequest->_d()->prepared.connect(this, [this, request]() {\n-\t\tdoQueueRequests(request->_d()->camera());\n-\t});\n-}\n-\n /**\n * \\fn PipelineHandler::queueRequest()\n * \\brief Queue a request\n@@ -493,7 +473,7 @@ void PipelineHandler::queueRequest(Request *request)\n \tCamera::Private *data = camera->_d();\n \tdata->waitingRequests_.push(request);\n \n-\trequest->_d()->prepare(300ms);\n+\tdoQueueRequests(camera);\n }\n \n /**\n@@ -533,8 +513,6 @@ void PipelineHandler::doQueueRequests(Camera *camera)\n \t\t\tbreak;\n \n \t\tRequest *request = data->waitingRequests_.front();\n-\t\tif (!request->_d()->prepared_)\n-\t\t\tbreak;\n \n \t\t/*\n \t\t * Pop the request first, in case doQueueRequests() is called\ndiff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\nindex 8a3934add3..8819ba0ce3 100644\n--- a/src/libcamera/request.cpp\n+++ b/src/libcamera/request.cpp\n@@ -7,7 +7,6 @@\n \n #include \"libcamera/internal/request.h\"\n \n-#include <map>\n #include <sstream>\n \n #include <libcamera/base/log.h>\n@@ -155,8 +154,6 @@ void Request::Private::doCancelRequest()\n \n \tcancelled_ = true;\n \tpending_.clear();\n-\tnotifiers_.clear();\n-\ttimer_.reset();\n }\n \n /**\n@@ -187,135 +184,7 @@ void Request::Private::reset()\n {\n \tsequence_ = 0;\n \tcancelled_ = false;\n-\tprepared_ = false;\n \tpending_.clear();\n-\tnotifiers_.clear();\n-\ttimer_.reset();\n-}\n-\n-/*\n- * Helper function to save some lines of code and make sure prepared_ is set\n- * to true before emitting the signal.\n- */\n-void Request::Private::emitPrepareCompleted()\n-{\n-\tprepared_ = true;\n-\tprepared.emit();\n-}\n-\n-/**\n- * \\brief Prepare the Request to be queued to the device\n- * \\param[in] timeout Optional expiration timeout\n- *\n- * Prepare a Request to be queued to the hardware device by ensuring it is\n- * ready for the incoming memory transfers.\n- *\n- * This currently means waiting on each frame buffer acquire fence to be\n- * signalled. An optional expiration timeout can be specified. If not all the\n- * fences have been signalled correctly before the timeout expires the Request\n- * is cancelled.\n- *\n- * The function immediately emits the prepared signal if all the prepare\n- * operations have been completed synchronously. If instead the prepare\n- * operations require to wait the completion of asynchronous events, such as\n- * fences notifications or timer expiration, the prepared signal is emitted upon\n- * the asynchronous event completion.\n- *\n- * As we currently only handle fences, the function emits the prepared signal\n- * immediately if there are no fences to wait on. Otherwise the prepared signal\n- * is emitted when all fences have been signalled or the optional timeout has\n- * expired.\n- *\n- * If not all the fences have been correctly signalled or the optional timeout\n- * has expired the Request will be cancelled and the Request::prepared signal\n- * emitted.\n- *\n- * The intended user of this function is the PipelineHandler base class, which\n- * 'prepares' a Request before queuing it to the hardware device.\n- */\n-void Request::Private::prepare(std::chrono::milliseconds timeout)\n-{\n-\t/* Create and connect one notifier for each synchronization fence. */\n-\tfor (FrameBuffer *buffer : pending_) {\n-\t\tconst Fence *fence = buffer->_d()->fence();\n-\t\tif (!fence)\n-\t\t\tcontinue;\n-\n-\t\tauto [it, inserted] = notifiers_.try_emplace(buffer, fence->fd().get(), EventNotifier::Type::Read);\n-\t\tASSERT(inserted);\n-\n-\t\tit->second.activated.connect(this, [this, buffer] {\n-\t\t\tnotifierActivated(buffer);\n-\t\t});\n-\t}\n-\n-\tif (notifiers_.empty()) {\n-\t\temitPrepareCompleted();\n-\t\treturn;\n-\t}\n-\n-\t/*\n-\t * In case a timeout is specified, create a timer and set it up.\n-\t *\n-\t * The timer must be created here instead of in the Request constructor,\n-\t * in order to be bound to the pipeline handler thread.\n-\t */\n-\tif (timeout != 0ms) {\n-\t\ttimer_ = std::make_unique<Timer>();\n-\t\ttimer_->timeout.connect(this, &Request::Private::timeout);\n-\t\ttimer_->start(timeout);\n-\t}\n-}\n-\n-/**\n- * \\var Request::Private::prepared\n- * \\brief Request preparation completed Signal\n- *\n- * The signal is emitted once the request preparation has completed and is ready\n- * to be queued. The Request might complete with errors in which case it is\n- * cancelled.\n- *\n- * The intended slot for this signal is the PipelineHandler::doQueueRequests()\n- * function which queues Request after they have been prepared or cancel them\n- * if they have failed preparing.\n- */\n-\n-void Request::Private::notifierActivated(FrameBuffer *buffer)\n-{\n-\t/* Close the fence if successfully signalled. */\n-\tASSERT(buffer);\n-\tbuffer->releaseFence();\n-\n-\t/* Remove the entry from the map and check if other fences are pending. */\n-\tauto it = notifiers_.find(buffer);\n-\tASSERT(it != notifiers_.end());\n-\tnotifiers_.erase(it);\n-\n-\tRequest *request = _o<Request>();\n-\tLOG(Request, Debug)\n-\t\t<< \"Request \" << request->cookie() << \" buffer \" << buffer\n-\t\t<< \" fence signalled\";\n-\n-\tif (!notifiers_.empty())\n-\t\treturn;\n-\n-\t/* All fences completed, delete the timer and emit the prepared signal. */\n-\ttimer_.reset();\n-\temitPrepareCompleted();\n-}\n-\n-void Request::Private::timeout()\n-{\n-\t/* A timeout can only happen if there are fences not yet signalled. */\n-\tASSERT(!notifiers_.empty());\n-\tnotifiers_.clear();\n-\n-\tRequest *request = _o<Request>();\n-\tLOG(Request, Debug) << \"Request prepare timeout: \" << request->cookie();\n-\n-\tcancel();\n-\n-\temitPrepareCompleted();\n }\n #endif /* __DOXYGEN_PUBLIC__ */\n \n", "prefixes": [ "RFC", "v1", "24/54" ] }