@@ -99,11 +99,11 @@ private:
class eGL
{
public:
- eGL();
+ eGL(EGLDisplay display);
~eGL();
int initEGLContext();
- static bool isAvailable();
+ static EGLDisplay probeDisplay();
int createInputDMABufTexture2D(eGLImage &eglImage, int fd);
int createOutputDMABufTexture2D(eGLImage &eglImage, int fd);
@@ -137,7 +137,6 @@ private:
EGLContext context_ = EGL_NO_CONTEXT;
EGLSurface surface_ = EGL_NO_SURFACE;
- static EGLDisplay probeDisplay();
int compileShader(int shaderType, GLuint &shaderId, Span<const unsigned char> shaderData,
Span<const std::string> shaderEnv);
@@ -64,12 +64,15 @@ LOG_DEFINE_CATEGORY(eGL)
/**
* \brief Construct an EGL helper
+ * \param[in] display The EGL display to use
*
* Creates an eGL instance with uninitialised context. Call initEGLContext()
- * to set up the EGL display, context, and load extension functions.
+ * to set up the EGL context, and load extension functions.
*/
-eGL::eGL()
+eGL::eGL(EGLDisplay display)
+ : display_(display)
{
+ ASSERT(display_ != EGL_NO_DISPLAY);
}
/**
@@ -299,15 +302,17 @@ void eGL::createTexture2D(eGLImage &eglImage, void *data)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
+/**
+ * \brief Try to create an EGL display for surfaceless rendering
+ *
+ * Tries to create an EGL display for surfaceless rendering.
+ *
+ * \return A EGL display handle if successful, otherwise \a EGL_NO_DISPLAY
+ */
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);
@@ -325,24 +330,6 @@ EGLDisplay eGL::probeDisplay()
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 Update a 2D texture already created
* \param[in,out] eglImage EGL image to associate with the texture
@@ -403,9 +390,8 @@ int eGL::initEGLContext()
EGLint numConfigs;
EGLConfig config;
- display_ = probeDisplay();
- if (display_ == EGL_NO_DISPLAY) {
- LOG(eGL, Error) << "Unable to probe display";
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ LOG(eGL, Error) << "API bind fail";
goto fail;
}
@@ -40,9 +40,10 @@ namespace libcamera {
* \brief Construct a DebayerEGL object
* \param[in] stats Statistics processing object
* \param[in] cm The camera manager
+ * \param[in] display The EGL display to use
*/
-DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm)
- : Debayer(cm), stats_(std::move(stats))
+DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm, EGLDisplay display)
+ : Debayer(cm), stats_(std::move(stats)), egl_(display)
{
}
@@ -40,7 +40,7 @@ class CameraManager;
class DebayerEGL : public Debayer
{
public:
- DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm);
+ DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm, EGLDisplay display);
~DebayerEGL();
int configure(const StreamConfiguration &inputCfg,
@@ -120,8 +120,9 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
}
if (!softISPMode || softISPMode == "gpu") {
- if (eGL::isAvailable()) {
- debayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm);
+ auto display = eGL::probeDisplay();
+ if (display != EGL_NO_DISPLAY) {
+ debayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm, display);
} else {
LOG(SoftwareIsp, Info)
<< "EGL not available, falling back to CPU debayer";