SurfaceFlinger と WindowManager

SurfaceFlinger は、バッファを受け取り、合成して、ディスプレイに送ります。WindowManager は、バッファとウィンドウ メタデータを SurfaceFlinger に提供し、これを使用して SurfaceFlinger がサーフェスを合成してディスプレイに送ります。

SurfaceFlinger

SurfaceFlinger がバッファを受け取る方法には、BufferQueue と SurfaceControl を通じて受け取る方法と、ASurfaceControl を通じて受け取る方法があります。

SurfaceFlinger がバッファを受け取る方法の 1 つは、BufferQueue と SurfaceControl を通す方法です。アプリは、フォアグラウンドになると WindowManager にバッファをリクエストします。次に WindowManager は SurfaceFlinger にレイヤをリクエストします。レイヤとは、BufferQueue を含んだサーフェスと、ディスプレイ フレームのようなレイヤ メタデータを含んだ SurfaceControl の組み合わせです。SurfaceFlinger は、レイヤを作成し、それを WindowManager に送ります。すると、WindowManager はサーフェスをアプリに送りますが、画面上でのアプリの外観を操作するために SurfaceControl を保持します。

Android 10 では、SurfaceFlinger がバッファを受け取るもう 1 つの方法として、ASurfaceControl が追加されています。ASurfaceControl は、サーフェスと SurfaceControl を 1 つのトランザクション パッケージに結合して SurfaceFlinger に送ります。ASurfaceControl は、アプリが ASurfaceTransaction を通じて更新するレイヤに関連付けられます。アプリはコールバックを通じて ASurfaceTransaction に関する情報を取得します。このコールバックは、ラッチ時間、取得時間などの情報を含む ASurfaceTransactionStats を渡します。

次の表は、ASurfaceControl とその関連コンポーネントの詳細です。

コンポーネント 説明
ASurfaceControl SurfaceControl をラップし、ディスプレイ上のレイヤに対応する SurfaceControl をアプリが作成できるようにします。

ANativeWindow の子として、または別の ASurfaceControl の子として作成できます。
ASurfaceTransaction Transaction をラップして、クライアントがジオメトリなどのレイヤの記述プロパティを編集し、更新されたバッファを SurfaceFlinger に送信できるようにします。
ASurfaceTransactionStats ラッチ時間、取得時間、前のリリース フェンスなどの与えられたトランザクションに関する情報を、事前登録されたコールバックを通じてアプリに送信します。

アプリはいつでもバッファを送れますが、SurfaceFlinger はディスプレイのリフレッシュ(デバイスによって異なる)の合間でのみ復帰してバッファを受け取ります。それによってメモリの使用量が最小限に抑えられ、ディスプレイのリフレッシュの途中で発生する画面の乱れがなくなります。

ディスプレイは、リフレッシュの合間に、VSYNC 信号を SurfaceFlinger に送ります。VSYNC 信号は、ディスプレイが乱れを発生させることなくリフレッシュできることを示します。SurfaceFlinger は、VSYNC 信号を受信すると、新しいバッファを見つけるためにレイヤのリストを確認します。SurfaceFlinger が新しいバッファを検出した場合、そのバッファを取得します。検出しなかった場合、以前に取得したバッファを引き続き使用します。SurfaceFlinger は常に何かを表示する必要があるため、1 つのバッファを保持し続けます。レイヤにバッファが送られていない場合、そのレイヤは無視されます。

SurfaceFlinger は、表示されるレイヤのすべてのバッファを収集した後、Hardware Composer(HWC)に合成方法を尋ねます。HWC がレイヤ合成タイプをクライアント合成にマークすると、SurfaceFlinger がそれらのレイヤを合成します。次に SurfaceFlinger は出力バッファを HWC に渡します。

WindowManager

WindowManager は、View オブジェクトのコンテナである Window オブジェクトを制御します。Window オブジェクトの背後には常に Surface オブジェクトがあります。WindowManager は、ライフサイクル、入力イベントやフォーカス イベント、画面の向き、遷移、アニメーション、位置、変換、Z オーダーなどのウィンドウの特性を監視します。WindowManager はすべてのウィンドウ メタデータを SurfaceFlinger に送るため、SurfaceFlinger はそのデータを使用してディスプレイ上にサーフェスを合成できます。

事前回転

多くのハードウェア オーバーレイは回転に対応していません(対応していても負荷の大きい処理です)。これは、SurfaceFlinger に到達する前にバッファを変換すれば解決します。Android は、ANativeWindow でクエリヒント(NATIVE_WINDOW_TRANSFORM_HINT)をサポートしており、SurfaceFlinger によってバッファに適用される可能性が最も高い変換を提示できます。GL ドライバは、このヒントを使用して SurfaceFlinger に到達する前にバッファを事前変換し、バッファが到着したときに正しく変換されているようにします。

たとえば、ヒントが 90 度の回転である場合、行列を生成してバッファに適用して、ページからはみ出さないようにします。電力を節約するには、この事前回転を行ってください。詳しくは、system/core/include/system/window.h で定義されている ANativeWindow インターフェースをご覧ください。