2

すでに死に至っていると確信しているので、この問題を再び提起してしまったことをお詫びします。:)

ただし、完全にネイティブなゲームをAndroidに変換しており、現在GLコンテキスト損失の処理を検討しています。

GLアセットを含むゲーム内の「リソース」のリストを維持しているので、それらをスピンしてGLコンテキストを復元することができます。ただし、これは単純化されたテストアプリケーションでは機能しますが、コンテキストの損失はいつでも発生する可能性があるため、他のゲーム領域(開始のためのスレッド化されたリソース処理)を変更する必要があるのではないかと少し心配しています。私はすべてをカバーしています。

私の心の奥底では、コンテキスト損失の発生を防ぐことが、サポートする必要のあるさまざまなデバイス(すべて2年未満)およびAPI8を使用するためのより安全なオプションであると感じずにはいられません。

これが実際に実行可能かどうかを判断するための最初のパスとして、拡張GLSurfaceViewクラス実装で静的EGLContextを作成し、これにコンテキストを作成しました(ネイティブAndroidアプリケーションは、のhello-gl2jniの例に基づいていますandroid ndk):

public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
  if (mEGLContext == null)
  {
    ...
    mEGLContext = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
  }
  return mEGLContext;
}

次に、destroycontext呼び出しを削除しました。

public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
  //egl.eglDestroyContext(display, context);
}

次に、アプリケーションの再入力時に、[ホーム]を押し、[最近のアプリのリスト]ボタンからアプリケーションを選択すると、アプリケーションがクラッシュしました。トレースログは次のとおりです。

// home button pressed
05-23 17:04:26.784: W/GlContextTrace(11504): Activity State Change: 'onPause' (pausing)
05-23 17:04:26.808: W/GlContextTrace(11504): 'GLSurfaceView.EGLContextFactory::destroyContext' (doesn't actually call eglDestroyContext)
05-23 17:04:27.519: W/GlContextTrace(11504): Activity State Change: 'onStop'

// application re-entry
05-23 17:04:30.089: W/GlContextTrace(11504): Activity State Change: 'onRestart'
05-23 17:04:30.089: W/GlContextTrace(11504): Activity State Change: 'onStart'
05-23 17:04:30.089: W/GlContextTrace(11504): Activity State Change: 'onResume'
05-23 17:04:30.229: W/GlContextTrace(11504): 'GLSurfaceView.EGLContextFactory::createContext' (uses the  previously created GL context)

// which immediately invokes destroyContext and ends my application:
05-23 17:04:30.315: W/GlContextTrace(11504): 'GLSurfaceView.EGLContextFactory::destroyContext'
05-23 17:04:30.479: W/GlContextTrace(11504): Activity State Change: 'onPause'
05-23 17:04:30.636: W/GlContextTrace(11504): Activity State Change: 'onStop'
05-23 17:04:30.636: W/GlContextTrace(11504): Activity State Change: 'onDestroy'

クラッシュログは次のとおりです。

05-23 17:04:30.401: W/dalvikvm(11504): threadid=11: thread exiting with uncaught exception (group=0x40a361f8)
05-23 17:04:30.409: E/AndroidRuntime(11504): FATAL EXCEPTION: GLThread 753
05-23 17:04:30.409: E/AndroidRuntime(11504): java.lang.RuntimeException: eglMakeCurrent failed: EGL_SUCCESS
05-23 17:04:30.409: E/AndroidRuntime(11504):    at android.opengl.GLSurfaceView$EglHelper.throwEglException(GLSurfaceView.java:1178)
05-23 17:04:30.409: E/AndroidRuntime(11504):    at android.opengl.GLSurfaceView$EglHelper.throwEglException(GLSurfaceView.java:1170)
05-23 17:04:30.409: E/AndroidRuntime(11504):    at android.opengl.GLSurfaceView$EglHelper.createSurface(GLSurfaceView.java:1081)
05-23 17:04:30.409: E/AndroidRuntime(11504):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1433)
05-23 17:04:30.409: E/AndroidRuntime(11504):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)

ここでのプロセスを完全に理解していないことを強調していると思いますが、クラッシュには少し驚きました。

GLコンテキストの損失を防ぎ、クラッシュすることなくアプリケーションに正常に再入力できるようにGLSurfaceViewクラスの実装を変更して、このオプションをテストできるようにする方法はありますか?

私は自分でこれをやろうとしていると言わなければならないので、私がそれを行う方法を見つけたら答えを投稿します。:)

どうもありがとう、

アンディ・スレイター

4

1 に答える 1

5

Android では、GL コンテキストを強制的に保持しないでください。モバイル デバイスでは、デバイスの機能に応じて、アプリケーションがコンテキストを解放するように求められたり、要求されたりするのが普通です (後でコンテキストを取得します)。

保持する代わりに、GL コンテキストが再び利用可能になったときにゲーム リソースをリロードする必要があります。これを行うのに適した場所は、Renderer.onSurfaceCreatedイベントです。このメソッドは、コンテキストが作成または再作成されるたびに (つまり、以前に失われたコンテキストが返されたときに) GL レンダラー スレッドによって呼び出されます。

したがって、GL コンテキストが失われ、それについてわからないことを心配する必要はありません。コンテキストが回復されると、onSurfaceCreated が常に呼び出されます。これについては確実です。

ちなみに、Android アプリケーションでは、Activity.onPause() で GLSurfaceView を一時停止し、Activity.onResume() で再開する必要があります。これらは、GLSurfaceView.onPause() および onResume() を介して実現できます。

于 2012-05-23T16:56:30.453 に答える