| Message ID | 20260119202835.372125-1-robert.mader@collabora.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
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_;
All done in v3, thanks! On 19.01.26 21:51, Laurent Pinchart wrote: > 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_;
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_;