Android ゲームの開発や最適化を行う際に、エンジンが使用しているグラフィック パイプラインを把握することは、多くの場合に役立ちます。エンジンは、デベロッパーが明確にアクセスできるシグナルなしで、Vulkan または GLES を選択することがあります。残念ながら、ゲームが Vulkan で実行されているか、OpenGL ES にサイレント フォールバックしているかを確認するために logcat に依存すると、信頼性が低下する場合があります。
このガイドでは、Android Performance Analyzer(APA)とカスタム Perfetto SQL クエリを使用して、ゲームのアクティブなレンダリング API を特定する方法について説明します。
ログベースの検証の制限事項
- ストリップ ログ: 製品版ビルドでは、初期化とドライバ読み込みのフットプリントが隠されていることがよくあります。
- 誤検出: 一部のゲームエンジンは、起動時に Vulkan ライブラリと OpenGL ES ライブラリの両方を読み込み、最終的にいずれかが失敗してフォールバックがトリガーされた場合でも、両方の初期化ログを出力します。
- サイレント フォールバック: デバイス固有のドライバの問題が原因で Vulkan の初期化が失敗した場合、エンジンは重大なエラーをスローせずに OpenGL ES にフォールバックすることがよくあります。
APA を使用して測定する
Android Performance Analyzer を使用すると、システム トレースを記録し、SQL クエリを使用してフレームデータを正確に分析できます。Vulkan と GLES の使用状況を測定する手順は次のとおりです。
APA でトレースをキャプチャする: ゲームを実行し、APA を使用して、分析するセグメント(ゲームプレイ中にフレーム落ちが疑われるポイントなど)のシステム トレースをキャプチャします。デバイスが接続され、トレースの記録が完了すると、トレースデータが APA インターフェースに読み込まれます。
APA で [SQL] タブをクリックする: トレース分析画面が開いているときに、UI のナビゲーション メニューで [SQL] タブをクリックしてトレース プロセッサ環境を開きます。この環境で、データを直接クエリできます。
APA SQL タブに次の SQL クエリを貼り付けます: 次の SQL クエリをコピーして、クエリ入力フィールドに貼り付けます。このクエリは、
eglSwapBuffers、QueuePresentKHR、vkQueuePresentKHRなどの描画 API イベントのトレースをスキャンします。プロセス名でグループ化し、レンダリング API の数と、Vulkan と OpenGL ES のレンダリング呼び出しの割合分布を計算します。WITH raw_slices AS ( -- 1. Map each slice (API call) to its corresponding process or package via UTID and UPID SELECT p.name AS process_name, s.name AS slice_name FROM slice s JOIN thread_track tt ON s.track_id = tt.id JOIN thread t USING (utid) JOIN process p USING (upid) WHERE (s.name LIKE 'eglSwapBuffers%' OR s.name IN ('QueuePresentKHR', 'vkQueuePresentKHR')) -- Optional: To isolate your game, uncomment the following and filter by package name and thread name: -- AND p.name = 'com.example.mygame' -- AND t.name = 'RenderThread' ), process_stats AS ( -- 2. Aggregate counts per individual process SELECT process_name, SUM(CASE WHEN slice_name LIKE 'eglSwapBuffers%' THEN 1 ELSE 0 END) AS egl_count, SUM(CASE WHEN slice_name IN ('QueuePresentKHR', 'vkQueuePresentKHR') THEN 1 ELSE 0 END) AS vulkan_count FROM raw_slices GROUP BY process_name ), process_totals AS ( -- 3. Calculate total counts for denominator calculation SELECT process_name, egl_count, vulkan_count, (egl_count + vulkan_count) AS total_count FROM process_stats ) -- 4. Calculate final percentage shares per row, preventing division by zero errors SELECT process_name, egl_count, vulkan_count, total_count, ROUND(CAST(egl_count AS REAL) * 100 / NULLIF(total_count, 0), 2) AS "egl_percentage(%)", ROUND(CAST(vulkan_count AS REAL) * 100 / NULLIF(total_count, 0), 2) AS "vulkan_percentage(%)" FROM process_totals ORDER BY total_count DESC;クエリを実行する: 入力フィールドの近くにある [クエリを実行] ボタンをクリックします。クエリを実行すると、結果ペインにテーブルが表示されます。このテーブルには、プロセス名(
process_name)、OpenGL ES プレゼンテーション数(egl_count)、Vulkan プレゼンテーション数(vulkan_count)、プレゼンテーションの合計数(total_count)、各 API の使用率(egl_percentage(%)とvulkan_percentage(%))が表示されます。
実行された SQL クエリと、テーブルに表示されたレンダリング API の指標を示す画面
主な注意点
SurfaceFlingerの混乱を避ける: 検索の範囲は常にゲームのアプリケーション スレッド(RenderThread)に設定してください。SurfaceFlingerなどのシステム全体のコンポジタ プロセスには、ゲームの内部レンダリング パイプラインではなく、システム UI レンダリングを表す Vulkan トラックや EGL トラックが表示されることがあります。ゲームを分離するには、メインの SQL クエリのWHERE句にある省略可能なフィルタのコメントを解除し、'com.example.mygame'をゲームのパッケージ名に置き換えます。-- AND p.name = 'com.example.mygame' -- AND t.name = 'RenderThread'ウォームアップ期間: ゲームのメインの 3D シーンが完全に読み込まれた後に、必ずトレースを記録します。スプラッシュ画面や読み込みの切り替え中にキャプチャすると、誤解を招く初期化になる可能性があります。
LevelUp Exemption Trace の要件
Google Play Games LevelUp の免除を受けるために Android Performance Analyzer(APA)を使用してトレースをキャプチャする場合、トレースが有効になるための特定のハードウェア要件があります。
トレースは、対象の Level Up リファレンス デバイスのいずれかを使用してキャプチャすることを強く推奨します。
また、正確な検証を行うため、ANGLE GPU を使用するデバイスでトレースを取得しないでください。具体的には、次のデバイスを使用して LevelUp 免除のトレースをキャプチャすることはできません。
- AMD Xclipse GPU を使用する SLSI(Samsung)の GPU ベンダーのデバイス
- Google Pixel 11