虽然有很多关于在Android上使用OpenGL ES的示例,但在EGL的初始化/终止方面,所有这些似乎都是不正确的(甚至是Android SDK / NDK附带的)。问题的根源在于Android应用程序模型,它正确地使用了EGL怪异。
EGL初始化每个操作系统 进程 的真正问题,而所有Android样本甚至 GLSurfaceView (实际上大多数样本只是使用它)涉及每个 组件 (活动或WallpaperService)的EGL初始化/终止。这是完全错误的,因为所有组件都在同一个进程中运行!如果应用程序只包含一个组件,则没有问题,但如果应用程序中有多个组件并且每个组件都使用OpenGL ES,则会出现问题。
只考虑使用OpenGL ES的两个应用程序组件同时运行并且其中一个组件完成的情况。完成此类组件后,将调用 eglTerminate()(查看 GLSurfaceView 源代码,看看我在说什么),这将终止整个进程的EGL !从这一刻开始,来自另一个已在运行的组件的任何EGL调用都将失败!
我已经检查了大量的示例,所有这些示例都初始化并终止了每个组件的EGL(实际上没有人看到过与 GLSurfaceView 做的不同的事情,其中大多数只是 GLSurfaceView 内部)。
现在我很有兴趣在Android上使用EGL找到“正确的”方式(关于初始化/终止)。
“正确”的方式应该提供:
请注意,当没有使用EGL / OpenGL ES的活动实体时,(2)对于最小化应用程序的系统资源使用至关重要。
有什么想法吗?或者我可能忽略了有关Android上EGL的一些内容?
还有一个有趣的相关问题:
由于每个线程只允许一个活动的渲染上下文,因此只有一个Component可以同时从主线程中使用OpenGL ES。在主线程中同时运行多个使用OpenGL ES的组件会导致问题,因为最后一个组件调用 eglMakeCurrent()将隐含地“替换”所有其他组件的上下文(而这实际上将彻底打破组件逻辑)。
有人透露(感谢 Romain Guy ),Android实际上有一个明确形式的EGL初始化/终止问题的内部解决方法(它违反了EGL规范,并未在Android中提及)文档) eglInitialize()和 eglTerminate()中的“引用计数”。
答案 0 :(得分:14)
eglTerminate()和eglInitialize()是引用计数,因此每个“组件”都可以调用它们。特别是在Android 3.0上,在同一个应用程序中有几个OpenGL上下文是很常见的,并且使用EGL没有任何问题。