From patchwork Wed Jun 10 09:38:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Hou X-Patchwork-Id: 26864 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 BB8DFC324C for ; Wed, 10 Jun 2026 09:38:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DDBB261EFB; Wed, 10 Jun 2026 11:38:22 +0200 (CEST) Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5FB7C60989 for ; Wed, 10 Jun 2026 11:38:21 +0200 (CEST) Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 0269E20180A; Wed, 10 Jun 2026 11:38:21 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id C0B4E201290; Wed, 10 Jun 2026 11:38:20 +0200 (CEST) Received: from lsvm11u0000124.swis.ap-northeast-2.aws.nxp.com (lsvm11u0000124.swis.ap-northeast-2.aws.nxp.com [10.52.8.111]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 9EFAC1800071; Wed, 10 Jun 2026 17:38:19 +0800 (+08) From: Qi Hou To: libcamera-devel@lists.libcamera.org Cc: jared.hu@nxp.com, qi.hou@nxp.com, julien.vuillaumier@nxp.com Subject: [PATCH v2] libcamera: software_isp: Probe EGL availability before creating DebayerEGL Date: Wed, 10 Jun 2026 18:38:12 +0900 Message-Id: <20260610093812.3604734-1-qi.hou@nxp.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP 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" When HAVE_DEBAYER_EGL is enabled, the SoftwareIsp constructor unconditionally creates a DebayerEGL instance. If the platform lacks EGL surfaceless support, DebayerEGL::start() fails with -ENODEV after SwStatsCpu ownership has already been moved, making fallback to DebayerCpu impossible. Add a static eGL::isAvailable() method that probes whether EGL surfaceless rendering can be initialised. Extract the common display obtaining logic (eglBindAPI, eglGetPlatformDisplay, eglInitialize) into a private eGL::probeDisplay() helper that is shared by both isAvailable() and initEGLContext(), avoiding code duplication. The SoftwareIsp constructor now calls eGL::isAvailable() before creating DebayerEGL. If EGL is not available, the existing fallback path creates a DebayerCpu instance instead. Signed-off-by: Qi Hou --- include/libcamera/internal/egl.h | 4 ++ src/libcamera/egl.cpp | 60 ++++++++++++++++----- src/libcamera/software_isp/software_isp.cpp | 10 +++- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h index 57f90d93..27c5c29d 100644 --- a/include/libcamera/internal/egl.h +++ b/include/libcamera/internal/egl.h @@ -99,6 +99,8 @@ private: class eGL { public: + static bool isAvailable(); + eGL(); ~eGL(); @@ -127,6 +129,8 @@ public: private: LIBCAMERA_DISABLE_COPY_AND_MOVE(eGL) + static EGLDisplay probeDisplay(); + pid_t tid_; EGLDisplay display_ = EGL_NO_DISPLAY; diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index c185bb7a..860f18dd 100644 --- a/src/libcamera/egl.cpp +++ b/src/libcamera/egl.cpp @@ -267,6 +267,50 @@ void eGL::createTexture2D(eGLImage &eglImage, void *data) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } +EGLDisplay eGL::probeDisplay() +{ + EGLDisplay display; + + if (!eglBindAPI(EGL_OPENGL_ES_API)) { + LOG(eGL, Info) << "API bind fail"; + return EGL_NO_DISPLAY; + } + + display = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, + EGL_DEFAULT_DISPLAY, + nullptr); + + if (display == EGL_NO_DISPLAY) { + LOG(eGL, Info) << "Unable to get EGL display"; + return EGL_NO_DISPLAY; + } + + if (eglInitialize(display, nullptr, nullptr) != EGL_TRUE) { + LOG(eGL, Error) << "eglInitialize fail"; + return EGL_NO_DISPLAY; + } + + return display; +} + +/** + * \brief Probe whether EGL surfaceless rendering is available + * + * Checks if an EGL surfaceless display can be obtained and initialised. + * The display is immediately terminated so that no resources are leaked. + * + * \return true if EGL surfaceless rendering is available, false otherwise + */ +bool eGL::isAvailable() +{ + EGLDisplay display = probeDisplay(); + if (display == EGL_NO_DISPLAY) + return false; + + eglTerminate(display); + return true; +} + /** * \brief Initialise the EGL context * @@ -297,21 +341,9 @@ int eGL::initEGLContext() EGLint numConfigs; EGLConfig config; - if (!eglBindAPI(EGL_OPENGL_ES_API)) { - LOG(eGL, Error) << "API bind fail"; - goto fail; - } - - display_ = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, - EGL_DEFAULT_DISPLAY, - nullptr); + display_ = probeDisplay(); if (display_ == EGL_NO_DISPLAY) { - LOG(eGL, Error) << "Unable to get EGL display"; - goto fail; - } - - if (eglInitialize(display_, nullptr, nullptr) != EGL_TRUE) { - LOG(eGL, Error) << "eglInitialize fail"; + LOG(eGL, Error) << "Unable to probe display"; goto fail; } diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 781cf02f..ff8c3465 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -119,8 +119,14 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, } } - if (!softISPMode || softISPMode == "gpu") - debayer_ = std::make_unique(std::move(stats), cm); + if (!softISPMode || softISPMode == "gpu") { + if (eGL::isAvailable()) { + debayer_ = std::make_unique(std::move(stats), cm); + } else { + LOG(SoftwareIsp, Info) + << "EGL not available, falling back to CPU debayer"; + } + } #endif if (!debayer_)