[1/2] egl: Use the Mesa surfaceless platform instead of GBM
diff mbox series

Message ID 20260110221337.145378-1-robert.mader@collabora.com
State New
Headers show
Series
  • [1/2] egl: Use the Mesa surfaceless platform instead of GBM
Related show

Commit Message

Robert Mader Jan. 10, 2026, 10:13 p.m. UTC
Which appears to be a better fit for the use-case at hand:
1. Like GBM it is Mesa specific, so no change in supported setups is
   expected. If ever required, a fallback to the generic device platform
   could be added on top.
2. It leaves the complexity of selecting a renderer device to the
   driver, reducing code and dependencies.
3. It allows to use llvmpipe / software drivers without dri device,
   which can be useful on CI or debugging (with LIBGL_ALWAYS_SOFTWARE=1).

Signed-off-by: Robert Mader <robert.mader@collabora.com>

---

Should be applied on to of
https://patchwork.libcamera.org/cover/25706/
---
 include/libcamera/internal/egl.h           |  4 +---
 src/libcamera/egl.cpp                      | 12 +++++-------
 src/libcamera/software_isp/debayer_egl.cpp |  7 ++-----
 src/libcamera/software_isp/debayer_egl.h   |  1 -
 4 files changed, 8 insertions(+), 16 deletions(-)

Comments

Robert Mader Jan. 10, 2026, 10:39 p.m. UTC | #1
P.S.: whops, forgot to add: the proprietary Nvidia driver also supports 
GBM - but apparently implements the surfaceless platform as well.

On 10.01.26 23:13, Robert Mader wrote:
> Which appears to be a better fit for the use-case at hand:
> 1. Like GBM it is Mesa specific, so no change in supported setups is
>     expected. If ever required, a fallback to the generic device platform
>     could be added on top.
> 2. It leaves the complexity of selecting a renderer device to the
>     driver, reducing code and dependencies.
> 3. It allows to use llvmpipe / software drivers without dri device,
>     which can be useful on CI or debugging (with LIBGL_ALWAYS_SOFTWARE=1).
>
> Signed-off-by: Robert Mader <robert.mader@collabora.com>
>
> ---
>
> Should be applied on to of
> https://patchwork.libcamera.org/cover/25706/
> ---
>   include/libcamera/internal/egl.h           |  4 +---
>   src/libcamera/egl.cpp                      | 12 +++++-------
>   src/libcamera/software_isp/debayer_egl.cpp |  7 ++-----
>   src/libcamera/software_isp/debayer_egl.h   |  1 -
>   4 files changed, 8 insertions(+), 16 deletions(-)
>
> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h
> index f007f448a..630345ea7 100644
> --- a/include/libcamera/internal/egl.h
> +++ b/include/libcamera/internal/egl.h
> @@ -16,8 +16,6 @@
>   #include <libcamera/base/span.h>
>   #include <libcamera/base/utils.h>
>   
> -#include "libcamera/internal/gbm.h"
> -
>   #define EGL_EGLEXT_PROTOTYPES
>   #include <EGL/egl.h>
>   #include <EGL/eglext.h>
> @@ -96,7 +94,7 @@ public:
>   	eGL();
>   	~eGL();
>   
> -	int initEGLContext(GBM *gbmContext);
> +	int initEGLContext();
>   
>   	int createInputDMABufTexture2D(eGLImage &eglImage, int fd);
>   	int createOutputDMABufTexture2D(eGLImage &eglImage, int fd);
> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp
> index 0ffd008c7..19c5ff48f 100644
> --- a/src/libcamera/egl.cpp
> +++ b/src/libcamera/egl.cpp
> @@ -256,24 +256,22 @@ void eGL::createTexture2D(eGLImage &eglImage, GLint format, uint32_t width, uint
>   
>   /**
>    * \brief Initialise the EGL context
> - * \param[in] gbmContext Pointer to initialised GBM context
>    *
> - * Sets up the EGL display from the GBM device, creates an OpenGL ES 2.0
> - * context, and retrieves function pointers for required extensions
> - * including:
> + * Sets up the EGL display, creates an OpenGL ES 2.0 context, and retrieves
> + * function pointers for required extensions including:
>    * - eglCreateImageKHR / eglDestroyImageKHR
>    * - glEGLImageTargetTexture2DOES
>    *
>    * \return 0 on success, or -ENODEV on failure
>    */
> -int eGL::initEGLContext(GBM *gbmContext)
> +int eGL::initEGLContext()
>   {
>   	EGLint configAttribs[] = {
>   		EGL_RED_SIZE, 8,
>   		EGL_GREEN_SIZE, 8,
>   		EGL_BLUE_SIZE, 8,
>   		EGL_ALPHA_SIZE, 8,
> -		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
> +		EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
>   		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
>   		EGL_NONE
>   	};
> @@ -297,7 +295,7 @@ int eGL::initEGLContext(GBM *gbmContext)
>   		goto fail;
>   	}
>   
> -	display_ = eglGetDisplay(gbmContext->device());
> +	display_ = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, nullptr, nullptr);
>   	if (display_ == EGL_NO_DISPLAY) {
>   		LOG(eGL, Error) << "Unable to get EGL display";
>   		goto fail;
> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp
> index 9693d7252..c85c7d6cd 100644
> --- a/src/libcamera/software_isp/debayer_egl.cpp
> +++ b/src/libcamera/software_isp/debayer_egl.cpp
> @@ -142,7 +142,7 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm
>   
>   	/*
>   	 * Tell shaders how to re-order output taking account of how the
> -	 * pixels are actually stored by GBM
> +	 * pixels are actually stored by EGL
>   	 */
>   	switch (outputFormat) {
>   	case formats::ARGB8888:
> @@ -586,10 +586,7 @@ int DebayerEGL::start()
>   {
>   	GLint maxTextureImageUnits;
>   
> -	if (gbmSurface_.createDevice())
> -		return -ENODEV;
> -
> -	if (egl_.initEGLContext(&gbmSurface_))
> +	if (egl_.initEGLContext())
>   		return -ENODEV;
>   
>   	glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h
> index a5033bc63..cfbaf8e9d 100644
> --- a/src/libcamera/software_isp/debayer_egl.h
> +++ b/src/libcamera/software_isp/debayer_egl.h
> @@ -113,7 +113,6 @@ private:
>   	Rectangle window_;
>   	std::unique_ptr<SwStatsCpu> stats_;
>   	eGL egl_;
> -	GBM gbmSurface_;
>   	uint32_t width_;
>   	uint32_t height_;
>   	GLint glFormat_;

Patch
diff mbox series

diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h
index f007f448a..630345ea7 100644
--- a/include/libcamera/internal/egl.h
+++ b/include/libcamera/internal/egl.h
@@ -16,8 +16,6 @@ 
 #include <libcamera/base/span.h>
 #include <libcamera/base/utils.h>
 
-#include "libcamera/internal/gbm.h"
-
 #define EGL_EGLEXT_PROTOTYPES
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
@@ -96,7 +94,7 @@  public:
 	eGL();
 	~eGL();
 
-	int initEGLContext(GBM *gbmContext);
+	int initEGLContext();
 
 	int createInputDMABufTexture2D(eGLImage &eglImage, int fd);
 	int createOutputDMABufTexture2D(eGLImage &eglImage, int fd);
diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp
index 0ffd008c7..19c5ff48f 100644
--- a/src/libcamera/egl.cpp
+++ b/src/libcamera/egl.cpp
@@ -256,24 +256,22 @@  void eGL::createTexture2D(eGLImage &eglImage, GLint format, uint32_t width, uint
 
 /**
  * \brief Initialise the EGL context
- * \param[in] gbmContext Pointer to initialised GBM context
  *
- * Sets up the EGL display from the GBM device, creates an OpenGL ES 2.0
- * context, and retrieves function pointers for required extensions
- * including:
+ * Sets up the EGL display, creates an OpenGL ES 2.0 context, and retrieves
+ * function pointers for required extensions including:
  * - eglCreateImageKHR / eglDestroyImageKHR
  * - glEGLImageTargetTexture2DOES
  *
  * \return 0 on success, or -ENODEV on failure
  */
-int eGL::initEGLContext(GBM *gbmContext)
+int eGL::initEGLContext()
 {
 	EGLint configAttribs[] = {
 		EGL_RED_SIZE, 8,
 		EGL_GREEN_SIZE, 8,
 		EGL_BLUE_SIZE, 8,
 		EGL_ALPHA_SIZE, 8,
-		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+		EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
 		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
 		EGL_NONE
 	};
@@ -297,7 +295,7 @@  int eGL::initEGLContext(GBM *gbmContext)
 		goto fail;
 	}
 
-	display_ = eglGetDisplay(gbmContext->device());
+	display_ = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, nullptr, nullptr);
 	if (display_ == EGL_NO_DISPLAY) {
 		LOG(eGL, Error) << "Unable to get EGL display";
 		goto fail;
diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp
index 9693d7252..c85c7d6cd 100644
--- a/src/libcamera/software_isp/debayer_egl.cpp
+++ b/src/libcamera/software_isp/debayer_egl.cpp
@@ -142,7 +142,7 @@  int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm
 
 	/*
 	 * Tell shaders how to re-order output taking account of how the
-	 * pixels are actually stored by GBM
+	 * pixels are actually stored by EGL
 	 */
 	switch (outputFormat) {
 	case formats::ARGB8888:
@@ -586,10 +586,7 @@  int DebayerEGL::start()
 {
 	GLint maxTextureImageUnits;
 
-	if (gbmSurface_.createDevice())
-		return -ENODEV;
-
-	if (egl_.initEGLContext(&gbmSurface_))
+	if (egl_.initEGLContext())
 		return -ENODEV;
 
 	glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h
index a5033bc63..cfbaf8e9d 100644
--- a/src/libcamera/software_isp/debayer_egl.h
+++ b/src/libcamera/software_isp/debayer_egl.h
@@ -113,7 +113,6 @@  private:
 	Rectangle window_;
 	std::unique_ptr<SwStatsCpu> stats_;
 	eGL egl_;
-	GBM gbmSurface_;
 	uint32_t width_;
 	uint32_t height_;
 	GLint glFormat_;