我在退出时调试一个segfault,我怀疑它是最近通过EGL屏幕外渲染设置对OpenGL进行的更改。在ubuntu上运行的一切都集成了英特尔图形。segfault仅在包含并使用OpenCV的highgui时显示。可以说,这可能只是煤矿里的金丝雀,而这个问题似乎源于对象的寿命。
我们有一个EGLContext
类,它管理EGL的所有内容。这意味着选择要使用哪个设备的/dev/dri/xyz
文件句柄,然后获得一个显示句柄。我们使用扩展EGL_EXT_platform_base
、EGL_EXT_platform_device
、EGL_EXT_device_base
、EGL_EXT_device_query
和EGL_EXT_device_enumeration
。
EGLDisplay句柄生存期
这个EGLContext
过去工作得很好,但由于最近进行了优化,它被静态对象所拥有,因此销毁的时间比以前晚得多。在析构函数中,我们调用eglDestroyContext()
和eglTerminate()
,这两个函数都会返回一个EGL_BAD_DISPLAY
错误。这些句柄是否有比静态对象更短的固有寿命?在我们的代码中,没有任何地方在此之前破坏显示连接。
EGL_PLATFORM_DEVICE_EXT显示句柄
在调试上述问题时,我注意到对eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devicedrm, display_attr)
的每次调用都会得到不同的显示句柄。扩展文档指出
使用相同的
<platform>
和<native_display>
对eglGetPlatformDisplayEXT进行的多个调用将返回相同的EGLDisplay句柄。
有人知道这可能是什么原因吗?我是不是错过了什么?
我找到了问题的答案。给你,未来的谷歌人,如果你偶然发现同样的问题。
多亏了这些文档,我发现了EGL_LOG_LEVEL
。将其设置为调试向我表明,事实上,当我仍然想使用它时,我的显示器被终止了
通过谷歌搜索,我找到了mesa源,它显示正在调用mesa的atexit
回调,这终止了我的显示。
尽管我很不相信,但很明显,mesa在静态对象被破坏之前就退出了,这一定意味着mesa是在静态对象之后初始化的。如果我们的EGLContext
仍然是一个普通对象,那么它早在atexit回调之前就已经被破坏了。然而,由于它现在是静态的,所以它是直接的";竞争";。
我仍然需要实现这个解决方案,但它要么与更早地初始化EGL有关,要么与注册我自己的atexit调用有关。或者一些我还想不出来的事情。。。
编辑:解决方案是在构造静态对象之前初始化我们的EGL。Mesa在一些函数中注册atexit处理程序,其中包括eglBindAPI
和eglMakeCurrent