EGL 显示句柄生命周期与静态对象生命周期

EGL Display Handle Lifetime vs Static Object Lifetime

我正在调试退出时出现的段错误,我怀疑这是最近对我们的 OpenGL-via-EGL 离屏渲染设置的更改。 ubuntu 上的所有内容 运行 都带有集成英特尔显卡。仅当包含并使用 OpenCV 的 highgui 时才会出现段错误。可以这么说,这可能只是煤矿中的金丝雀,问题似乎源于对象的生命周期。

我们有一个 EGLContext class 来管理所有 EGL。这意味着为要使用的设备选择 /dev/dri/xyz 文件句柄,然后获取显示句柄。我们使用扩展名 EGL_EXT_platform_baseEGL_EXT_platform_deviceEGL_EXT_device_baseEGL_EXT_device_queryEGL_EXT_device_enumeration.

EGLDisplay 句柄寿命

这个 EGLContext 过去工作正常,但是由于最近的优化,它由静态对象拥有,因此销毁比以前晚得多。在析构函数中,我们调用 eglDestroyContext()eglTerminate(),它们都会返回一个 EGL_BAD_DISPLAY 错误。这些句柄的固有生命周期是否比静态对象的生命周期短?在此之前,我们的代码中没有任何地方破坏显示连接。

EGL_PLATFORM_DEVICE_EXT显示句柄

在调试上述问题时,我注意到每次调用 eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devicedrm, display_attr) 时我们都会得到不同的显示句柄。 extension docs 表示

Multiple calls made to eglGetPlatformDisplayEXT with the same <platform> and <native_display> will return the same EGLDisplay handle.

有人知道这可能是什么原因吗?我错过了什么吗?

我找到了问题的答案。如果您遇到同样的问题,未来的 googler 就可以了。

Thanks to the docs,我发现了 EGL_LOG_LEVEL。将其设置为调试向我展示了,确实,我的显示正在终止,而我仍然想使用它。

谷歌搜索将我带到 mesa source,它告诉我正在调用 mesa 的 atexit 回调,这终止了我的显示。

尽管我难以置信,但显然 mesa 在我们的静态对象被销毁之前就退出了,这一定意味着 mesa 在我们的静态对象之后被初始化。如果我们的 EGLContext 仍然是一个普通对象,它会在 atexit 回调之前很久就被破坏了。但是,由于它现在是静态的,因此处于直接“竞争”状态。

我仍然需要实施的解决方案,但它要么与更早地初始化 EGL 有关,要么与注册我自己的 atexit 调用有关。或者我还没有想到的东西...

编辑:解决方案是在构造静态对象之前初始化我们的 EGL 事物。 Mesa 在一些函数中注册了它的 atexit 处理程序,其中包括 eglBindAPIeglMakeCurrent