2025 年 3 月 27 日より、AOSP のビルドとコントリビューションには aosp-main
ではなく android-latest-release
を使用することをおすすめします。詳細については、AOSP の変更をご覧ください。
レイヤとディスプレイ
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
レイヤとディスプレイは、合成処理と、ディスプレイ ハードウェアとのインタラクションを表す 2 つのプリミティブです。
レイヤ
レイヤは合成の最も重要なユニットであり、サーフェスと SurfaceControl
のインスタンスを組み合わせたものです。各レイヤには、他のレイヤとの連携を定義する一連のプロパティがあります。以下の表でレイヤのプロパティについて説明します。
プロパティ |
説明 |
位置 |
ディスプレイ上でレイヤが表示される場所を定義します。レイヤの角の位置や、他のレイヤに対する Z オーダー(他のレイヤの前に配置されるか後に配置されるか)などの情報が含まれます。 |
コンテンツ |
位置プロパティで定義された境界内にレイヤ上のコンテンツをどのように表示するかを定義します。切り抜き(コンテンツの一部を展開してレイヤの境界を埋める)や変形(回転または反転したコンテンツを表示する)などの情報が含まれます。 |
合成 |
レイヤを他のレイヤと合成する方法を定義します。ブレンドモードや、アルファ合成のレイヤ全体のアルファ値などの情報が含まれます。 |
最適化 |
レイヤを正しく合成するうえで厳密に必要な情報ではないものの、Hardware Composer(HWC)デバイスによる合成方法を最適化するために使用できる情報を提供します。レイヤの表示領域や、前のフレームから更新された部分などの情報が含まれます。 |
ディスプレイ
ディスプレイは、合成のもう 1 つの重要なユニットです。システムで複数のディスプレイを保持でき、通常のシステム オペレーション中にディスプレイを追加または削除することができます。ディスプレイは、HWC のリクエストまたはフレームワークのリクエストに応じて追加または削除されます。HWC デバイスは、外部ディスプレイをデバイスに接続したり接続を解除したりする(ホットプラグ)ときに、ディスプレイの追加または削除をリクエストします。クライアントは、コンテンツが物理ディスプレイではなくオフスクリーン バッファにレンダリングされる仮想ディスプレイをリクエストします。
仮想ディスプレイ
SurfaceFlinger は、内部ディスプレイ(スマートフォンまたはタブレットに組み込まれている)、外部ディスプレイ(HDMI で接続されたテレビなど)、1 つ以上の仮想ディスプレイ(合成された出力をシステム内で使用可能にする)に対応しています。仮想ディスプレイを使用して、画面を録画したり、ネットワーク経由で画面を送信したりできます。仮想ディスプレイ用に生成されたフレームは、BufferQueue に書き込まれます。
仮想ディスプレイでは、メイン ディスプレイと同じレイヤセットを共有する(レイヤスタック)ことも、独自のレイヤセットを使用することもできます。仮想ディスプレイには VSYNC がないため、内部ディスプレイ用の VSYNC によってすべてのディスプレイの合成がトリガーされます。
仮想ディスプレイ対応の HWC 実装では、OpenGL ES(GLES)、HWC、または GLES と HWC の両方で仮想ディスプレイを合成できます。非対応の実装では、仮想ディスプレイは常に GLES を使用して合成されます。
ケーススタディ: screenrecord
screenrecord
コマンドを使用すると、画面に表示されたすべての内容をディスク上の .mp4
ファイルとして録画できます。この場合、システムは SurfaceFlinger から合成フレームを受け取って動画エンコーダに書き込み、エンコードされた動画データをファイルに書き込みます。動画コーデックは別のプロセス(mediaserver
)で管理されるため、大きなグラフィック バッファはシステム中を移動する必要があります。さらに困難なのは、60 fps の動画をフル解像度で録画することです。この作業を効率的に行うための鍵は、BufferQueue です。
MediaCodec
クラスを使用すると、アプリがバッファまたはサーフェスで生のバイトとしてデータを提供できます。screenrecord
によって動画エンコーダへのアクセスがリクエストされると、mediaserver
プロセスは BufferQueue を作成して自身をコンシューマ側に接続し、プロデューサー側をサーフェスとして screenrecord
に渡します。
次に screenrecord
ユーティリティは、メイン ディスプレイをミラーリングする(同じレイヤをすべて保持する)仮想ディスプレイの作成を SurfaceFlinger に要求し、出力を mediaserver
プロセスから渡されたサーフェスに送信するように指示します。この場合、SurfaceFlinger はバッファのコンシューマではなくプロデューサーです。
設定の完了後は、エンコードされたデータが表示されたときに screenrecord
がトリガーされます。アプリが描画すると、バッファが SurfaceFlinger に移動して 1 つのバッファに合成され、mediaserver
プロセスの動画エンコーダに直接送信されます。screenrecord
プロセスではフルフレームは表示されません。mediaserver
プロセスには、内部でバッファを移動し、さらにハンドルによってデータを渡してオーバーヘッドを最小限に抑える独自の方法が備わっています。
ケーススタディ: セカンダリ ディスプレイのシミュレート
WindowManager は、SurfaceFlinger が BufferQueue コンシューマとして機能する可視レイヤの作成を SurfaceFlinger に要求できます。また、SurfaceFlinger が BufferQueue プロデューサーとして機能する仮想ディスプレイの作成を SurfaceFlinger に要求することもできます。
仮想ディスプレイを可視レイヤに接続すると、クローズド ループが作成され、合成された画面がウィンドウに表示されます。このウィンドウが合成出力の一部になるため、次の更新でウィンドウ内の合成画像にもウィンドウ コンテンツが表示されます。実際にこの動作を確認するには、[設定] で [開発者向けオプション] を有効化し、[2 次画面シミュレート] を選択してウィンドウを有効にします。セカンダリ ディスプレイの動作を確認するには、screenrecord
を使用してディスプレイを有効にする動作をキャプチャしてから、フレームごとに再生します。
このページのコンテンツやコードサンプルは、コンテンツ ライセンスに記載のライセンスに従います。Java および OpenJDK は Oracle および関連会社の商標または登録商標です。
最終更新日 2025-03-26 UTC。
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["必要な情報がない","missingTheInformationINeed","thumb-down"],["複雑すぎる / 手順が多すぎる","tooComplicatedTooManySteps","thumb-down"],["最新ではない","outOfDate","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["サンプル / コードに問題がある","samplesCodeIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-03-26 UTC。"],[],[],null,["# Layers and displays are two primitives that represent composition work\nand interactions with the display hardware.\n\nLayers\n------\n\nA *layer* is the most important unit of composition. A layer is a\ncombination of a [surface](/docs/core/graphics/arch-sh) and an instance of\n[`SurfaceControl`](https://developer.android.com/reference/android/view/SurfaceControl).\nEach layer has a set of properties that define how it interacts with other layers. Layer\nproperties are described in the following table:\n\n| Property | Description |\n|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Positional | Defines where the layer appears on its display. Includes information such as the positions of a layer's edges and its *Z order* relative to other layers (whether it should be in front of or behind other layers). |\n| Content | Defines how content displayed on the layer should be presented within the bounds defined by the positional properties. Includes information such as crop (to expand a portion of the content to fill the bounds of the layer) and transform (to show rotated or flipped content). |\n| Composition | Defines how the layer should be composited with other layers. Includes information such as blending mode and a layer-wide alpha value for [alpha compositing](https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending). |\n| Optimization | Provides information not strictly necessary to correctly composite the layer, but that can be used by the Hardware Composer (HWC) device to optimize how it performs composition. Includes information such as the visible region of the layer and which portion of the layer has been updated since the previous frame. |\n\nDisplays\n--------\n\nA *display* is another important unit of composition. A system can\nhave multiple displays and\ndisplays can be added or removed during normal system operations. Displays are\nadded or removed at the request of the HWC or at the request of the framework.\nThe HWC device requests displays be added or removed when an external\ndisplay is connected or disconnected from the device, which is called\n*hotplugging* . Clients request *virtual displays*, whose contents\nare rendered into an off-screen buffer instead of to a physical display.\n\n### Virtual displays\n\n[SurfaceFlinger](/docs/core/graphics/arch-sf-hwc#surfaceflinger)\nsupports an internal display (built into the phone or tablet), external displays\n(such as a television connected through HDMI), and one or more virtual displays\nthat make composited output available within the system. Virtual displays can\nbe used to record the screen or send the screen over a network. Frames generated\nfor a virtual display are written to a BufferQueue.\n\nVirtual displays may share the same set of layers as the main display\n(the layer stack) or have their own set. There's no VSync for a virtual display,\nso the VSync for the internal display triggers composition for all\ndisplays.\n\nOn HWC implementations that support them, virtual\ndisplays can be composited with OpenGL ES (GLES), HWC, or both GLES and HWC.\nOn nonsupporting implementations, virtual displays are always composited using\nGLES.\n\nCase study: screenrecord\n------------------------\n\nThe [`screenrecord` command](https://android.googlesource.com/platform/frameworks/av/+/android16-release/cmds/screenrecord/) allows the user to\nrecord everything that appears on the screen as an MP4 file on\ndisk. To implement this, the system receives composited frames from\nSurfaceFlinger, writes them to the video encoder, and then writes the encoded\nvideo data to a file. The video codecs are managed by a separate process\n(`mediaserver`), so large graphics buffers have to move around the\nsystem. To make it more challenging, the goal is to record 60 fps video at\nfull resolution. The key to making this work efficiently is BufferQueue.\n\nThe `MediaCodec` class allows an app to provide data as raw bytes in buffers,\nor through a surface. When `screenrecord` requests access to a video\nencoder, the `mediaserver` process creates a BufferQueue, connects\nitself to the consumer side, then passes the producer side back to\n`screenrecord` as a surface.\n\nThe `screenrecord` utility then asks SurfaceFlinger to create a\nvirtual display that mirrors the main display (that is, it has all of the same\nlayers), and directs it to send output to the surface that came from the\n`mediaserver` process. In this case, SurfaceFlinger is the producer\nof buffers rather than the consumer.\n\nAfter the configuration is complete, `screenrecord` triggers when\nthe encoded data appears. As apps draw, their buffers travel to SurfaceFlinger,\nwhich composites them into a single buffer that's sent directly to the video\nencoder in the `mediaserver` process. The full frames are never\nseen by the `screenrecord` process. Internally, the\n`mediaserver` process has its own way of moving buffers around that\nalso passes data by handle, minimizing overhead.\n\nCase study: simulate secondary displays\n---------------------------------------\n\nThe WindowManager can ask SurfaceFlinger to create a visible layer for which\nSurfaceFlinger acts as the BufferQueue consumer. It's also possible to ask\nSurfaceFlinger to create a virtual display, for which SurfaceFlinger acts as\nthe BufferQueue producer.\n\nIf you connect a virtual display to a visible layer, a closed loop is created\nwhere the composited screen appears in a window. That window is now part of the\ncomposited output, so on the next refresh the composited image inside the window\nshows the window contents as well. To see this in action, enable\n[Developer options](https://developer.android.com/studio/debug/dev-options) in **Settings** , select\n**Simulate secondary displays** , and enable a window. To see\nsecondary displays in action, use `screenrecord` to capture the act\nof enabling the display then play it back frame by frame."]]