グラフィック

Android グラフィック HAL アイコン

Android フレームワークは、メーカーによって実装されるグラフィック ドライバと連携する、2D および 3D 用のさまざまなグラフィック レンダリング API を提供します。したがって、上位レベルでの API の動作を十分に理解することが重要です。このページでは、ドライバがビルドされるグラフィック ハードウェア抽象化レイヤ(HAL)について説明します。

アプリ デベロッパーが画面に画像を描画するには、CanvasOpenGL ES、または Vulkan を使用する 3 つの方法があります。

Android グラフィック コンポーネント

デベロッパーがどのレンダリング API を使用しても、すべて「サーフェス」にレンダリングされます。サーフェスは、SurfaceFlinger でよく使用されるバッファキューのプロデューサー側を表します。Android プラットフォームで作成されるすべてのウィンドウは、サーフェスによってサポートされています。レンダリングされた表示可能なすべてのサーフェスは、SurfaceFlinger によってディスプレイ上に合成されます。

主要コンポーネントの連携の仕組みを示したのが次の図です。

画像レンダリング コンポーネント

図 1. サーフェスのレンダリングの仕組み

主要コンポーネントについて以下で説明します。

画像ストリーム プロデューサー

画像ストリーム プロデューサーとは、使用するグラフィック バッファを生成するもののことです。たとえば、OpenGL ES、Canvas 2D、mediaserver 動画デコーダなどがあります。

画像ストリーム コンシューマ

画像ストリームの最も一般的なコンシューマは SurfaceFlinger です。このシステム サービスはウィンドウ マネージャーから提供された情報を使用して、現在表示されているサーフェスをディスプレイに合成します。SurfaceFlinger は、ディスプレイのコンテンツを変更できる唯一のサービスであり、OpenGL と Hardware Composer を使用してサーフェスのグループを作成します。

その他の OpenGL ES アプリでも画像ストリームを使用できます(カメラアプリがカメラ プレビュー画像ストリームを使用するなど)。GL 以外のアプリがコンシューマになる場合もあります(ImageReader クラスなど)。

Hardware Composer

ディスプレイ サブシステム用のハードウェア抽象化です。SurfaceFlinger は特定の合成処理を Hardware Composer に委任して、OpenGL と GPU から作業をオフロードできます。SurfaceFlinger は普通の OpenGL ES クライアントとして動作するので、たとえばアクティブに 1 つまたは 2 つのバッファを 3 つ目に合成する場合は、OpenGL ES を使用します。この結果、GPU ですべての計算を実行するよりも、合成の消費電力が抑えられます。

残りの処理を行う Hardware Composer HAL は、すべての Android グラフィック レンダリングの中心です。Hardware Composer は、VSYNC などのイベントに対応する必要があります(他のイベントとして、プラグアンドプレイ HDMI をサポートするためのホットプラグがあります)。

Gralloc

グラフィック メモリ アロケータ(Gralloc)は、画像プロデューサーが要求するメモリを割り当てるために必要です。詳細については、Gralloc HAL をご覧ください。

データフロー

Android グラフィック パイプラインを示したのが次の図です。

グラフィック データフロー

図 2. Android でのグラフィック データフロー

左側のオブジェクトは、ホーム画面、ステータスバー、システム UI などのグラフィック バッファを作成するレンダラです。SurfaceFlinger はコンポジターで、Hardware Composer はコンポーザーです。

BufferQueue

BufferQueue は、Android グラフィック コンポーネント同士を接続します。これらは、プロデューサーからコンシューマへのバッファのサイクルを一定に保つキューのペアです。プロデューサーがバッファを渡すと、SurfaceFlinger はディスプレイ上にすべてを合成します。

BufferQueue の通信プロセスについては、次の図をご覧ください。

BufferQueue の通信プロセス

図 3. BufferQueue の通信プロセス

BufferQueue には、画像ストリーム プロデューサーと画像ストリーム コンシューマを関連付けるロジックが含まれます。画像プロデューサーには、カメラ HAL または OpenGL ES ゲームで作成されるカメラ プレビューなどがあります。画像コンシューマには、SurfaceFlinger や、OpenGL ES ストリームを表示するアプリ(カメラのビューファインダーを表示するカメラアプリなど)があります。

BufferQueue は、バッファプールとキューを結合し、Binder IPC を使用してプロセス間でバッファを渡すデータ構造です。プロデューサー インターフェース、つまりグラフィック バッファを生成する相手に渡すものは、IGraphicBufferProducer(SurfaceTexture の一部)です。BufferQueue は、さまざまなタスクの中でもサーフェスへのレンダリングと GL コンシューマでの処理によく使用されます。BufferQueue は次の 3 つのモードで動作します。

同期優先モード - デフォルトで BufferQueue は同期優先モードで動作し、プロデューサーから受け取ったすべてのバッファをコンシューマに渡します。このモードでは、バッファが破棄されることはありません。プロデューサーの速度が速すぎて、使いきる前にバッファが作成される場合は、ブロックして空きバッファを待機します。

非ブロッキング モード - BufferQueue は非ブロッキング モードでも動作可能で、前述の状況ではバッファを待たずにエラーを生成します。このモードでもバッファは破棄されません。これは、グラフィック フレームワークの複雑な依存関係を認識できないアプリ ソフトウェアでデッドロックが発生することを回避するのに役立ちます。

破棄モード - 最終的には、エラーを生成したり待機したりせずに古いバッファを破棄するように BufferQueue を設定できます。たとえば、GL レンダリングをテクスチャ表示にして、できるだけ早く描画する場合は、バッファを破棄する必要があります。

この作業のほとんどを実施するために、SurfaceFlinger は普通の OpenGL ES クライアントとして動作します。したがって、たとえば SurfaceFlinger がアクティブに 1 つまたは 2 つのバッファを 3 つ目に合成する場合、OpenGL ES が使用されます。

Hardware Composer HAL が残り半分の作業を行います。この HAL は、すべての Android グラフィック レンダリングの中心として機能します。