Android フレームワークは、メーカーによって実装されるグラフィック ドライバと連携する、2D および 3D 用のさまざまなグラフィック レンダリング API を提供します。したがって、上位レベルでの API の動作を十分に理解することが重要です。このページでは、ドライバがビルドされるグラフィック Hardware Abstraction Layer(HAL)について説明します。このセクションに進む前に、以下の用語についてよく理解しておいてください。
Canvas
(API 要素)Surface
オブジェクトに対して、実際のビットの合成を処理する描画サーフェス。Canvas
には、ビットマップ、線、円、長方形、テキストなど、標準的なコンピュータ図形描画用のメソッドが用意されており、ビットマップやサーフェスにバインドされます。キャンバスは、2D オブジェクトを画面上に描画するためのシンプルで簡単な方法です。基本クラスは Canvas
です。android.graphics.drawable
のサブクラスにコンパイルされます。ドローアブルや各種リソースの詳細については、アプリリソースの概要をご覧ください。android.opengl
パッケージと javax.microedition.khronos.opengles
パッケージからエクスポーズされます。Surface
(API 要素)Surface
オブジェクトのサイズ変更を行うさまざまなヘルパー メソッドを備えています。Surface
クラスを直接使用するのではなく、SurfaceView
クラスを使用します。SurfaceView
(API 要素)Surface
オブジェクトをラップする View
オブジェクト。サイズや形式を動的に指定するメソッドをエクスポーズします。サーフェス ビューを使用すると、リソース消費の多い処理(ゲームやカメラ プレビューなど)において、UI スレッドから独立して描画を行うことができます。ただし、結果的にメモリ使用量は増えます。サーフェス ビューは、キャンバスと OpenGL ES の両方のグラフィックをサポートしています。SurfaceView
オブジェクトの基本クラスは SurfaceView
です。R.style
にリストされ、Theme_
から始まります。View
(API 要素)View
クラスが、アクティビティ画面やダイアログ画面のほとんどのレイアウト コンポーネント(テキスト ボックス、ウィンドウなど)の基本クラスです。View
オブジェクトは、親オブジェクトからの呼び出しを受け取って(ViewGroup
を参照)自身を描画し、使用するサイズと場所を親オブジェクトに伝えます(親によって適用されない可能性もあります)。詳しくは、View
をご覧ください。ViewGroup
(API 要素)widget
パッケージに含まれますが、ViewGroup
クラスを拡張します。android.widget
パッケージにあります。Window
(API 要素)Window
抽象クラスから派生したオブジェクトで、デザイン、タイトルバーのテキスト、メニューの位置やコンテンツなど、汎用ウィンドウの要素を指定します。ダイアログとアクティビティは Window
クラスの実装を使用して Window
オブジェクトをレンダリングします。アプリで Window
クラスを実装したりウィンドウを使用したりする必要はありません。アプリ デベロッパーが画面に画像を描画するには、Canvas、OpenGL ES、または Vulkan を使用する 3 つの方法があります。
Android グラフィック コンポーネント
デベロッパーがどのレンダリング API を使用しても、すべてサーフェスにレンダリングされます。サーフェスは、SurfaceFlinger でよく使用されるバッファキューのプロデューサー側を表します。Android プラットフォームで作成されるすべてのウィンドウは、サーフェスによってサポートされています。レンダリングされた表示可能なすべてのサーフェスは、SurfaceFlinger によってディスプレイ上に合成されます。
主要コンポーネントの連携の仕組みを次の図に示します。
主要コンポーネントについて以下で説明します。
画像ストリーム プロデューサー
画像ストリーム プロデューサーとは、使用するグラフィック バッファを生成するもののことです。たとえば、OpenGL ES、Canvas 2D、mediaserver 動画デコーダなどがあります。
画像ストリーム コンシューマ
画像ストリームの最も一般的なコンシューマは SurfaceFlinger です。このシステム サービスはウィンドウ マネージャーから提供された情報を使用して、現在表示されているサーフェスをディスプレイに合成します。SurfaceFlinger は、ディスプレイのコンテンツを変更できる唯一のサービスであり、OpenGL と Hardware Composer を使用してサーフェスのグループを作成します。
その他の OpenGL ES アプリでも画像ストリームを使用できます(カメラアプリがカメラ プレビュー画像ストリームを使用するなど)。GL 以外のアプリがコンシューマになる場合もあります(ImageReader クラスなど)。
Hardware Composer
ディスプレイ サブシステム用のハードウェア抽象化です。SurfaceFlinger は特定の合成処理を Hardware Composer に委任して、OpenGL と GPU から作業をオフロードできます。SurfaceFlinger は普通の OpenGL ES クライアントとして動作するため、たとえば SurfaceFlinger がアクティブに 1 つまたは 2 つのバッファを 3 つ目に合成する場合、OpenGL ES が使用されます。この結果、GPU ですべての計算を実行するよりも、合成の消費電力が抑えられます。
残りの処理を行う Hardware Composer HAL は、すべての Android グラフィック レンダリングの中心です。Hardware Composer は、VSYNC などのイベントに対応する必要があります(他のイベントとして、プラグアンドプレイ HDMI をサポートするためのホットプラグがあります)。
Gralloc
グラフィック メモリ アロケータ(Gralloc)は、画像プロデューサーが要求するメモリを割り当てるために必要です。詳細については、Gralloc HAL をご覧ください。
データフロー
Android グラフィック パイプラインを示した次の図をご覧ください。
左側のオブジェクトは、ホーム画面、ステータスバー、システム UI などのグラフィック バッファを作成するレンダラです。SurfaceFlinger はコンポジターで、Hardware Composer はコンポーザーです。
BufferQueue
BufferQueue は、Android グラフィック コンポーネント同士を接続します。これらは、プロデューサーからコンシューマへのバッファのサイクルを一定に保つキューのペアです。プロデューサーがバッファを渡すと、SurfaceFlinger はディスプレイ上にすべてを合成します。
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 グラフィック レンダリングの中心として機能します。