【问题标题】:recreate eglCreateWindowSurface with same native window使用相同的本机窗口重新创建 eglCreateWindowSurface
【发布时间】:2019-06-21 11:55:17
【问题描述】:

我使用 EGL API 编写了一个库。该库具有“init”和“deinit”功能。 在“init”函数中,用户传递的本机窗口 ID,使用该本机窗口 ID eglCreateWindowSurface 被创建。在 'deinit' 函数中,使用 eglDestroySurface 销毁表面。

现在用户再次调用“init”函数来创建另一个 eglCreateWindowSurface,但他传递了与之前相同的窗口 id(因为他没有关闭他的窗口),这里 eglCreateWindowSurface 失败并出现错误 EGL_BAD_ALLOC。

我阅读了 EGL 规范

如果已经存在与 win 关联的 EGLSurface(由于 之前的 eglCreateWindowSurface 调用),然后是 EGL_BAD_ALLOC 错误 生成

当我已经使用 eglDestroySurface 破坏了表面时,我不明白为什么要使用相同的窗口 ID 再次创建它。

xserver 重新使用之前关闭的窗口 id 时会出现这个问题吗?

【问题讨论】:

    标签: x11 xserver egl


    【解决方案1】:

    eglDestroySurface 是否返回了 EGL_TRUE 值?

    否则,销毁可能失败。

    请注意,如果没有足够的资源来分配新表面,也可能会生成 EGL_BAD_ALLOC。

    【讨论】:

    • 很抱歉,eglDestroySurface 返回一个 EGL_TRUE 值。它也与足够的资源无关。如果用户关闭窗口并传递新句柄,则创建 egl 表面。似乎 egl 已经输入了一些窗口 ID,即使成功返回 eglDestroySurface,也不会被清除。我担心的是,如果 xserver 返回刚刚关闭的相同窗口 ID,那么 egl 也将无法创建 egl Surface。我还需要等待一段时间才能创建具有相同窗口 ID 的 egl 表面吗?
    【解决方案2】:

    即使在eglDestroySurfaceeglTerminate 之后,您的EGLSurface 也不会被销毁。您可能调用了eglMakeCurrent( display, surface... context) - 这会将您的表面绑定到 GL 上下文的默认帧缓冲区。您需要解除绑定,才能真正删除曲面。调用eglMakeCurrent(display, EGL_NO_SURFACE... EGL_NO_CONTEXT) - 这会导致活动线程释放上下文和表面。现在您会发现 EGL 已经忘记/删除了表面,您可以重新使用 Window ID。 eglReleaseThread 也应该这样做。

    eglMakeCurrent(显示, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);将取消绑定您的表面并允许将其删除,它不是立即的, eglMakeCurrent 将在该上下文中导致 glFlush 。因此,可能需要一点时间来完成您调用的绘图并将图像解析到缓冲区。否则 GPU 可能会崩溃。在 eglMakeCurrent 之前调用 glFinish() 以确保完成,或者创建栅栏并等待它。在 eglMakeCurrent(... EGL_NO_SURFACE...) 之前或之后调用 eglDeleteSurface 都没有关系,但是所有 gl 命令都必须在 eglMakeCurrent(... EGL_NO_SURFACE..., EGL_NO_CONTEXT) 之前发生。因为这使得没有当前上下文,并且 gl 命令不会在没有当前上下文的情况下执行。

    您可以尝试调用 eglGetCurrentContext 和 eglGetCurrentSurface 来检查表面是否仍然存在 - 您得到的句柄不是 EGL_NO_SURFACE。但是在eglDeleteSurface之后,表面句柄肯定是没有用的。请参阅 EGL 规范 1.5 第 3.7.4 节 - 但正如我上面所说,它的存在只是因为它绑定到当前上下文。请参阅第 3.7.3 节

    【讨论】:

    • 感谢您解释它的努力...但我很遗憾地说它仍然对我不起作用...我使用 eglMakeCurrent(display, EGL_NO_SURFACE... EGL_NO_CONTEXT) 并发布破坏表面,上下文 eglGetCurrentSurface 未能获取表面,并且在下一个初始化调用中,'eglCreateWindowSurface' 失败,如所询问的那样。
    • 嗯,重用 xwindow ID 似乎确实存在一些问题。你能检查它是否仍然是一个有效的 X 对象?在我所说的步骤之后,EGL 中应该不再有关联。所以我不得不认为 Xwindow 的某些东西是无效的。如果 EGL 保留了某些东西 - 那么它是该驱动程序中的一个错误。
    • xwindow ID 是一个有效的 X 对象。只有一个变化,xwindow 被调整为新值。但这不应该是问题,如果我不关闭现有的 EGL 上下文和 EGL Surface,即使调整大小的 xwindow id 也同样适用。唯一的问题是关闭和重新打开 egl 窗口表面。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多