NDKベースのゲームをAndroidICSで動作させようとしています。HoneycombとGingerbreadでは問題なく機能しました。
ゲームは、いくつかの2Dレンダリング、いくつかの3Dレンダリングを使用し、実行のさまざまな段階で2つを切り替えます。(サードパーティのコードのため、これは交渉できません。)2DレンダリングにはANativeWindow_lock()
/を使用し、3Dレンダリングには// 3を使用しています。ANativeWindow_unlockAndPost()
eglCreateWindowSurface()
gl*()
eglSwapBuffers()
HoneycombとGingerbreadでは、これはすべて正常に機能しました。ICSではeglCreateWindowSurface()
、ログに次のメッセージが表示されて失敗します。
E/SurfaceTexture( 1765): [com.fnord/com.fnord.MyActivity] connect: already connected (cur=2, req=1)
E/libEGL ( 5466): EGLNativeWindowType 0x29e9b8 already connected to another API
E/libEGL ( 5466): eglCreateWindowSurface:374 error 300b (EGL_BAD_NATIVE_WINDOW)
E/libEGL ( 5466): call to OpenGL ES API with no current context (logged once per thread)
ソースコードを見ると、2Dレンダリング用にネイティブウィンドウが開いているために失敗していることは明らかですeglCreateWindowSurface()
。最初にサーフェスを解放しないと、3Dに変更できません。ただし、ANativeWindow APIには、これを行うための明確な方法がないようです。
他の誰かがこれに遭遇しましたか、そして解決策は何ですか?
更新しました
そこで、代わりにOpenGLプリミティブを使用するように2Dレンダリングコードを書き直しました(バックバッファーをテクスチャにアップロードし、三角形のペア、スワップバッファーを介してテクスチャをレンダリングします)。これはある程度まで機能します。ここで起こっているのは、2Dレンダリングが正常に機能することです。次に、サーフェスを破棄し、3Dレンダリングの準備として新しいサーフェスを作成すると、2回目の呼び出しがeglCreateWindowSurface()
失敗します。今回は、次のようになります。
E/SurfaceTexture( 1869): [com.fnord/com.fnord.MyActivity] connect: already connected (cur=1, req=1)
...そしてそれはのEGLエラーをスローしますAEGL_BAD_NATIVE_WINDOW
。
新しいサーフェスは、古いサーフェスとまったく同じ属性で作成されることに注意してください。私は、への2つの呼び出しの間にeglTerminate()
/を呼び出すことを確認しようとしました。eglInitialize()
eglCreateWindowSurface()
各ANativeWindowを1回だけ使用できるのですか?もしそうなら、それはクロノスのEGL適合性テストに失敗しませんか?では、NativeActivityにウィンドウを再作成させる方法はありますか?
更新更新
最後の問題はeglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)
、コンテキストとサーフェスを破棄する前に電話をかけなかったことが原因であることが判明しました。これにより、スレッドがコンテキストとサーフェスのバインドを解除するまで破棄が遅延していましたが、もちろんそうではなかったため、呼び出しはeglCreateWindowSurface()
合法的に失敗しました(同じネイティブウィンドウに2つのウィンドウサーフェスを設定することはできません)。
これは少しeglTerminate()
直感に反します。これは、呼び出しによってすべてのEGLリソースが破棄されると想定されるためですが、仕様では許可されています。注意してください!