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

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

Commit Message

Robert Mader Jan. 19, 2026, 8:28 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>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sm8250/rb5, x1e/Dell Insprion14p
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # ThinkPad X1 Yoga Gen 7 + ov2740
---
 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

Laurent Pinchart Jan. 19, 2026, 8:51 p.m. UTC | #1
On Mon, Jan 19, 2026 at 09:28:34PM +0100, Robert Mader wrote:
> Which appears to be a better fit for the use-case at hand:

Mesa surfaceless platform appears to be ...

> 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>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sm8250/rb5, x1e/Dell Insprion14p
> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
> Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69
> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # ThinkPad X1 Yoga Gen 7 + ov2740
> ---
>  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 da563ee09..7ff1b5ea2 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
>  	};
> @@ -291,7 +289,7 @@ int eGL::initEGLContext(GBM *gbmContext)
>  		goto fail;
>  	}
>  
> -	display_ = eglGetDisplay(gbmContext->device());
> +	display_ = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, nullptr, nullptr);

	display_ = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, nullptr,
					 nullptr);

But according to
https://registry.khronos.org/EGL/extensions/MESA/EGL_MESA_platform_surfaceless.txt
the native_display parameter must be EGL_DEFAULT_DISPLAY, so this would
be

	display_ = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA,
					 EGL_DEFAULT_DISPLAY,
					 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

While at it let's improve the comment formatting:

	 * Tell shaders how to re-order output taking account of how the pixels
	 * are actually stored by EGL.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

>  	 */
>  	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 da563ee09..7ff1b5ea2 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
 	};
@@ -291,7 +289,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_;