【问题标题】:Prevent EGLContext to be destroyed when going to background进入后台时防止 EGLContext 被销毁
【发布时间】:2015-05-16 22:46:08
【问题描述】:

当用户最小化我的 Android (OpenGL ES 2.0) 游戏时,需要暂停它,而不破坏已经在屏幕上绘制的内容。最初它使用的是 NativeActivity 和纯 C++,但看起来在那里是不可能的。我已经重写了它,它现在是 Java 生成自定义 GLSurfaceView 和游戏逻辑+渲染是在 C++ 中。我在创建表面时添加了 setPreserveEGLContextOnPause(true)

所以用户点击主页按钮后的缺陷是:

  1. onPause 正在通过 JNI 将 nativeOnPause 发送到 C++ 代码
  2. C++ 代码设置了阻止更新和渲染的暂停变量

这工作正常。回到应用后:

  1. onResume 调用 nativeOnResume
  2. nativeOnResume 调用 EGL 方法来获取当前上下文、显示和表面并将其传递给游戏管理器。
  3. 更新和渲染现已激活
  4. 我们收到几条 EGL_BAD_SURFACE 消息,最后在 eglMakeCurrent 上崩溃

问题是:我们应该以任何方式使用当前上下文重新创建 EGLSurface 和 EGLDisplay,还是获取当前表面和显示都可以?

我还注意到,当我们回到应用程序时,onResume 被调用,但 onSurfaceChangedonSurfaceCreated 没有被调用。

有什么建议可以在 >4.0 设备上解决这个问题吗?

【问题讨论】:

    标签: android opengl-es android-ndk glsurfaceview onpause


    【解决方案1】:

    如果您想控制 EGL 上下文生存期,请不要使用 GLSurfaceView。

    GLSurfaceView 类为您处理 EGL 上下文,并且非常积极地丢弃它。 setPreserveEGLContextOnPause() 调用可能不会做你想做的事。如果您切换到 SurfaceView,您将可以完全控制 EGL 上下文生存期,但这是一把双刃剑,因为您现在需要完全管理 EGL 上下文。

    您可以在Grafika 中找到各种将 GLES 与 SurfaceView 结合使用的示例。 “hardware scaler exerciser”活动就是一个合理的例子。

    该活动还展示了一种活动生命周期管理方法。有关 Activity 和 SurfaceView 之间关系的讨论,包括为什么您并不总是看到 surfaceChanged()surfaceCreated(),可以在图形架构文档中找到 in an appendix

    话虽如此,但在您的应用处于非活动状态时保留 EGL 上下文和所有相关资源是一种不好的做法。当用户暂停您的应用时,应释放这些资源,以便其他应用可以使用设备的全部功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 1970-01-01
      相关资源
      最近更新 更多