EGL 显示句柄生命周期与静态对象生命周期
EGL Display Handle Lifetime vs Static Object Lifetime
我正在调试退出时出现的段错误,我怀疑这是最近对我们的 OpenGL-via-EGL 离屏渲染设置的更改。 ubuntu 上的所有内容 运行 都带有集成英特尔显卡。仅当包含并使用 OpenCV 的 highgui 时才会出现段错误。可以这么说,这可能只是煤矿中的金丝雀,问题似乎源于对象的生命周期。
我们有一个 EGLContext
class 来管理所有 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)
时我们都会得到不同的显示句柄。 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 处理程序,其中包括 eglBindAPI
和 eglMakeCurrent
我正在调试退出时出现的段错误,我怀疑这是最近对我们的 OpenGL-via-EGL 离屏渲染设置的更改。 ubuntu 上的所有内容 运行 都带有集成英特尔显卡。仅当包含并使用 OpenCV 的 highgui 时才会出现段错误。可以这么说,这可能只是煤矿中的金丝雀,问题似乎源于对象的生命周期。
我们有一个 EGLContext
class 来管理所有 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)
时我们都会得到不同的显示句柄。 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 处理程序,其中包括 eglBindAPI
和 eglMakeCurrent