libcamera: egl: Cache probed EGLDisplay to avoid redundant init/teardown
diff mbox series

Message ID 20260724014338.1850939-1-qi.hou@oss.nxp.com
State New
Headers show
Series
  • libcamera: egl: Cache probed EGLDisplay to avoid redundant init/teardown
Related show

Commit Message

qi.hou@oss.nxp.com July 24, 2026, 1:43 a.m. UTC
From: Qi Hou <qi.hou@nxp.com>

isAvailable() previously called probeDisplay() which ran eglBindAPI(),
eglGetPlatformDisplay() and eglInitialize(), then immediately terminated
the display with eglTerminate(). When SoftwareIsp subsequently called
initEGLContext(), probeDisplay() repeated a full initialisation sequence.

Avoid this double init/teardown by caching the EGLDisplay handle inside
probeDisplay() using static parameters. The first call initialises EGL
and stores the result, all later calls return the cached handle
without reinitialising.

isAvailable() is simplified to return probeDisplay() != EGL_NO_DISPLAY
and no longer calls eglTerminate(), because the cached display should
be live for reuse by initEGLContext().
---
 src/libcamera/egl.cpp | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp
index 7ec7a654d..f5200ee76 100644
--- a/src/libcamera/egl.cpp
+++ b/src/libcamera/egl.cpp
@@ -301,46 +301,49 @@  void eGL::createTexture2D(eGLImage &eglImage, void *data)
 
 EGLDisplay eGL::probeDisplay()
 {
-	EGLDisplay display;
+	static EGLDisplay cachedDisplay = EGL_NO_DISPLAY;
+	static bool probed = false;
+
+	if (probed)
+		return cachedDisplay;
+
+	probed = true;
 
 	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);
+	cachedDisplay = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA,
+					      EGL_DEFAULT_DISPLAY,
+					      nullptr);
 
-	if (display == EGL_NO_DISPLAY) {
+	if (cachedDisplay == EGL_NO_DISPLAY) {
 		LOG(eGL, Info) << "Unable to get EGL display";
 		return EGL_NO_DISPLAY;
 	}
 
-	if (eglInitialize(display, nullptr, nullptr) != EGL_TRUE) {
+	if (eglInitialize(cachedDisplay, nullptr, nullptr) != EGL_TRUE) {
 		LOG(eGL, Error) << "eglInitialize fail";
+		cachedDisplay = EGL_NO_DISPLAY;
 		return EGL_NO_DISPLAY;
 	}
 
-	return display;
+	return cachedDisplay;
 }
 
 /**
  * \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.
+ * The result is cached so that a subsequent call to initEGLContext() reuses
+ * the already-initialised display without a redundant init/teardown cycle.
  *
  * \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;
+	return probeDisplay() != EGL_NO_DISPLAY;
 }
 
 /**