OpenGL は、3D グラフィック処理ハードウェアの標準ソフトウェア インターフェースを定める、クロス プラットフォームのグラフィック API です。OpenGL ES は OpenGL 仕様の組み込みデバイス向けのサブセットです。
Android 互換であるためには、EGL、OpenGL ES 1.x、OpenGL ES 2.0 用のドライバを提供する必要があります。OpenGL ES 3.x のサポートは任意です。主に以下の点を考慮してください。
- GL ドライバを安定させ、OpenGL ES 標準に準拠するようにします。
- GL コンテキスト数を無制限にします。Android は、バックグラウンドのアプリを許可し、GL コンテキストを有効のままにしようとするため、ドライバでコンテキスト数を制限しないでください。
- 20~30 個の有効な GL コンテキストが同時に存在することがよくあるため、各コンテキストに割り当てられるメモリの量に注意してください。
- メディア コーデックやカメラなど、システム内の他のコンポーネントに由来する YV12 画像形式やその他の YUV 画像形式をサポートしてください。
- 必須の拡張機能である
EGL_KHR_wait_sync
、GL_OES_texture_external
、EGL_ANDROID_image_native_buffer
、EGL_ANDROID_recordable
をサポートしてください。また、Hardware Composer v1.1 以降では、EGL_ANDROID_framebuffer_target
拡張機能が必要です。
加えて、EGL_ANDROID_blob_cache
、EGL_KHR_fence_sync
、EGL_ANDROID_native_fence_sync
をサポートすることも強くおすすめします。
Android 10 は、EGL 1.5 インターフェースを実装しています。EGL 1.5 の新機能については、Khronos リリース 1.5 の仕様をご覧ください。
ドライバの読み込み
Android では、システム イメージのビルド時にシステムで使用可能な GPU が認識されると想定しています。32 ビット、64 ビットの OpenGL ES ドライバの推奨パスは、それぞれ /vendor/lib/egl
、/vendor/lib64/egl
です。ローダーは、2 つのシステム プロパティ ro.hardware.egl
と ro.board.platform
を使用して、または正確な名前を使用して、システム ドライバを検出して読み込みます。OpenGL ES ドライバは、1 つのバイナリでリリースするか、3 つのバイナリに分割してリリースする必要があります。OpenGL ES ドライバを 1 つのバイナリでリリースする場合、次のいずれかの名前を使用します。
libGLES_${ro.hardware.egl}.so libGLES_${ro.board.platform}.so libGLES.so
OpenGL ES ドライバを 3 つのバイナリでリリースする場合、次の名前の組のいずれかを使用します。
libEGL_${ro.hardware.egl}.so libGLESv1_CM_${ro.hardware.egl}.so libGLESv2_${ro.hardware.egl}.so libEGL_${ro.board.platform}.so libGLESv1_CM_${ro.board.platform}.so libGLESv2_${ro.board.platform}.so libEGL.so libGLESv1_CM.so libGLESv2.so
OpenGL ES レイヤ
Android 10 では、GLES 2.0 以降のレイヤシステムが導入されています。GLES レイヤは、アプリ内またはツールから提供される共有オブジェクトです。GLES レイヤは、Vulkan と同じ設定メカニズムを使用して、デバッグ可能アプリがレイヤを検出して読み込めるようにします。
GLES LayerLoader は、EGL ローダー内のコンポーネントであり、GLES レイヤを検出します。
GLES LayerLoader が検出したレイヤごとに、GLES LayerLoader が AndroidGLESLayer_Initialize
を呼び出し、libEGL の関数リストを調べて、すべての既知の関数に対して AndroidGLESLayer_GetProcAddress
を呼び出します。関数をインターセプトするレイヤの場合、関数のアドレスがトラッキングされます。
関数をインターセプトしないレイヤの場合、AndroidGLESLayer_GetProcAddress
は、渡されたものと同じ関数アドレスを返します。次に、LayerLoader はレイヤのエントリ ポイントを指すように関数フックリストを更新します。
レイヤを有効にする
GLES レイヤは、アプリレベルかグローバル レベルで有効にできます。アプリレベルの設定は再起動後も保持されますが、グローバル プロパティは再起動時にクリアされます。
アプリレベルでレイヤを有効にするには、次のコマンドを実行します。
# Enable layersadb shell settings put global enable_gpu_debug_layers 1
# Specify target appadb shell settings put global gpu_debug_app package_name
# Specify layer list (from top to bottom)adb shell settings put global gpu_debug_layers_gles layer1:layer2:...:layerN
# Specify packages to search for layersadb shell settings put global gpu_debug_layer_app package1:package2:...:packageN
アプリレベルでレイヤを無効にするには、次のコマンドを実行します。
adb shell settings delete global enable_gpu_debug_layers
adb shell settings delete global gpu_debug_app
adb shell settings delete global gpu_debug_layer_app
グローバル レベルでレイヤを有効にするには、次のコマンドを実行します。
# Attempts to load layers for all applications, including native executables
adb shell setprop debug.gles.layers layer1:layer2:...:layerN
レイヤをテストする
GLES レイヤは Android CTS に基づいているため、互換性のあるデバイスの CTS テストに合格する必要があります。デバイスでレイヤが動作しているかどうかを確認するには、$ atest CtsGpuToolsHostTestCases
を実行します。