EGLSurface と OpenGL ES

Android は OpenGL ES(GLES)API を使用してグラフィックをレンダリングします。GLES コンテキストを作成し、GLES レンダリング用のウィンドウ システムを提供するために、Android は EGL ライブラリを使用します。GLES 呼び出しはテクスチャのあるポリゴンをレンダリングし、EGL 呼び出しは画面にレンダリングを配置します。

GLES で描画する前に、GL のコンテキストを作成する必要があります。EGL では、これは EGLContext と EGLSurface を作成することを意味します。GLES オペレーションは、現在のコンテキストに適用されます。このコンテキストは、引数として渡されるのではなく、スレッド ローカルのストレージ経由でアクセスされます。レンダリングのコードは、UI スレッドではなく、現在の GLES スレッドで実行する必要があります。

EGLSurface

EGLSurface は、pbuffer と呼ばれる EGL によって割り当てられたオフスクリーンのバッファ、またはオペレーティング システムによって割り当てられたウィンドウになります。eglCreateWindowSurface() 関数を呼び出すと、EGL ウィンドウのサーフェスが作成されます。eglCreateWindowSurface() は、ウィンドウのオブジェクトを引数(Android ではサーフェス)として取得します。サーフェスは、BufferQueue のプロデューサー側です。SurfaceView、SurfaceTexture、TextureView、または ImageReader であるコンシューマーが、サーフェスを作成します。eglCreateWindowSurface() を呼び出すと、EGL は新しい EGLSurface オブジェクトを作成し、作成したオブジェクトをウィンドウ オブジェクトの BufferQueue のプロデューサー インターフェースに接続します。その以降に対象の EGLSurface にレンダリングされると、バッファはキューから除外され、レンダリングされて、コンシューマーが使用できるようキューに登録されます。

EGL は、ロックやロック解除の呼び出しを行いません。描画コマンドを発行してから eglSwapBuffers() を呼び出して、現在のフレームを送信します。メソッド名は従来の前後バッファの入れ替えに由来しますが、実際の実装は異なる場合があります。

一度にサーフェスと関連付けることができる EGLSurface は 1 つのみ(BufferQueue に接続できるのは 1 つのプロデューサーのみ)ですが、その EGLSurface を破壊した場合、BufferQueue との接続は解除され、他の対象が BufferQueue と接続されます。

対象のスレッドは、現在のものを変更することで、複数の EGLSurface 間で切り替えることができます。EGLSurface は、一度に 1 つのスレッドでのみ最新のものであることが必要です。

EGL は、SurfaceHolder のようにサーフェスのもう 1 つの側面ではありません。EGLSurface は関連付けられていますが、独立した概念です。サーフェスに基づいていない EGLSurface に描画でき、EGL なしでもサーフェスを使用できます。EGLSurface は、描画する場所を GLES に提供するだけです。

OpenGL ES と EGL の要件については、Android の互換性定義ドキュメントを参照してください。

ANativeWindow

一般公開のサーフェス クラスは Java プログラミング言語で実装されています。C / C++ の同等のクラスは、Android NDK によって準公開されている ANativeWindow のクラスです。ANativeWindow は ANativeWindow_fromSurface() 呼び出しを使用してサーフェスから取得できます。Java 言語の親族と同様、ソフトウェアでのロック、レンダリング、ロック解除と投稿が可能です。基本のネイティブ ウィンドウの型は、BufferQueue のプロデューサー側です。

ネイティブ コードから EGL ウィンドウのサーフェスを作成するには、EGLNativeWindowType のインスタンスを eglCreateWindowSurface() に渡します。EGLNativeWindowType は、ANativeWindow の類義語であるため、一方を他方にキャストできます。