Android グラフィック表示プロセスの概要

注: この記事の略称の説明

0a53a9984335dfbd97f28974d07ba4a8.png

この記事のコードは Android S に基づいています

I. 概要

この記事では、アプリがフレームを描画してから、フレームが画面に到達し、最終的に人間の目に見えるまでのプロセスを簡単に分析し、systrace でのパフォーマンスに関連するさまざまなプロセスに対応させます。 Androidシステムでの画面表示処理の理解。

1e7d9b2e14ec12d6a3c43a0e49884182.png

上図はAndroidグラフィックス表示システムのフレームワーク図で、まず上位層アプリがViewRootのscheduleTraversals関数で描画タスクを起動し、HWUIでOpenGLインターフェースを呼び出して描画データをGPUに転送して処理する; SF は、すべてのアプリケーションの更新された描画データを受け取り、 - 順序、透明度、サイズ、位置、およびその他のパラメータが、最終的な合成イメージでの各アプリケーション レイヤの位置を計算します; SF は、レイヤ処理後にすべてのアプリケーション レイヤを HWC に提供します。 HWC は、これらのレイヤーの合成戦略の位置を決定し、画面表示ドライバーを呼び出して合成を行います。最後に、画面表示ドライバーは、合成された最終イメージをハードウェア画面に送信して表示します。

Android システムはバッファ バッファを介してグラフィックス情報を保存します. このバッファのメモリ空間は SF によってグラフィックス メモリ アロケータ Gralloc に適用されます.Gralloc は ION ドライバを介してカーネルから共有メモリを開きます. 全体のグラフィックス表示処理では、バッファ バッファが App、SF、HWC の間を行き来しますが、この記事ではバッファのデータ フローを通して Android の画面表示処理について詳しく説明します。

2.SFへの応用

アプリケーション インターフェイスが変更されると、つまりビュー データが変更されると、ViewRootImpl の requestLayout 呼び出しが発生し、その後、scheduleTraversals メソッドが呼び出されます。scheduleTraversals メソッドは、最初に同期バリアをメッセージ キューに送信し、次に Choreographer コールバックを実行して、リスナーの CALLBACK_TRAVERSAL タイプを登録します。Choreographer は、次の Vsync 信号を検出すると、mTraversalRunnable の run メソッドを実行します。このメソッドは、doTraversal メソッドを呼び出してメッセージ キュー内の同期バリアを削除し、performTraversals メソッドを通じてレイアウト描画プロセスをトリガーします。

dbe988c6080d5fab9c62798e1b800c79.png

Choreographer と Vsync は、Android 4.1 の butter プロジェクトで導入された 2 つの重要な要素です。最初の Vsync 信号は、システムのフレーム レートに応じて固定周波数 (60/90/120fps) でハードウェア画面によってシステムに送信されるタイム パルス信号です。 . Choreographer SurfaceFlinger と SurfaceFlinger の両方が、描画と合成のためにこの信号をリッスンします。その後、インターフェイスの流暢なエクスペリエンスをさらに改善するために、Vsync 仮想化が Android 4.4 に導入されました. Vsync は DispSyncThread を介して Vsync-app と Vsync-sf に仮想化されます. Vsync-app と Vsync-sf の間には固定の時間オフセットがあります.それぞれ App と SurfaceFlinger の動作リズムを制御し、次々と描画タスクの流れのリズムを維持します。

When Choreographer is listen to the Vsync signal, it will call back the doFrame method. このメソッドは主に、現在のフレーム実行のタイムスタンプの確認と現在のフレーム データのレンダリングという 2 つのことを完了します。データの描画時には、Input、Animation、Drawing(TRAVERSAL)、Commit の 4 種類のコールバック関数が順次実行され、TRAVERSAL 型のコールバック メソッドの実行時に上記のコールバック メソッドが呼び出されます。レイアウトの描画プロセス。

89014c0e8a47cae4c6d207d64a87eb08.png

下図の systrace は、アプリから SurfaceFlinger への UI データの処理フローを示しています。systrace から、アプリケーション側に UI スレッドとレンダリング スレッドの 2 つのスレッドがあり、アプリケーションが更新したい UI データを処理するために使用されることがわかります。アプリケーションは Choreographer と Vsync 信号を介してリズミカルに描画し、描画するすべてのデータを描画します. 情報は描画命令の形式で DisplayList に記録され、レンダー スレッドに同期されます.レンダリング用の GPU への UI スレッド。同期作業が完了すると、UI スレッドは次の Vsync-app 信号の到着を待ち続け、次のフレームを描画できます。

Render Thread needs to apply for a buffer buffer to store GPU rendering data before do GPU render. This buffer is applied to BufferQueue by the application through the dequeueBuffer method of the Surface interface. バッファを取得した後、アプリケーションは OpenGL インターフェイスを呼び出して描画コマンド Render を GPU に渡し、レンダリング データを含むバッファーを SF に送信して、queueBuffer 関数を介してレイヤー処理を行います。

0c3c899099d922a3853a25bbfd8b6fad.png

Android S より前は、バッファの状態は BufferQueue によって管理され、bufferQueue は SF で作成され、アプリケーション側のデキューおよびキュー Buffer 操作はバインダーを介して SF とやり取りしていたことに注意してください。しかし、Android S では、BufferQueue の作成は SF から削除され、BLASTBufferQueue になり、BufferQueue の作成が完了します.デキュー、キュー、取得、および Buffer の解放の操作はすべてアプリによって実行されます。アプリがフレームの描画を終了すると、BLASTBufferQueue インターフェイスを介して onFrameAvailable コールバックを実行し、トランザクションを介してバッファを SF に送信します。

3.SFからHWCへ

SF が Vsync-sf 信号をリッスンすると、onMessageReceived 関数を呼び出して UI データを処理します。

4c0de3e573ca5107287974ba248df1a8.png

onMessageReceived メソッドは、主に 2 つのメッセージを処理するために使用されます。

INVALIDATE メッセージ -- onMessageInvalidate は、最初に handleMessageTransaction メソッドを呼び出して、レイヤー/ディスプレイのプロパティと数量が変更されたかどうかを確認します。次に、handleMessageInvalidate メソッドを呼び出して、各レイヤーに新しく送信されたバッファーがあるかどうかを確認し、そうであれば、latchBuffer メソッドを呼び出します。 handlePageFlip でバッファを BufferQueue に保存する acquireBuffer を介してバッファを取り除き、最後に、HWC に再描画要求があるかどうかを確認します。上記の 3 つの状況のいずれかが発生する限り、refreshNeeded は true に設定され、画像合成のために onMessageRefresh メソッドが呼び出されます。

4ad67216a176ac0427deac9136efc056.png

REFRESH メッセージ — onMessageRefresh メソッドは、バッファ更新を使用してすべてのレイヤーを合成します. 合成作業のほとんどは、現在のメソッドで行われます. ここで、SurfaceFlinger は HWC と対話して、画面の合成を完了します. 基本的なプロセスは次のとおりです。

  1. SF は、レイヤーの完全なリストを HWC に提供し、chooseCompositionStrategy メソッドを通じて合成戦略をクエリします。

  2. HWC は、ハードウェアのパフォーマンスに応じて、ハードウェア レイヤー コンポジターまたは GPU 合成を使用するかどうかを決定し、各レイヤーをオーバーレイまたは GLES コンポジションとしてマークして応答します。

  3. ハードウェア レイヤー コンポジター合成を必要とするレイヤーは、HWC によって直接処理されます。GPU 合成を必要とするレイヤーは、最初に SF によって合成される必要があります。次に、残りの合成と表示を完了するために、他のレイヤーと一緒に HWC に送信されます。

画像合成が終了した後、SF は postComposition を呼び出して、releaseBuffer を介して前のフレームを合成するときに SF によって取得されたすべてのバッファーを解放するなど、いくつかの合成後の処理を実行します。

4e2fd52dcfbc2d3747fb09b23a59528d.png

下図の systrace は、SF から HWC への UI データの処理フローを示しています。SF は Vsync-sf 信号をリッスンすると、INVALIDATE メッセージと REFRESH メッセージのコールバック関数を順次実行し、onMessageRefresh メソッドを実行すると、SF と HWC が協力して合成戦略を選択し、HWC が最終的な画面合成を完了します。画像の合成が完了すると、SF はトランザクションを介してアプリケーションに通知し、前のフレームの描画に使用されたバッファーを解放します。

59a4dce3dde60c35514f6816cfb9af36.png

4. 画面への HWC

systrace で表示されるのはソフトウェア上の一部の操作であり、ハードウェアの処理フローは表示されません。ただし、HWCから画面までのUIデータのこの段階では、ソフトウェア上で実行されるのはごくわずかな時間であり、ほとんどの時間はハードウェアによるデータ処理です​​。まず、この段階でのソフトウェアの主な作業を見てみましょう. HWC は、DRM を介して画面に画像を出力します. DRM は、グラフィックス カードとのやり取りを担当する Linux カーネルのサブシステムです. したがって、HWC はまず、 drmModeAtomicCommit インターフェイスを介したカーネルへのレイヤー データ、drmModeAtomicCommit は ioctl を介してカーネルを呼び出し、次に disp スレッドに通知します。

a56a8331df449f014da13cc9363aa2e5.png

complete_commit メソッドを実行するとき、crtc_commit スレッドはほとんど常に D 状態にあり、この時点で DRM 内のハードウェアが構成作業を行っていることを示します。一連の合成処理の後、最終的な画像が画面に送信され、DSI インターフェイスを介して表示されます。これまでのところ、UI データはアプリケーション側からハードウェア画面への旅を完了しました。

V. まとめ

デキューに適用されてから、HWC が画面合成を完了した後に SF によって最終的に解放されるまでのバッファーのライフサイクル全体は、次のプロセスを経ています。

  1. Vsync-app 信号が到着すると、Choreographer は APP 側で Input、Animation、Traversal のコールバックを順に実行し、dequeueBuffer を介して使用可能なバッファーを取得して描画を開始し、描画データを含むバッファーを queueBuffer を介して SF に送信します。 .

  2. Vsync-sf 信号が到着すると、SF はまず acquireBuffer を介してすべてのレイヤーの更新されたバッファーを取得し、Z オーダー、透明度、サイズ、位置などのパラメーターに従ってこれらのレイヤーに対してレイヤー処理を実行し、すべてのレイヤーをに送信します。合成用の HWC。

  3. HWC は複数のレイヤーを合成し、合成が完了した後、libdrm が提供するインターフェースを介して画面に画像を表示するように DRM モジュールに通知します。

  4. 最終的な画像が画面に送信された後、HWC は使用されたバッファーを SF に返し、SF は次の Vsync-sf 信号が到着した後に返されたバッファーを解放します。

ディスプレイ システムにおける UI データのデータ フローの方向に導かれて、このホワイト ペーパーでは、UI データを処理する基本的な手順を、アプリ、SF、HWC、およびハードウェア画面で順番に分析します。Android の表示システムは非常に複雑で、多くのモジュールが関与しており、常に更新と最適化が行われていますが、UI データ処理の基本的な流れは変わりません. この記事は、読者が表示システムを巨視的に理解できるようにすることを目的としています.処理の詳細の中には、読者がソース コードを読んでゆっくりと理解する必要があるものもあります。

参考文献:

1. Android ソース コード: https://cs.android.com/android/platform/superproject

2. Android グラフィックス システムの概要: https://www.jianshu.com/p/180e1b6d0dcd

3. Android Systrace の基礎知識: https://www.androidperformance.com/2019/05/28/Android-Systrace-About/

65f95cac3a2281d774f3565cb3327216.gif

長押しでカーネル職人のWeChatをフォロー

Linux Kernel Black テクノロジー | 技術記事 | 注目のチュートリアル

おすすめ

転載: blog.csdn.net/feelabclihu/article/details/128979354