[{"id":39869,"web_url":"https://patchwork.libcamera.org/comment/39869/","msgid":"<6adfae94-00aa-47db-8219-7cf0ae7b2231@ideasonboard.com>","date":"2026-07-27T11:27:34","subject":"Re: [PATCH v2] libcamera: egl: Pass EGLDisplay to eGL constructor to\n\tavoid double init","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 07. 27. 8:41 keltezéssel, qi.hou@oss.nxp.com írta:\n> From: Qi Hou <qi.hou@nxp.com>\n> \n> isAvailable() previously called probeDisplay() to run a full EGL\n> initialisation sequence and then immediately terminated the display with\n> eglTerminate(). When SoftwareIsp subsequently created a DebayerEGL\n> instance, initEGLContext() would call probeDisplay() again, repeating\n> the full initialisation.\n> \n> Fix this by reusing the display obtained during the availability check.\n> probeDisplay() is promoted to a public static method and isAvailable()\n> is removed. The eGL constructor now takes the EGLDisplay as a parameter\n> and stores it directly, so initEGLContext() no longer needs to call\n> probeDisplay(). DebayerEGL is updated to accept and forward the display\n> to eGL, and SoftwareIsp calls eGL::probeDisplay() once, passing the\n> result straight to DebayerEGL when EGL is available.\n\nSo this was my suggestion... and of course there is likely an issue. While\nI have checked, and as far as I can tell `eglGetPlatformDisplay()` should work\nwhen called in one thread and used in another; `eglBindAPI()` is directly\nmodifying the thread state, so this change is not ideal (even though it did\nappear to work on mesa).\n\nI'm wondering if `eglGetPlatformDisplay()` and `eglInitialize()` work without\n`eglBindAPI()`, if that's the case, then I think the easy fix is to move the\n`eglBindAPI()` call into `initEGLContext()`.\n\nThe specification (https://registry.khronos.org/EGL/specs/eglspec.1.5.pdf # 3.7) says:\n\n   Some of the functions described in this section make use of the current rendering API, [...]\n   [...]\n   Applications using multiple client APIs are responsible for ensuring the current rendering\n   API is correct before calling the functions eglCreateContext, eglGetCurrentContext,\n   eglGetCurrentDisplay, eglGetCurrentSurface, eglCopyBuffers, eglSwapBuffers, eglSwapInterval,\n   eglMakeCurrent (when its ctx parameter is EGL_NO_CONTEXT), eglWaitClient, or eglWaitNative.\n\nSo I think just moving `eglBindAPI()` should be fine?\n\n\n> \n> Signed-off-by: Qi Hou <qi.hou@nxp.com>\n> ---\n>   include/libcamera/internal/egl.h            |  5 ++-\n>   src/libcamera/egl.cpp                       | 38 +++++++--------------\n>   src/libcamera/software_isp/debayer_egl.cpp  |  5 +--\n>   src/libcamera/software_isp/debayer_egl.h    |  2 +-\n>   src/libcamera/software_isp/software_isp.cpp |  5 +--\n>   5 files changed, 21 insertions(+), 34 deletions(-)\n> \n> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h\n> index 1e31d490b..7ef1ca0d9 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -99,11 +99,11 @@ private:\n>   class eGL\n>   {\n>   public:\n> -\teGL();\n> +\teGL(EGLDisplay display);\n>   \t~eGL();\n>   \n>   \tint initEGLContext();\n> -\tstatic bool isAvailable();\n> +\tstatic EGLDisplay probeDisplay();\n>   \n>   \tint createInputDMABufTexture2D(eGLImage &eglImage, int fd);\n>   \tint createOutputDMABufTexture2D(eGLImage &eglImage, int fd);\n> @@ -137,7 +137,6 @@ private:\n>   \tEGLContext context_ = EGL_NO_CONTEXT;\n>   \tEGLSurface surface_ = EGL_NO_SURFACE;\n>   \n> -\tstatic EGLDisplay probeDisplay();\n>   \tint compileShader(int shaderType, GLuint &shaderId, Span<const unsigned char> shaderData,\n>   \t\t\t  Span<const std::string> shaderEnv);\n>   \n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp\n> index 7ec7a654d..b5ed0e13a 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -64,12 +64,15 @@ LOG_DEFINE_CATEGORY(eGL)\n>   \n>   /**\n>    * \\brief Construct an EGL helper\n> + * \\param[in] display The EGL display to use\n>    *\n>    * Creates an eGL instance with uninitialised context. Call initEGLContext()\n> - * to set up the EGL display, context, and load extension functions.\n> + * to set up the EGL context, and load extension functions.\n>    */\n> -eGL::eGL()\n> +eGL::eGL(EGLDisplay display)\n> +\t: display_(display)\n>   {\n> +\tASSERT(display_ != EGL_NO_DISPLAY);\n>   }\n>   \n>   /**\n> @@ -299,6 +302,13 @@ void eGL::createTexture2D(eGLImage &eglImage, void *data)\n>   \tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n>   }\n>   \n> +/**\n> + * \\brief Try to create an EGL display for surfaceless rendering\n> + *\n> + * Tries to create an EGL display for surfaceless rendering.\n> + *\n> + * \\return A EGL display handle if successful, otherwise \\a EGL_NO_DISPLAY\n> + */\n>   EGLDisplay eGL::probeDisplay()\n>   {\n>   \tEGLDisplay display;\n> @@ -325,24 +335,6 @@ EGLDisplay eGL::probeDisplay()\n>   \treturn display;\n>   }\n>   \n> -/**\n> - * \\brief Probe whether EGL surfaceless rendering is available\n> - *\n> - * Checks if an EGL surfaceless display can be obtained and initialised.\n> - * The display is immediately terminated so that no resources are leaked.\n> - *\n> - * \\return True if EGL surfaceless rendering is available, false otherwise\n> - */\n> -bool eGL::isAvailable()\n> -{\n> -\tEGLDisplay display = probeDisplay();\n> -\tif (display == EGL_NO_DISPLAY)\n> -\t\treturn false;\n> -\n> -\teglTerminate(display);\n> -\treturn true;\n> -}\n> -\n>   /**\n>    * \\brief Update a 2D texture already created\n>    * \\param[in,out] eglImage EGL image to associate with the texture\n> @@ -403,12 +395,6 @@ int eGL::initEGLContext()\n>   \tEGLint numConfigs;\n>   \tEGLConfig config;\n>   \n> -\tdisplay_ = probeDisplay();\n> -\tif (display_ == EGL_NO_DISPLAY) {\n> -\t\tLOG(eGL, Error) << \"Unable to probe display\";\n> -\t\tgoto fail;\n> -\t}\n> -\n>   \tLOG(eGL, Info) << \"EGL: EGL_VERSION: \" << eglQueryString(display_, EGL_VERSION);\n>   \tLOG(eGL, Info) << \"EGL: EGL_VENDOR: \" << eglQueryString(display_, EGL_VENDOR);\n>   \tLOG(eGL, Info) << \"EGL: EGL_CLIENT_APIS: \" << eglQueryString(display_, EGL_CLIENT_APIS);\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index dd2041219..20b478b1c 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -40,9 +40,10 @@ namespace libcamera {\n>    * \\brief Construct a DebayerEGL object\n>    * \\param[in] stats Statistics processing object\n>    * \\param[in] cm The camera manager\n> + * \\param[in] display The EGL display to use\n>    */\n> -DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm)\n> -\t: Debayer(cm), stats_(std::move(stats))\n> +DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm, EGLDisplay display)\n> +\t: Debayer(cm), stats_(std::move(stats)), egl_(display)\n>   {\n>   }\n>   \n> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n> index e613639f5..30e51a477 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -40,7 +40,7 @@ class CameraManager;\n>   class DebayerEGL : public Debayer\n>   {\n>   public:\n> -\tDebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm);\n> +\tDebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm, EGLDisplay display);\n>   \t~DebayerEGL();\n>   \n>   \tint configure(const StreamConfiguration &inputCfg,\n> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n> index c73a16ce0..c7165771c 100644\n> --- a/src/libcamera/software_isp/software_isp.cpp\n> +++ b/src/libcamera/software_isp/software_isp.cpp\n> @@ -120,8 +120,9 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>   \t}\n>   \n>   \tif (!softISPMode || softISPMode == \"gpu\") {\n> -\t\tif (eGL::isAvailable()) {\n> -\t\t\tdebayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm);\n> +\t\tauto display = eGL::probeDisplay();\n> +\t\tif (display != EGL_NO_DISPLAY) {\n> +\t\t\tdebayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm, display);\n>   \t\t} else {\n>   \t\t\tLOG(SoftwareIsp, Info)\n>   \t\t\t\t<< \"EGL not available, falling back to CPU debayer\";","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 57D6EBDE4C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jul 2026 11:27:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9BDFE67F64;\n\tMon, 27 Jul 2026 13:27:38 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4228467EB2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jul 2026 13:27:37 +0200 (CEST)","from [192.168.33.46] (185.182.215.156.nat.pool.zt.hu\n\t[185.182.215.156])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 85CDD492;\n\tMon, 27 Jul 2026 13:26:33 +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=\"L8T02ndU\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1785151593;\n\tbh=pRa86zLWBQIYxsyeHPkEWIfKV7sDTkhVjFiHk1qZY2c=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=L8T02ndUphV/f4NGtsdsjn5cGAbuj8M9WOSXD2lw29JtWRQvgWnAvbQiKv1pzvDy/\n\tS/lpw1bu3pWHIgA1o2Zyp6npd8l0CGQB1RH3Sx5nuPnCVUrP1xj90680wmO+dgAoCR\n\to2tLTUQ0y+q4tOJ2AoxC3kZUXO108FaZb53aBIHk=","Message-ID":"<6adfae94-00aa-47db-8219-7cf0ae7b2231@ideasonboard.com>","Date":"Mon, 27 Jul 2026 13:27:34 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] libcamera: egl: Pass EGLDisplay to eGL constructor to\n\tavoid double init","To":"qi.hou@oss.nxp.com, libcamera-devel@lists.libcamera.org","Cc":"jared.hu@nxp.com, julien.vuillaumier@nxp.com","References":"<20260727064152.2161526-1-qi.hou@oss.nxp.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260727064152.2161526-1-qi.hou@oss.nxp.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","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>"}},{"id":39900,"web_url":"https://patchwork.libcamera.org/comment/39900/","msgid":"<PAXPR04MB82857C4A617FD7CDDDA4CE8397CA2@PAXPR04MB8285.eurprd04.prod.outlook.com>","date":"2026-07-29T02:59:12","subject":"RE: [PATCH v2] libcamera: egl: Pass EGLDisplay to eGL constructor to\n\tavoid double init","submitter":{"id":455,"url":"https://patchwork.libcamera.org/api/people/455/","name":"Qi Hou (OSS)","email":"qi.hou@oss.nxp.com"},"content":"Hi Barnabás Pőcze,\n\nI moved the eglBindAPI() call into initEGLContext(), and test result is fine.\nPatch named as \" [PATCH v3] libcamera: egl: Pass EGLDisplay to eGL constructor to avoid double init\" has been sent out.\n\nRegards,\nQi Hou\n\n-----Original Message-----\nFrom: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> \nSent: Monday, July 27, 2026 7:28 PM\nTo: Qi Hou (OSS) <qi.hou@oss.nxp.com>; libcamera-devel@lists.libcamera.org\nCc: Jared Hu <jared.hu@nxp.com>; Julien Vuillaumier <julien.vuillaumier@nxp.com>\nSubject: Re: [PATCH v2] libcamera: egl: Pass EGLDisplay to eGL constructor to avoid double init\n\n2026. 07. 27. 8:41 keltezéssel, qi.hou@oss.nxp.com írta:\n> From: Qi Hou <qi.hou@nxp.com>\n> \n> isAvailable() previously called probeDisplay() to run a full EGL \n> initialisation sequence and then immediately terminated the display \n> with eglTerminate(). When SoftwareIsp subsequently created a \n> DebayerEGL instance, initEGLContext() would call probeDisplay() again, \n> repeating the full initialisation.\n> \n> Fix this by reusing the display obtained during the availability check.\n> probeDisplay() is promoted to a public static method and isAvailable() \n> is removed. The eGL constructor now takes the EGLDisplay as a \n> parameter and stores it directly, so initEGLContext() no longer needs \n> to call probeDisplay(). DebayerEGL is updated to accept and forward \n> the display to eGL, and SoftwareIsp calls eGL::probeDisplay() once, \n> passing the result straight to DebayerEGL when EGL is available.\n\nSo this was my suggestion... and of course there is likely an issue. While I have checked, and as far as I can tell `eglGetPlatformDisplay()` should work when called in one thread and used in another; `eglBindAPI()` is directly modifying the thread state, so this change is not ideal (even though it did appear to work on mesa).\n\nI'm wondering if `eglGetPlatformDisplay()` and `eglInitialize()` work without `eglBindAPI()`, if that's the case, then I think the easy fix is to move the `eglBindAPI()` call into `initEGLContext()`.\n\nThe specification (https://registry.khronos.org/EGL/specs/eglspec.1.5.pdf # 3.7) says:\n\n   Some of the functions described in this section make use of the current rendering API, [...]\n   [...]\n   Applications using multiple client APIs are responsible for ensuring the current rendering\n   API is correct before calling the functions eglCreateContext, eglGetCurrentContext,\n   eglGetCurrentDisplay, eglGetCurrentSurface, eglCopyBuffers, eglSwapBuffers, eglSwapInterval,\n   eglMakeCurrent (when its ctx parameter is EGL_NO_CONTEXT), eglWaitClient, or eglWaitNative.\n\nSo I think just moving `eglBindAPI()` should be fine?\n\n\n> \n> Signed-off-by: Qi Hou <qi.hou@nxp.com>\n> ---\n>   include/libcamera/internal/egl.h            |  5 ++-\n>   src/libcamera/egl.cpp                       | 38 +++++++--------------\n>   src/libcamera/software_isp/debayer_egl.cpp  |  5 +--\n>   src/libcamera/software_isp/debayer_egl.h    |  2 +-\n>   src/libcamera/software_isp/software_isp.cpp |  5 +--\n>   5 files changed, 21 insertions(+), 34 deletions(-)\n> \n> diff --git a/include/libcamera/internal/egl.h \n> b/include/libcamera/internal/egl.h\n> index 1e31d490b..7ef1ca0d9 100644\n> --- a/include/libcamera/internal/egl.h\n> +++ b/include/libcamera/internal/egl.h\n> @@ -99,11 +99,11 @@ private:\n>   class eGL\n>   {\n>   public:\n> -\teGL();\n> +\teGL(EGLDisplay display);\n>   \t~eGL();\n>   \n>   \tint initEGLContext();\n> -\tstatic bool isAvailable();\n> +\tstatic EGLDisplay probeDisplay();\n>   \n>   \tint createInputDMABufTexture2D(eGLImage &eglImage, int fd);\n>   \tint createOutputDMABufTexture2D(eGLImage &eglImage, int fd); @@ \n> -137,7 +137,6 @@ private:\n>   \tEGLContext context_ = EGL_NO_CONTEXT;\n>   \tEGLSurface surface_ = EGL_NO_SURFACE;\n>   \n> -\tstatic EGLDisplay probeDisplay();\n>   \tint compileShader(int shaderType, GLuint &shaderId, Span<const unsigned char> shaderData,\n>   \t\t\t  Span<const std::string> shaderEnv);\n>   \n> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index \n> 7ec7a654d..b5ed0e13a 100644\n> --- a/src/libcamera/egl.cpp\n> +++ b/src/libcamera/egl.cpp\n> @@ -64,12 +64,15 @@ LOG_DEFINE_CATEGORY(eGL)\n>   \n>   /**\n>    * \\brief Construct an EGL helper\n> + * \\param[in] display The EGL display to use\n>    *\n>    * Creates an eGL instance with uninitialised context. Call \n> initEGLContext()\n> - * to set up the EGL display, context, and load extension functions.\n> + * to set up the EGL context, and load extension functions.\n>    */\n> -eGL::eGL()\n> +eGL::eGL(EGLDisplay display)\n> +\t: display_(display)\n>   {\n> +\tASSERT(display_ != EGL_NO_DISPLAY);\n>   }\n>   \n>   /**\n> @@ -299,6 +302,13 @@ void eGL::createTexture2D(eGLImage &eglImage, void *data)\n>   \tglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n>   }\n>   \n> +/**\n> + * \\brief Try to create an EGL display for surfaceless rendering\n> + *\n> + * Tries to create an EGL display for surfaceless rendering.\n> + *\n> + * \\return A EGL display handle if successful, otherwise \\a \n> +EGL_NO_DISPLAY  */\n>   EGLDisplay eGL::probeDisplay()\n>   {\n>   \tEGLDisplay display;\n> @@ -325,24 +335,6 @@ EGLDisplay eGL::probeDisplay()\n>   \treturn display;\n>   }\n>   \n> -/**\n> - * \\brief Probe whether EGL surfaceless rendering is available\n> - *\n> - * Checks if an EGL surfaceless display can be obtained and initialised.\n> - * The display is immediately terminated so that no resources are leaked.\n> - *\n> - * \\return True if EGL surfaceless rendering is available, false \n> otherwise\n> - */\n> -bool eGL::isAvailable()\n> -{\n> -\tEGLDisplay display = probeDisplay();\n> -\tif (display == EGL_NO_DISPLAY)\n> -\t\treturn false;\n> -\n> -\teglTerminate(display);\n> -\treturn true;\n> -}\n> -\n>   /**\n>    * \\brief Update a 2D texture already created\n>    * \\param[in,out] eglImage EGL image to associate with the texture \n> @@ -403,12 +395,6 @@ int eGL::initEGLContext()\n>   \tEGLint numConfigs;\n>   \tEGLConfig config;\n>   \n> -\tdisplay_ = probeDisplay();\n> -\tif (display_ == EGL_NO_DISPLAY) {\n> -\t\tLOG(eGL, Error) << \"Unable to probe display\";\n> -\t\tgoto fail;\n> -\t}\n> -\n>   \tLOG(eGL, Info) << \"EGL: EGL_VERSION: \" << eglQueryString(display_, EGL_VERSION);\n>   \tLOG(eGL, Info) << \"EGL: EGL_VENDOR: \" << eglQueryString(display_, EGL_VENDOR);\n>   \tLOG(eGL, Info) << \"EGL: EGL_CLIENT_APIS: \" << \n> eglQueryString(display_, EGL_CLIENT_APIS); diff --git \n> a/src/libcamera/software_isp/debayer_egl.cpp \n> b/src/libcamera/software_isp/debayer_egl.cpp\n> index dd2041219..20b478b1c 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -40,9 +40,10 @@ namespace libcamera {\n>    * \\brief Construct a DebayerEGL object\n>    * \\param[in] stats Statistics processing object\n>    * \\param[in] cm The camera manager\n> + * \\param[in] display The EGL display to use\n>    */\n> -DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm)\n> -\t: Debayer(cm), stats_(std::move(stats))\n> +DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm, EGLDisplay display)\n> +\t: Debayer(cm), stats_(std::move(stats)), egl_(display)\n>   {\n>   }\n>   \n> diff --git a/src/libcamera/software_isp/debayer_egl.h \n> b/src/libcamera/software_isp/debayer_egl.h\n> index e613639f5..30e51a477 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -40,7 +40,7 @@ class CameraManager;\n>   class DebayerEGL : public Debayer\n>   {\n>   public:\n> -\tDebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm);\n> +\tDebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager \n> +&cm, EGLDisplay display);\n>   \t~DebayerEGL();\n>   \n>   \tint configure(const StreamConfiguration &inputCfg, diff --git \n> a/src/libcamera/software_isp/software_isp.cpp \n> b/src/libcamera/software_isp/software_isp.cpp\n> index c73a16ce0..c7165771c 100644\n> --- a/src/libcamera/software_isp/software_isp.cpp\n> +++ b/src/libcamera/software_isp/software_isp.cpp\n> @@ -120,8 +120,9 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>   \t}\n>   \n>   \tif (!softISPMode || softISPMode == \"gpu\") {\n> -\t\tif (eGL::isAvailable()) {\n> -\t\t\tdebayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm);\n> +\t\tauto display = eGL::probeDisplay();\n> +\t\tif (display != EGL_NO_DISPLAY) {\n> +\t\t\tdebayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm, \n> +display);\n>   \t\t} else {\n>   \t\t\tLOG(SoftwareIsp, Info)\n>   \t\t\t\t<< \"EGL not available, falling back to CPU debayer\";","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 94CE9C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Jul 2026 02:59:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D12AC67FA2;\n\tWed, 29 Jul 2026 04:59:17 +0200 (CEST)","from MRWPR03CU001.outbound.protection.outlook.com\n\t(mail-francesouthazlp170110003.outbound.protection.outlook.com\n\t[IPv6:2a01:111:f403:c207::3])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C429267EB2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jul 2026 04:59:15 +0200 (CEST)","from PAXPR04MB8285.eurprd04.prod.outlook.com\n\t(2603:10a6:102:1ca::15)\n\tby PA4PR04MB7616.eurprd04.prod.outlook.com (2603:10a6:102:e7::5) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.270.12;\n\tWed, 29 Jul 2026 02:59:12 +0000","from PAXPR04MB8285.eurprd04.prod.outlook.com\n\t([fe80::81d0:4221:c6e5:9b82]) by\n\tPAXPR04MB8285.eurprd04.prod.outlook.com\n\t([fe80::81d0:4221:c6e5:9b82%4]) with mapi id 15.21.0270.009;\n\tWed, 29 Jul 2026 02:59:12 +0000"],"Authentication-Results":["lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=NXP1.onmicrosoft.com\n\theader.i=@NXP1.onmicrosoft.com header.b=\"WxoFK0Us\"; \n\tdkim-atps=neutral","dkim=none (message not signed)\n\theader.d=none;dmarc=none action=none header.from=oss.nxp.com;"],"ARC-Seal":"i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n\tb=lvNXy+WTA7yNI1+yi3YYriVdXADTLM3S1ot57Qg7uFyL3rb4EGyyV1z0dYXZaPN8aPZ1dxjtSTQhM/ZzKWjHGkC0du4iYKICE1m90526vVrq7RBJ5/5LFfyOFhBuxYgwgZvLnqRXw78ef1F5GEvmFJzDK8Az47eIBg971fICw+mmXyzpygVxpNRkOBGoPj9nmQt+KNsDNaTxbbCBCkt6WMdMvRu7zVtjJyO8pAJgyRD0JSWwvLeigf2sY3A38C/h4+DO0wuFdO/tSW5xPuEfMMUy2vDSD0U1TKefBTAC/wQtX0ZgXLRsH6QRoN7RyOrIoEXGmCbBBLDsDRloh4aXXg==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n\ts=arcselector10001;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n\tbh=1x17O/HQNe/fAoDaPWZ/O1hDO7p+hr1O9P7jrnLb/24=;\n\tb=vG+3ii385eJmQIJfKxYCGQmWDRwu9cF4v6ykqkkLPBdXS36FzVAChiFxsB7W+fCBYBbsy95is0lXBdNEqBWsRIIPME/HRFV9/7hV3CGbjWb5/6HTGHqRYtiPdp7CfkwAJdtH1ITpPfnf3Zl5+ORAZVbHXRKRz7fwMJdwZPG8ml4k67w1R1am4or0mO6E1nY9uLlaxU+5cOI3e2L55Y2vFdLEUvHE2fy1YkCpchGs1NDScz14gyZ58R3y5Z2O5SPpILhQH/LVPM6t3TmgaB+VlVNwMQcA9UW8dnYi+rWKNAAtn7GNj1FXeXTRuBMhp8O0w6hO1R91KNygiTXbGRBdzw==","ARC-Authentication-Results":"i=1; mx.microsoft.com 1; spf=pass\n\tsmtp.mailfrom=oss.nxp.com;\n\tdmarc=pass action=none header.from=oss.nxp.com; \n\tdkim=pass header.d=oss.nxp.com; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com;\n\ts=selector1-NXP1-onmicrosoft-com;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=1x17O/HQNe/fAoDaPWZ/O1hDO7p+hr1O9P7jrnLb/24=;\n\tb=WxoFK0UskAFpytebUAwR/U6sn649YMSmzQHw2yO5hDkrHw2eiwUz63iy/UTACGEwl6A9QVXV8XafewJW6aS3uTKYXaV+YVrR4jwd7F18LcokA9drt7IU1S7bUKG+vaKBJWLGLyDQNynQsbeU5Y4I5pmOHY5se7Be5I+PgQsA9MQC83HoihY8M7C/UWBCKIOHStNz6Twi6H+6D3RXTPkPDbCxiXWcCZwBuSNots3ug5NhFfe3vLruTkDv/aRijicWPZqoEAEHYWv3AZItfmQ2RvsPL6Md774Vg25LCwwqjmykf5rVH9grqInb/0Rr3mvJAbo7i42MQAPJQUXh+MCl8A==","From":"\"Qi Hou (OSS)\" <qi.hou@oss.nxp.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\t\"Qi Hou (OSS)\" <qi.hou@oss.nxp.com>,\n\t\"libcamera-devel@lists.libcamera.org\"\n\t<libcamera-devel@lists.libcamera.org>","CC":"Jared Hu <jared.hu@nxp.com>, Julien Vuillaumier\n\t<julien.vuillaumier@nxp.com>","Subject":"RE: [PATCH v2] libcamera: egl: Pass EGLDisplay to eGL constructor to\n\tavoid double init","Thread-Topic":"[PATCH v2] libcamera: egl: Pass EGLDisplay to eGL constructor\n\tto avoid double init","Thread-Index":"AQHdHZMHT3lOE3zLFkSHPB5jKW3i8baBOrAAgAKV2iA=","Date":"Wed, 29 Jul 2026 02:59:12 +0000","Message-ID":"<PAXPR04MB82857C4A617FD7CDDDA4CE8397CA2@PAXPR04MB8285.eurprd04.prod.outlook.com>","References":"<20260727064152.2161526-1-qi.hou@oss.nxp.com>\n\t<6adfae94-00aa-47db-8219-7cf0ae7b2231@ideasonboard.com>","In-Reply-To":"<6adfae94-00aa-47db-8219-7cf0ae7b2231@ideasonboard.com>","Accept-Language":"zh-CN, en-US","Content-Language":"en-US","X-MS-Has-Attach":"","X-MS-TNEF-Correlator":"","authentication-results":["lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=NXP1.onmicrosoft.com\n\theader.i=@NXP1.onmicrosoft.com header.b=\"WxoFK0Us\"; \n\tdkim-atps=neutral","dkim=none (message not signed)\n\theader.d=none;dmarc=none action=none header.from=oss.nxp.com;"],"x-ms-exchange-messagesentrepresentingtype":"1","x-ms-publictraffictype":"Email","x-ms-traffictypediagnostic":"PAXPR04MB8285:EE_|PA4PR04MB7616:EE_","x-ms-office365-filtering-correlation-id":"fcbc9970-3603-417b-b688-08deed1d5e6e","x-ms-exchange-sharedmailbox-routingagent-processed":"True","x-ms-exchange-senderadcheck":"1","x-ms-exchange-antispam-relay":"0","x-microsoft-antispam":"BCL:0;\n\tARA:13230040|376014|366016|19092799006|1800799024|23010399003|6133799003|22082099003|18002099003|38070700021|3023799007|11063799006|4143699003|56012099006|10067099003;","x-microsoft-antispam-message-info":"oYfuH8UQDrv/sQsVsgHkIJEWZatxrsvhIbSrneiPUbMg5gkX17SjXDk79zohbH6J7aOX5wS7u4ToIFAj2np5Q3ERtUSrJ/UD+7pw8J8HiJ/l1R6iBZGN/gNThPB/nvV/XxWb+PndhqaZS4pX3ojjldJlXpN/yRDhGXW3zB5O+VLn7AGcTpcm1f5L1inFFuJ8SHPHCcmnxw/oieuY3/Gh2uC2Y+drfctZzZhK6vLw/vXlPSfQM1ulmo5krov24t4MRxTXVXsXLTWbwZNU+ybo66zOaZjBoFF1QkredYnA9BrK/TD31EmZgtvnIWvJKUGNASzoEEJN6714IaVE1l7wwri7x70vkj3ZWtF8LEum1azctSDF34s/E4G86qcRtSFY7zesoaO/HVMyr9od4yIUmHgVIAdpVzp70av+5601aLdhaQV5vuF9z7zCpR2CvPulLWj6M37e3fGMrTZTTC+lH8hlkvTCgi80kSPTr8Fs4MA7qWC+FWZ0gMn7XK8j9oOlCR1bHEuZSzfgrc/JZh+HELr1q/8B5rauC1O+4+iETjb9mG3pkOwUs+Ac/iOD/7Q8a7JqZ1kAlEqXyGuXEYg4VKR/XW7vh9NknlIpv8klz3AFrocM1mqA9Mrlrji7BbeRhObX/fUyrDwYadGN4arnCI3Zs7OeJXASGtw0PvuO15DEysbTaxRGx3yZ+04/nOUm","x-forefront-antispam-report":"CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n\tIPV:NLI; SFV:NSPM; H:PAXPR04MB8285.eurprd04.prod.outlook.com; PTR:;\n\tCAT:NONE; \n\tSFS:(13230040)(376014)(366016)(19092799006)(1800799024)(23010399003)(6133799003)(22082099003)(18002099003)(38070700021)(3023799007)(11063799006)(4143699003)(56012099006)(10067099003);\n\tDIR:OUT; SFP:1101; ","x-ms-exchange-antispam-messagedata-chunkcount":"1","x-ms-exchange-antispam-messagedata-0":"=?utf-8?q?NJwe29Kwal2EAuxr90D8j3euX?=\n\t=?utf-8?q?QUhNRvoY7hbwwHZSZLvWiS1BH6++7531KQWng+dKsK2O9fhpVaOQJZFU?=\n\t=?utf-8?q?eE2Bpco+SDkbKg8cOAFgqvaVJYQt9reQJQFbDEP5RkY70jOD9EXxYZ58?=\n\t=?utf-8?q?aG3eEx3tf59qplxegZI8uQQVhMoUSMPO2syYNsX1NPAloASbYqxzAGDy?=\n\t=?utf-8?q?9zUyAujg4dqp2rKEdCc7B/kGETrGE39KEo3eLIuHzooSHjc8iBxPRak2?=\n\t=?utf-8?q?X8NJTVauXuyM+7ZV6UpZYg5iyJSsz87J18x7SrqMUMr1LyIpjYzWk6FC?=\n\t=?utf-8?q?RriDrY7b2EiWvUmeqsM0W9bx/8FdbAy8CNczAlJJ27HTWYC9fuVEHtwR?=\n\t=?utf-8?q?JDA7kSenUj8mL5ukj+qZBpZtYkQQenownyrPHnjg1nqdQl4e8EdBhQT8?=\n\t=?utf-8?q?pU0GYlyWkzq9np/RyZvBcYjn3EiSfi4C1owJisseROXu01erwwgXtd/l?=\n\t=?utf-8?q?p5kSb2ncpkbErZ6ZAL7ruIP7BiIdo5OhuR0Ib6exVmYXJwdQQQqmVBUZ?=\n\t=?utf-8?q?uf+p5xWro1I1+PMecQnFvm93d6RdzoBiJ4/5gY/tW/Q25K9kmKNbuZHe?=\n\t=?utf-8?q?ES8PLVho4t1FsfZww+o5sLzmplmXEWe/Pc+uEEtLBpcxfGS43bH3bcN+?=\n\t=?utf-8?q?zPry6XbLdCnLOBdeDZa5mR17oOGp8o3MCOMsr564xGPQn3moHj0MRvzq?=\n\t=?utf-8?q?ExUKGd70DIcff7xDmR1E2RT9MUkHRK8t4SwgnD3WH6kIPXQEA82z8wqG?=\n\t=?utf-8?q?7i82cqfOUwx+FYCD0crrSlNIQqeCNt552JT+BXHtt2MDS7CG4pRR+gk3?=\n\t=?utf-8?q?se4GWE4+Ey60U2PYk0yIXEhcJaw8m8Tybxou5Je/vdkjkOEh14YAELoz?=\n\t=?utf-8?q?5MxLqW4uyTuep0CrNAn7DKCXf0TwprMysI1dkcKsMcTwtICwSCOdpYZI?=\n\t=?utf-8?q?bF0hlMFCiK7HHhKmoKQVLUmJrHM+9kqN3Xhm2cHG7/+RXAB3OyhpuR7w?=\n\t=?utf-8?q?hb0NTfKmKQ5DYiV/3HsagWtP5KWuz/gJCWoDqvbxJEYerAINw5InUTC9?=\n\t=?utf-8?q?Zod3Kqo71rzSB2sMzD441zC9gp7KOEIjY0VSMZ0PMLajmJd0inAaG+5I?=\n\t=?utf-8?q?7cd0eGhiQVPfyu19ijWc2AxnFUr6J8xEYgTJXnfm1/1xeDIq0fHBGwhn?=\n\t=?utf-8?q?DNKnrqimDVqySrkM6WRuUyx4AeT2JXalbx27gI4zuDeJ9LUBjinGyvUK?=\n\t=?utf-8?q?5Uonw2MmbP3J5JscZcDl2nrWT+9MA0Fgzt4g5IB4YTWJQwVnNQdTTlqM?=\n\t=?utf-8?q?vGaCtkBuDYAOBJdrfp0HHVSvidUTxnI1HXb1eqBHhLGnvcHz84BerIOV?=\n\t=?utf-8?q?yyBONlqemDM4kfijmMy03xabax/R7mGwIZEGeKA943Vs3H1CWI6xX6Nn?=\n\t=?utf-8?q?AdjoRnMTPQEl+0HqjeQwqZNlU/MnoQ8cNNcW9nlEBWJPLI4fokT8V2wf?=\n\t=?utf-8?q?/gB7YKYoBe8AG3hbG5kiq0a/9z4S9bisyM4//VZdLwg2U/4BIq37NBpe?=\n\t=?utf-8?q?3krGlyNYXHpU9F5tnuJStmJ/grhcDzkM7m+p6P+NDQk50b61NMZAZqMy?=\n\t=?utf-8?q?aA02r7qblrCJOVdpZIoIwij5usc0bSvs+i0Sj9lhZq43ifV9IH/S2xBS?=\n\t=?utf-8?q?XyB6UZfCnOIbe+USWfAaP8g3/QaP1PO8fkzhAlDlKP7qpJBPNskuyb+t?=\n\t=?utf-8?q?OCjVmGgdfd8TWoCZKKrf9HKn9kp8f7iPCp++vkhVbgk3j2d9lEGWv7BO?=\n\t=?utf-8?q?ceITacu+M9jBn4TKRDyxbik?=","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","MIME-Version":"1.0","X-OriginatorOrg":"oss.nxp.com","X-MS-Exchange-CrossTenant-AuthAs":"Internal","X-MS-Exchange-CrossTenant-AuthSource":"PAXPR04MB8285.eurprd04.prod.outlook.com","X-MS-Exchange-CrossTenant-Network-Message-Id":"fcbc9970-3603-417b-b688-08deed1d5e6e","X-MS-Exchange-CrossTenant-originalarrivaltime":"29 Jul 2026 02:59:12.7223\n\t(UTC)","X-MS-Exchange-CrossTenant-fromentityheader":"Hosted","X-MS-Exchange-CrossTenant-id":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635","X-MS-Exchange-CrossTenant-mailboxtype":"HOSTED","X-MS-Exchange-CrossTenant-userprincipalname":"h7L5gRcnGsq1V5Rq7ETH3iUGBbbA+AFmo6EO79hX+QHLyO2LKsCopWmcqIEGtTZl","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"PA4PR04MB7616","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>"}}]