[{"id":38949,"web_url":"https://patchwork.libcamera.org/comment/38949/","msgid":"<1f2ecbc0-d553-438a-b6be-e4a724bdb1a1@nxsw.ie>","date":"2026-05-26T17:22:10","subject":"Re: [PATCH v2 2/2] debayer_egl: Sync output buffers after processing\n\tstats","submitter":{"id":226,"url":"https://patchwork.libcamera.org/api/people/226/","name":"Bryan O'Donoghue","email":"bod.linux@nxsw.ie"},"content":"On 26/05/2026 09:06, Robert Mader wrote:\n> Instead of waiting for the GPU to finish output buffers *before* computing\n> stats, do so afterwards. This allows work to happen in parallel on the GPU\n> and CPU, improving throughput and reducing latency on various devices as\n> shown below.\n> \n> On order for this to work well we need to flush all GL commands to the\n> GPU before doing heavy CPU work - thus add a corresponding function.\n> \n> Below are some benchmark results. All where done using postmarketOS edge\n> with updates from 21th May 2026 (Mesa 26.1.1). The mentioned pipelines\n> where run five times each, with the mean value included here, which should\n> be quite representive as the variance was rather small. All devices\n> where using the powersave governor.\n> \n> Notes:\n> 1. We only expect changes for frames where stats get computed, currently\n>     every fourth frame (see kStatPerNumFrames) - and the improvements indeed\n>     have been observed to increase when computing stats more often.\n> 2. At least the qcom/freedreno devices have been found to be affected by a\n>     performance issue *without* this patch. This issue can be worked\n>     around by calling `glFlush()` directly before `glFinish()` - as done\n>     in v1 of this series - or by running with `GALLIUM_THREAD=0`. The\n>     benchmarks below show the performance gains *with* those workarounds\n>     applied in order to not inflate the impact of this patch. See\n>     https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15516 for more\n>     context.\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a -s width=1920,height=1080 --capture=60\n> Before: 33596 us/frame\n> After: 30179 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@1/camera@1a -s width=1920,height=1080 --capture=60\n> Before: 14922 us/frame\n> After: 14304 us/frame\n> \n> cam -c /base/soc@0/cci@ac4b000/i2c-bus@1/camera@10 -s width=1920,height=1080 --capture=60\n> Before: 26106 us/frame\n> After: 23312 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@1/camera@29 -s width=1920,height=1080 --capture=60\n> Before: 15897 us/frame\n> After: 14791 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@1/camera@10 -s width=1920,height=1080 --capture=60\n> Before: 25721 us/frame\n> After: 23625 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@0/camera@10 -s width=1920,height=1080 --capture=60\n> Before: 34124 us/frame\n> After: 29471 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a -s width=1920,height=1080 --capture=60\n> Before: 23707 us/frame\n> After: 21890 us/frame\n> \n> cam -c /base/soc@0/bus@30800000/i2c@30a40000/camera@20 -s width=1280,height=720 --capture=60\n> Before: 91649 us/frame\n> After: 83233 us/frame\n> \n> cam -c /base/soc@0/bus@30800000/i2c@30a50000/camera@2d -s width=1280,height=720 --capture=60\n> Before: 76956 us/frame\n> After: 69569 us/frame\n> \n> cam -c /base/i2c-csi/front-camera@3c -s width=1280,height=720 --capture=60\n> Before: 188500 us/frame\n> After: 173764 us/frame\n> \n> cam -c /base/i2c-csi/rear-camera@4c -s width=1280,height=720 --capture=60\n> Before: 190222 us/frame\n> After: 177251 us/frame\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> ---\n>   include/libcamera/internal/egl.h           |  1 +\n>   src/libcamera/egl.cpp                      | 13 +++++++++++++\n>   src/libcamera/software_isp/debayer_egl.cpp |  3 ++-\n>   3 files changed, 16 insertions(+), 1 deletion(-)\n> \n> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n> index 0ad2320b1..0ec8ea6ec 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -119,6 +119,7 @@ public:\n>   \tvoid useProgram(GLuint programId);\n>   \tvoid deleteProgram(GLuint programId);\n>   \tvoid syncOutput();\n> +\tvoid flushOutput();\n> \n>   private:\n>   \tLIBCAMERA_DISABLE_COPY_AND_MOVE(eGL)\n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n> index 357918711..19ae92305 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -97,6 +97,19 @@ void eGL::syncOutput()\n>   \tglFinish();\n>   }\n> \n> +/**\n> + * \\brief Flush the rendering pipeline\n> + *\n> + * Calls glFlush().\n> + *\n> + */\n> +void eGL::flushOutput()\n> +{\n> +\tASSERT(tid_ == Thread::currentId());\n> +\n> +\tglFlush();\n> +}\n> +\n>   /**\n>    * \\brief Create a DMA-BUF backed 2D texture\n>    * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index ed9a68013..7b9e02d90 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -521,7 +521,7 @@ int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParam\n>   \t\tLOG(eGL, Error) << \"Drawing scene fail \" << err;\n>   \t\treturn -ENODEV;\n>   \t} else {\n> -\t\tegl_.syncOutput();\n> +\t\tegl_.flushOutput();\n>   \t}\n> \n>   \treturn 0;\n> @@ -558,6 +558,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>   \tstats_->processFrame(frame, 0, input);\n>   \tdmaSyncers.clear();\n> \n> +\tegl_.syncOutput();\n>   \tbench_.finishFrame();\n> \n>   \toutputBufferReady.emit(output);\n> --\n> 2.54.0\n> \n\nReviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n\n---\nbod","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 334DBC328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 May 2026 17:22:20 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5847B62FD3;\n\tTue, 26 May 2026 19:22:19 +0200 (CEST)","from mail-4317.protonmail.ch (mail-4317.protonmail.ch\n\t[185.70.43.17])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 10C8962FB1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 May 2026 19:22:17 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=nxsw.ie header.i=@nxsw.ie header.b=\"cXG8Rj+D\";\n\tdkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxsw.ie;\n\ts=protonmail; t=1779816136; x=1780075336;\n\tbh=EK5iUAQiVQzcRel2SGukptE+Kg0gYWs4TNi1JENOmPU=;\n\th=Date:To:From:Subject:Message-ID:In-Reply-To:References:\n\tFeedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID:\n\tMessage-ID:BIMI-Selector;\n\tb=cXG8Rj+DQZshSIKA6Umfmfg8dskRhZyOoSqYP3AkHfTq0BDBLnk0wR22cLU536XaI\n\tGgtHAacZq7+MyW0plEI0DOsemS9uBKul51KccMKNQ5tdlFFc/GAmetepm/tM1fP2Ch\n\teRtN0jz6rHxZoWtzZdvBWdBBzK1wBtrWVFWa+4mRCnJWlk3LffzjK+AnXvnhqegl/J\n\tbRjpz+L2QODSZHyd3jy5YnqfbmPADRTrLR+dT7iNiIE0Rnkf9uPMOYSgu/qHZsvAB7\n\twqZ2px10YZsu/Sk3MjpMbgcito9aIL/KI8cdKtZQErxnM2oF3QLTgJf8FkJyLMzHmA\n\tDgup7gfWnwqNg==","Date":"Tue, 26 May 2026 17:22:10 +0000","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","From":"Bryan O'Donoghue <bod.linux@nxsw.ie>","Subject":"Re: [PATCH v2 2/2] debayer_egl: Sync output buffers after processing\n\tstats","Message-ID":"<1f2ecbc0-d553-438a-b6be-e4a724bdb1a1@nxsw.ie>","In-Reply-To":"<20260526080639.70173-3-robert.mader@collabora.com>","References":"<20260526080639.70173-1-robert.mader@collabora.com>\n\t<20260526080639.70173-3-robert.mader@collabora.com>","Feedback-ID":"136405006:user:proton","X-Pm-Message-ID":"d2c1721d05a7935e6f66d3f9d252165712dee6b9","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"quoted-printable","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>"}},{"id":38957,"web_url":"https://patchwork.libcamera.org/comment/38957/","msgid":"<177986894833.3918214.16285846959153858776@ping.linuxembedded.co.uk>","date":"2026-05-27T08:02:28","subject":"Re: [PATCH v2 2/2] debayer_egl: Sync output buffers after processing\n\tstats","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Robert Mader (2026-05-26 09:06:39)\n> Instead of waiting for the GPU to finish output buffers *before* computing\n> stats, do so afterwards. This allows work to happen in parallel on the GPU\n> and CPU, improving throughput and reducing latency on various devices as\n> shown below.\n> \n> On order for this to work well we need to flush all GL commands to the\n> GPU before doing heavy CPU work - thus add a corresponding function.\n> \n> Below are some benchmark results. All where done using postmarketOS edge\n> with updates from 21th May 2026 (Mesa 26.1.1). The mentioned pipelines\n> where run five times each, with the mean value included here, which should\n> be quite representive as the variance was rather small. All devices\n> where using the powersave governor.\n> \n> Notes:\n> 1. We only expect changes for frames where stats get computed, currently\n>    every fourth frame (see kStatPerNumFrames) - and the improvements indeed\n>    have been observed to increase when computing stats more often.\n> 2. At least the qcom/freedreno devices have been found to be affected by a\n>    performance issue *without* this patch. This issue can be worked\n>    around by calling `glFlush()` directly before `glFinish()` - as done\n>    in v1 of this series - or by running with `GALLIUM_THREAD=0`. The\n>    benchmarks below show the performance gains *with* those workarounds\n>    applied in order to not inflate the impact of this patch. See\n>    https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15516 for more\n>    context.\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a -s width=1920,height=1080 --capture=60\n> Before: 33596 us/frame\n> After: 30179 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@1/camera@1a -s width=1920,height=1080 --capture=60\n> Before: 14922 us/frame\n> After: 14304 us/frame\n> \n> cam -c /base/soc@0/cci@ac4b000/i2c-bus@1/camera@10 -s width=1920,height=1080 --capture=60\n> Before: 26106 us/frame\n> After: 23312 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@1/camera@29 -s width=1920,height=1080 --capture=60\n> Before: 15897 us/frame\n> After: 14791 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@1/camera@10 -s width=1920,height=1080 --capture=60\n> Before: 25721 us/frame\n> After: 23625 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@0/camera@10 -s width=1920,height=1080 --capture=60\n> Before: 34124 us/frame\n> After: 29471 us/frame\n> \n> cam -c /base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a -s width=1920,height=1080 --capture=60\n> Before: 23707 us/frame\n> After: 21890 us/frame\n> \n> cam -c /base/soc@0/bus@30800000/i2c@30a40000/camera@20 -s width=1280,height=720 --capture=60\n> Before: 91649 us/frame\n> After: 83233 us/frame\n> \n> cam -c /base/soc@0/bus@30800000/i2c@30a50000/camera@2d -s width=1280,height=720 --capture=60\n> Before: 76956 us/frame\n> After: 69569 us/frame\n> \n> cam -c /base/i2c-csi/front-camera@3c -s width=1280,height=720 --capture=60\n> Before: 188500 us/frame\n> After: 173764 us/frame\n> \n> cam -c /base/i2c-csi/rear-camera@4c -s width=1280,height=720 --capture=60\n> Before: 190222 us/frame\n> After: 177251 us/frame\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n\nAnd https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1674453\nlooks clear so I'll push these now.\n\n--\nThanks\n\nKieran\n\n\n> ---\n>  include/libcamera/internal/egl.h           |  1 +\n>  src/libcamera/egl.cpp                      | 13 +++++++++++++\n>  src/libcamera/software_isp/debayer_egl.cpp |  3 ++-\n>  3 files changed, 16 insertions(+), 1 deletion(-)\n> \n> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n> index 0ad2320b1..0ec8ea6ec 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -119,6 +119,7 @@ public:\n>         void useProgram(GLuint programId);\n>         void deleteProgram(GLuint programId);\n>         void syncOutput();\n> +       void flushOutput();\n>  \n>  private:\n>         LIBCAMERA_DISABLE_COPY_AND_MOVE(eGL)\n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n> index 357918711..19ae92305 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -97,6 +97,19 @@ void eGL::syncOutput()\n>         glFinish();\n>  }\n>  \n> +/**\n> + * \\brief Flush the rendering pipeline\n> + *\n> + * Calls glFlush().\n> + *\n> + */\n> +void eGL::flushOutput()\n> +{\n> +       ASSERT(tid_ == Thread::currentId());\n> +\n> +       glFlush();\n> +}\n> +\n>  /**\n>   * \\brief Create a DMA-BUF backed 2D texture\n>   * \\param[in,out] eglImage EGL image to associate with the DMA-BUF\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index ed9a68013..7b9e02d90 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -521,7 +521,7 @@ int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParam\n>                 LOG(eGL, Error) << \"Drawing scene fail \" << err;\n>                 return -ENODEV;\n>         } else {\n> -               egl_.syncOutput();\n> +               egl_.flushOutput();\n>         }\n>  \n>         return 0;\n> @@ -558,6 +558,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>         stats_->processFrame(frame, 0, input);\n>         dmaSyncers.clear();\n>  \n> +       egl_.syncOutput();\n>         bench_.finishFrame();\n>  \n>         outputBufferReady.emit(output);\n> -- \n> 2.54.0\n>","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 131A8BDCBC\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 27 May 2026 08:02:34 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 306DB62E6A;\n\tWed, 27 May 2026 10:02:33 +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 C1CFA62E6A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 May 2026 10:02:30 +0200 (CEST)","from monstersaurus.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F00983A2;\n\tWed, 27 May 2026 10:02:11 +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=\"BvIIg6dE\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1779868932;\n\tbh=fqMpyB+y3P4OUVulpGqUI1FQQg29JAkyzA9RdwsNe5I=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=BvIIg6dEXfWRCGlFGvQSTnrNxKw2mhx7MvHYskD0AbO7xw30CQKv1lRr0ylet3MtI\n\tknv++/dnztaMFcjNXsPIZb4OUutSM4qRBgTJI0sLCy3S9rAr5dS9zl0gaSGPUZIvwu\n\twLSDDForjIi5pIlacb7CsIGNbczhn8qLKnLgthpw=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260526080639.70173-3-robert.mader@collabora.com>","References":"<20260526080639.70173-1-robert.mader@collabora.com>\n\t<20260526080639.70173-3-robert.mader@collabora.com>","Subject":"Re: [PATCH v2 2/2] debayer_egl: Sync output buffers after processing\n\tstats","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Robert Mader <robert.mader@collabora.com>","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Wed, 27 May 2026 09:02:28 +0100","Message-ID":"<177986894833.3918214.16285846959153858776@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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>"}}]