虽然有很多关于在 Android 上使用 OpenGL ES 的示例,但所有这些示例在 EGL 的初始化/终止方面似乎都是不正确的(即使是 Android SDK/NDK 附带的示例)。问题的根源在于 Android 应用程序模型,这使得 EGL 的正确使用变得很奇怪。
EGL 根据操作系统初始化的真正问题process而所有 Android 示例甚至GL表面视图(实际上大多数示例只是使用它)涉及 EGL 初始化/终止成分(活动或壁纸服务)。这是完全错误的,因为所有组件都在同一个进程中运行!如果应用程序仅由一个组件组成,那么没有问题,但如果应用程序中有多个组件并且每个组件都使用 OpenGL ES,则这就出现问题了。
考虑一下这样的情况:两个使用 OpenGL ES 的应用程序组件同时运行并且其中一个组件完成。完成此类组件后将调用例如终止()(在看GL表面视图源代码看看我在说什么),这将终止整个 EGLprocess!从此刻开始,来自另一个已运行组件的任何 EGL 调用都将失败!
我检查了大量的示例,所有示例都在每个组件的基础上初始化和终止 EGL(实际上,我见过没有人做与GL表面视图做,其中大多数只是复制GL表面视图内部结构)。
现在我有兴趣找到一个"proper"在 Android 上使用 EGL 进行工作(关于初始化/终止)的方法。
“正确”的方式应该提供:
- 当任何第一个使用 EGL 的组件启动时 EGL 初始化
- 当使用 EGL 的最后一个组件完成时,EGL 终止
- 多线程。不应该限制仅从主应用程序线程进行 EGL 操作。
请注意,当没有使用 EGL/OpenGL ES 的活动实体时,(2) 对于最大限度地减少应用程序对系统资源的使用至关重要。
有任何想法吗?或者也许我忽略了有关 Android 上的 EGL 的一些内容?
Update
还有另一个有趣的相关问题:
由于每个线程仅允许一个活动渲染上下文,因此同一时间只有一个组件可以正常从主线程使用 OpenGL ES。在主线程中同时运行多个使用 OpenGL ES 的组件会导致问题,因为最后一个组件调用例如:MakeCurrent()将隐式地用他自己的上下文“替换”所有其他组件的上下文(这实际上将完全破坏组件逻辑)。
更新2(最终版)
它被揭露了(感谢罗曼·盖伊)Android 实际上有一个针对 EGL 初始化/终止问题的内部解决方法,其形式是显式的(它违反了 EGL 规范,并且 Android 文档中未提及)“引用计数”egl初始化() and 例如终止().