如何在Android上正确初始化和终止EGL

时间:2011-06-15 22:52:12

标签: android opengl-es

虽然有很多关于在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找到“正确的”方式(关于初始化/终止)。

“正确”的方式应该提供:

  1. 启动使用EGL的任何第一个组件时的EGL初始化
  2. 使用EGL完成最后一个组件时的EGL终止
  3. 多线程。只应从主应用程序线程中对EGL操作进行限制。
  4. 请注意,当没有使用EGL / OpenGL ES的活动实体时,(2)对于最小化应用程序的系统资源使用至关重要。

    有什么想法吗?或者我可能忽略了有关Android上EGL的一些内容?

    更新

    还有一个有趣的相关问题:

    由于每个线程只允许一个活动的渲染上下文,因此只有一个Component可以同时从主线程中使用OpenGL ES。在主线程中同时运行多个使用OpenGL ES的组件会导致问题,因为最后一个组件调用 eglMakeCurrent()将隐含地“替换”所有其他组件的上下文(而这实际上将彻底打破组件逻辑)。

    更新2(最终)

    有人透露(感谢 Romain Guy ),Android实际上有一个明确形式的EGL初始化/终止问题的内部解决方法(它违反了EGL规范,并未在Android中提及)文档) eglInitialize() eglTerminate()中的“引用计数”。

1 个答案:

答案 0 :(得分:14)

eglTerminate()和eglInitialize()是引用计数,因此每个“组件”都可以调用它们。特别是在Android 3.0上,在同一个应用程序中有几个OpenGL上下文是很常见的,并且使用EGL没有任何问题。