我用EGL API编写了一个库。这个库有'init'和'deinit'功能。在'init'函数中,用户传递的Native窗口id,使用该本机窗口id创建eglCreateWindowSurface。在'deinit'中,使用eglDestroySurface来破坏函数表面。
现在用户再次调用'init'函数来创建另一个eglCreateWindowSurface,但是他传递了与之前相同的窗口id(因为他还没有关闭他的窗口),这里eglCreateWindowSurface失败,错误为EGL_BAD_ALLOC。
我读了EGL规格
如果已经存在与win相关联的EGLSurface(作为先前的eglCreateWindowSurface调用的结果),则生成EGL_BAD_ALLOC错误
当我已经使用eglDestroySurface来破坏表面时,我不会得到这个,为什么再次使用相同的窗口ID创建它是困扰的。
当xserver重用早期关闭的窗口id时会发生此问题?
eglDestroySurface
是否返回了EGL_TRUE值?
如果没有,破坏可能会失败。
请注意,如果没有足够的资源来分配新曲面,也可能会生成EGL_BAD_ALLOC。
即使在EGLSurface
或eglDestroySurface
之后,你的eglTerminate
也不会被销毁。您可能调用了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()以确保完成,或者创建fence并等待它。如果在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节