防止onPause破坏OpenGL上下文

我正在编写一个使用OpenGL ES(GLSurfaceView和GLSurfaceView.Renderer)的Android应用程序。 问题是,当用户切换应用程序,然后切换回我的应用程序,GLSurfaceView销毁并重新创buildGL上下文。 这是根据文档应该做什么,但有没有办法来防止这种情况发生?

将纹理加载到上下文中需要很长时间,并且我想阻止必须重新加载它们。

Solutions Collecting From Web of "防止onPause破坏OpenGL上下文"

我认为你在找什么在GLSurfaceView文档中讨论:

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

使用标准Android SDK时,只要活动暂停/恢复(包括屏幕方向更改),就必须释放/重新创build上下文。 不这样做会导致GL上下文被释放,并在活动被加载回内存时不被恢复。 请记住,我们正在处理非常有限的资源(特别是在低规格设备上)。 所以简短的回答是:你不能阻止它,而不会破坏你的应用程序。

假设你正在使用标准的Android / OpenGL框架,你需要执行以下操作…

在您的活动中,确保您有以下重写的方法:

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

在GL环境之外的任何东西,仍然需要手动保存和恢复(位图,游戏状态等),因此需要使用静态字段或像SharedPreferences这样的机制。

更新

Android 3.x提供了一个函数来暂停GL上下文,而不需要重新创build。 但是,有几个警告:

  1. Android 3.xfunction不提供约。 目前市场上有90%的设备
  2. 该设备还必须支持多个EGL上下文,目前市场上有多less设备支持这一点尚不清楚。

使用一些APIreflection来检查function,可以在支持设备上使用这个function。 但是,您仍然需要重新为其余部分重新创build上下文。 在我看来,直到更多的设备运行Android 3,最好是setPreserveEGLContextOnPause使用setPreserveEGLContextOnPause并重点确保上下文娱乐方法得到充分testing。

正如在上面的评论中提到的,也可以避免在Android版本(1.x,2.x)之前废弃GL上下文,解决scheme是从Android-15 SDK源代码复制GLSurfaceView,更改其包名,然后使用您自己的GlSurfaceView副本。

它应该适用于支持多种GL环境的设备(Adreno芯片除外),无论Android版本如何。 需要注意的是,Android-15的GLSurfaceView只包含了使用android-15所必需的东西,我们的版本必须处理所有的操作系​​统版本。

我们使用我们自己的实现GlSurfaceView基于从ReplicaIsland副本,其中Chriss Pruit也使用他自己的实现。

在我们的版本中,我们添加了来自SDK-15的setPreserveEGLContextOnPause,它允许保持GL上下文,例如运行android 2.3的nexus。

我们也改变了其他的东西,以适应我们的需要,这是不相关的这个问题(如在支持它的手机32位渲染,否则16位)。

我们的GlSurfaceView: http ://pastebin.com/U4x5JjAr

这里是与上面http://pastebin.com/hziRmB3E相同(Android)风格格式化的原始SDK-15版本的GlSurfaceView(因此很容易比较和查看更改)

请记住通过调用以下命令启用上下文保留

  glSurfaceView.setPreserveEGLContextOnPause(true); 

从API级别11开始,您可以指定是否必须保留您的上下文。

从文档:

public void setPreserveEGLContextOnPause (boolean preserveOnPause)从以下版本开始:API Level 11

控制在GLSurfaceView暂停和恢复时是否保留EGL上下文。

如果设置为true,那么在GLSurfaceView暂停时可以保留EGL上下文。 EGL上下文是否实际保留取决于程序运行的Android设备是否可以支持任意数量的EGL上下文。 只能支持有限数量的EGL上下文的设备必须释放EGL上下文才能允许多个应用程序共享GPU。

如果设置为false,当GLSurfaceView被暂停时,EGL上下文将被释放,并且当GLSurfaceView被恢复时被重新创build。

默认值是false。

参数preserveOnPause暂停时保留EGL上下文

从我使用OpenGL开始,这已经有一段时间了,这是桌面PC上的标准sorting,但我似乎记得标准的OpenGL不需要在上下文切换时重新加载纹理。 当然,这在这种情况下并没有什么帮助。

假设纹理必须重新加载,问题就变成了:你如何加快速度? 那么问题就变成了,你一次只需要多less纹理,你可以根据需要加载纹理吗? 他们的维度是什么? 我记得两个幂的加载通常比较快,不过这也可能取决于OpenGL的实现和驱动程序。

我也听说过把上下文保存在一个不会被销毁的地方,有点像这个线程: opengles view switching problem