グラフィックのアーキテクチャ

すべてのデベロッパーが Surface、SurfaceHolder、EGLSurface、SurfaceView、GLSurfaceView、SurfaceTexture、TextureView、SurfaceFlinger、Vulkan に関して知っておくべきこと。

このページでは、Android のシステムレベルのグラフィックのアーキテクチャの重要な要素と、アプリケーションのフレームワークとマルチメディア システムでの使用方法について説明します。重要なのは、グラフィカル データのバッファがシステム内をどのように動くかです。SurfaceView と TextureView の動作の背景にあるものや、Surface と EGLSurface の操作について疑問に思ったことがあるのならば、このページでその答えを確認できます。

Android デバイスとアプリケーション開発にある程度精通していることが前提です。API フレームワークの詳細な知識は不要で、API 呼び出しについてもほとんど言及していませんが、コンテンツは他の公開ドキュメントとは重複していません。目標は、出力フレームのレンダリングに関係する重要なイベントの詳細を提供して、アプリケーションの設計時に、十分な情報に基づいて選択できるようにすることです。これを実現するために、UI クラスの使い方ではなく仕組みを初めから説明します。

このセクションでは、背景資料から HAL の詳細、ユースケースまで、あらゆるコンテンツを取り上げます。まず Android のグラフィック バッファについての説明から始め、構成と表示の仕組みを説明し、それからコンポジタにデータを供給する高レベルのメカニズムに進みます。興味のあるトピックだけでなく、順番にページを読み進めていくことをおすすめします。

下位コンポーネント

  • BufferQueue と gralloc。BufferQueue は、グラフィック データのバッファを生成するもの(プロデューサー)と、ディスプレイまたは追加処理のデータを受け入れるもの(消費者)を接続します。バッファ割り当ては、ベンダー固有の HAL インターフェースを介して実装された gralloc のメモリ アロケータを介して行われます。
  • SurfaceFlinger、Hardware Composer、および仮想ディスプレイ。SurfaceFlinger は、複数のソースからデータのバッファを受け取り、合成してディスプレイに送信します。Hardware Composer HAL(HWC)は、使用可能なハードウェアでバッファを合成する最も効率的な方法を決定し、仮想ディスプレイは、システム内で合成された出力を使用可能にします(画面を録画またはネットワーク経由で送信します)。
  • Surface、Canvas、および SurfaceHolder。Surface は、SurfaceFlinger でよく使用されるバッファキューを生成します。Surface にレンダリングすると、結果は消費者に送られるバッファに格納されます。Canvas API は、Surface 上に直接描画するために、ハードウェア アクセラレーションのサポートがあるソフトウェア実装を提供します(OpenGL ES の低レベルの代替方法です)。View と関係があるものはすべて SurfaceHolder があり、その API は、サイズや形式などの Surface パラメータの取得と設定を可能にします。
  • EGLSurface と OpenGL ES。OpenGL ES(GLES)は、EGL(オペレーティング システムからウィンドウを作成してアクセスする方法を認識するライブラリ)と組み合わせるように設計されたグラフィック レンダリング API を定義します(テクスチャのあるポリゴンを描画するには GLES 呼び出しを使用し、画面にレンダリングを置くには EGL 呼び出しを使用します)。このページでは、ネイティブ コードから EGL ウィンドウ サーフェスを作成するために使用される Java Surface クラスの C / C++ と同等の ANativeWindow についても説明します。
  • Vulkan。Vulkan は、高パフォーマンスの 3D グラフィックを実現する、低オーバーヘッドのクロス プラットフォーム API です。Vulkan は、OpenGL ES と同様に、アプリケーションで高品質のリアルタイム グラフィックを作成するためのツールを提供します。Vulkan のメリットとしては、CPU オーバーヘッドを削減できることや SPIR-V バイナリ中間言語をサポートしていることなども挙げられます。

上位コンポーネント

  • SurfaceView と GLSurfaceView。SurfaceView は Surface と View を結合します。SurfaceView の View コンポーネントは、SurfaceFlinger で作成され(かつアプリでは作成されず)、別のスレッドやプロセスからのレンダリングと、アプリの UI レンダリングからの分離を可能にします。GLSurfaceView は、EGL コンテキスト、スレッド間の通信、アクティビティのライフサイクルでの操作を管理するヘルパークラスを提供します(GLES を使用する必要はありません)。
  • SurfaceTexture。SurfaceTexture は、Surface と GLES テクスチャを結合して、アプリが消費者である BufferQueue を作成します。プロデューサーは、新しいバッファをキューに登録するとアプリに通知します。次に、以前保持していたバッファを解放してキューから新しいバッファを取得し、EGL を呼び出して GLES がバッファを外部テクスチャとして使用できるようにします。Android 7.0 には、保護された動画コンテンツの GPU 後処理を可能にする安全なテクスチャ動画再生のサポートが追加されています。
  • TextureView。TextureView は、View と SurfaceTexture を結合します。TextureView は、SurfaceTexture をラップし、コールバックへの応答と新しいバッファの取得を行います。TextureView は描画の際に、最後に受信したバッファのコンテンツをそのデータソースとして使用し、View の状態が示すあらゆる場所、方法でレンダリングします。View の構成は常に GLES を使用して実行されるため、コンテンツの更新によって他の View 要素も再描画されます。