安卓:OpenGL上下文何时被销毁?

15

在Android上,GLSurfaceView文档中有这样的说明:

当活动暂停和恢复时必须通知GLSurfaceView。GLSurfaceView客户端需要在活动暂停时调用onPause(),在活动恢复时调用onResume()。这些调用允许GLSurfaceView暂停和恢复渲染线程,也允许GLSurfaceView释放和重新创建OpenGL显示。

因此,在我的活动中,我应该像这样做:

public void onPause() {
    myGlSurfaceView.onPause();
}

public void onResume() {
    myGlSurfaceView.onResume();
}

我在代码中观察到,如果我不调用onPause()onResume()方法,则当我按下主页按钮时,上下文并不会丢失,因此我可以在应用程序之间切换,然后返回到我的游戏,一切正常。 我发现,如果我使用返回按钮关闭游戏,那么再次打开游戏时屏幕是黑色的,但是我可以更改返回按钮的行为以完全关闭游戏并避免此问题。

因此,我的问题是:什么时候销毁OpenGL上下文? 如果我不调用 onPause()onResume() 方法,我可以假定它永远不会被销毁吗?

编辑:

我的目标是 Android 2.2,因此对我而言,setPreserveEGLContextOnPause()不是一个选择。


我很好奇知道myGlSurfaceView.getPreserveEGLContextOnPause()的值。如果设置为true,则您的上下文可能会被保留。有关更多信息,请参见http://developer.android.com/reference/android/opengl/GLSurfaceView.html#setPreserveEGLContextOnPause(boolean)。 - R Hyde
@RodHyde 抱歉,我忘了说我的目标是 Android 2.2。 - Damian
这是一段使用GLSurface进行绘图的代码。http://code.google.com/p/andengine/source/browse/src/org/anddev/andengine/opengl/view/GLSurfaceView.java?r=ef54dd94f1fe8fa9ed134d993802c3c9974d3a84 - AZ_
你找到了一个适用于 Android 3.0 之前版本的好解决方案吗?我只能重建上下文并重新加载纹理,这会导致长时间的空白屏幕加载或者精灵突然出现,看起来很糟糕。 - james82345
2个回答

28

只有在调用Actvity::onPause()后,OpenGL才可能会丢失,而且仅在这种情况下。请参阅setPreserveEGLContextOnPause文档:

实际上是否保留EGL上下文取决于程序运行的Android设备是否支持任意数量的EGL上下文。只能支持有限数量的EGL上下文的设备必须释放EGL上下文,以允许多个应用程序共享GPU。 [...] 当GLSurfaceView暂停时,EGL上下文将被释放,并在GLSurfaceView恢复时重新创建。

编辑:文档中描述的情况在所有Android版本上都是有效的。不管你是否可以访问setPreserveEGLContextOnPause

在我看来,这是Android OGLES实现的一个主要缺点:你不能确定。

documentation本身含糊不清(EGL Context Lost note):

在某些情况下,EGL渲染上下文可能会丢失。这通常发生在设备从休眠状态中唤醒后。
我注意到你对Home和Back按钮的行为与我相同。调用并不完全相同(但无法准确记住)。
确定OpenGL上下文可用的唯一方法是在onSurfaceCreated中创建所有OpenGL资源。
关于setPreserveEGLContextOnPause的注意事项。再次说明,这个 documentation comment展示了上下文销毁的“随机”行为:

如果设置为true,则当GLSurfaceView暂停时,EGL上下文可能会被保留。[...]


抱歉,我忘了说我的目标是 Android 2.2。 - Damian
我也在Android 2.2上工作。在这种情况下,setPreserveEGLContextOnPause不可用,但它并不改变OpenGL上下文丢失的方式... - rockeye
我仍然不清楚。所以,如果我不调用GLSurfaceView的onPause()方法,并在请求确认后处理返回键来关闭应用程序,那么上下文将永远不会被销毁? - Damian
更或少 : 这就是 Android(顺便提一下,iOS也是如此)的工作方式。如果您不完全关闭应用程序,则它将保留在内存中以加快下次启动并检索完全相同的状态。然而,正如文档中所指定的那样,如果其他应用程序创建OpenGL上下文,则Android可能会销毁您的应用程序中的上下文。关于是否调用OnPause,文档说:GLSurfaceView客户端需要调用onPause()。建议遵循这个,否则您可能会因操作系统版本或设备而产生意外的结果...但当然,您可以自由选择不调用它! - rockeye

1

使用您的GlSurfaceView实现在Adreno设备上会发生什么? - Damian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接