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

Ale*_*hen 14 android opengl-es

虽然有许多关于在Android上使用OpenGL ES的样本,但在EGL的初始化/终止方面,所有这些似乎都是不正确的(甚至是Android SDK/NDK附带的).问题的根源在于Android应用程序模型,它正确地使用了EGL怪异的东西.

在所有Android样本甚至GLSurfaceView(实际上大多数样本只使用它)中,EGL初始化每个操作系统进程的真正问题涉及每个组件(Activity或WallpaperService)的EGL初始化/终止.这是完全错误的,因为所有组件都在同一个进程中运行!如果应用程序只包含一个组件,则没有问题,但如果应用程序中有多个组件且每个组件都使用OpenGL ES,则会出现问题.

只考虑使用OpenGL ES的两个应用程序组件同时运行并且其中一个组件完成的情况.完成这样的组件将调用eglTerminate()(在GLSurfaceView源代码中查看我正在谈论的内容),这将终止整个过程的EGL !从这一刻开始,来自另一个已在运行的组件的任何EGL调用都将失败!

我检查了大量的示例,并且所有示例都初始化并终止每个组件的EGL(实际上没有人看到我做过与GLSurfaceView不同的事情,其中​​大多数只是GLSurfaceView内部的副本).

而现在我很有兴趣找到一种"正确"的方式来使用EGL在Android上工作(关于初始化/终止).

"适当"的方式应该提供:

  1. 启动任何使用EGL的第一个组件时的EGL初始化
  2. 完成使用EGL的最后一个组件时的EGL终止
  3. 多线程.不应仅限于来自主应用程序线程的EGL操作限制.

请注意,当没有使用EGL/OpenGL ES的活动实体时,(2)对于最小化应用程序的系统资源使用至关重要.

有任何想法吗?或许我忽略了Android上的EGL?

更新

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

由于每个线程只允许一个活动渲染上下文,因此同一时间只有一个Component可以正常使用主线程中的OpenGL ES.在同一时间运行的主线程中有多个使用OpenGL ES的组件会导致问题,因为最后一个组件调用eglMakeCurrent()会隐藏"替换"所有其他组件的上下文(这实际上将完全打破组件逻辑).

更新2(最终)

据透露(感谢Romain Guy)Android实际上有一个内部解决方案,用于EGL初始化/终止问题,以明确的形式(它违反EGL规范,在Android文档中没有提到)"引用计数"在eglInitialize内部( )eglTerminate().

Rom*_*Guy 14

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