Android 13 以降では、クライアント合成中に使用される新しいフレームバッファがディスプレイ解像度が変更されるたびに割り当てられます。この割り当ては、解像度変更後、次の無効化サイクル時に SurfaceFlinger が行います。
解像度の切り替え時のフレームバッファ管理
解像度の変更は、次の 2 つのシナリオのいずれかが原因で発生します。
Hardware Composer(HWC)によって開始されるホットプラグ イベント。デフォルトの解像度が異なる外部ディスプレイから別の外部ディスプレイに切り替えられるときに発生します。
ホットプラグ イベント中は、古いディスプレイ データの割り当てが解除されると、古いフレームバッファへのハンドルが解放されます。
SurfaceFlinger によって開始された表示モードの切り替え。ユーザーがユーザー設定で解像度を変更したり、アプリで
preferredDisplayModeId
によって解像度が変更されたりすると発生します。表示モードの切り替え中は、SurfaceFlinger によって
setActiveConfig
またはsetActiveConfigWithConstraints
を呼び出す前に、既存のクライアント フレームバッファに対するハンドルが解放されます。
メモリの断片化などの壊滅的な問題を回避するには、以下のケースで示すように、古いフレームバッファと新しいフレームバッファのメモリが予約されていないデバイスで、HWC が古いフレームバッファを使用するのを中止し、これらのフレームバッファに対するハンドルを解放することが極めて重要になります。
ホットプラグ イベントの場合は、
onHotplug
を呼び出す直前モード切り替えの場合は、
setActiveConfig
またはsetActiveConfigWithConstraints
を呼び出した直後
ハンドルを解放すると、SurfaceFlinger が次の無効化サイクル中に実行する新しいフレームバッファを割り当てる前に、フレームバッファ メモリの割り当てを完全に解除できます。
フレームバッファ管理の推奨事項
HWC が古いフレームバッファに対するハンドルを時間内に解放しない場合、古いフレームバッファの割り当ての解除前に新しいフレームバッファの割り当てが行われます。これにより、断片化やその他の問題が原因で新しい割り当てが失敗すると、致命的な問題が発生する可能性があります。さらに、HWC がこれらのハンドルをまったく解放しない場合、メモリリークが発生する可能性があります。
致命的な割り当て障害を回避するための推奨事項を示します。
新しいクライアント フレームバッファが提供されるまで HWC が古いクライアント フレームバッファを引き続き使用する必要がある場合は、古いフレームバッファと新しいフレームバッファの両方に十分なメモリを予約することが重要です。場合によっては、フレームバッファのメモリ容量でフレームバッファにデフラグ アルゴリズムを実行する必要があります。
残りのグラフィック バッファ メモリとは別のフレームバッファに、専用のメモリプールを割り当てます。これは、フレームバッファの割り当て解除と再割り当ての間にサードパーティ プロセスがグラフィック メモリの割り当てを試行することがあるため、重要です。同じグラフィック メモリプールがフレームバッファによって使用され、グラフィック メモリがいっぱいの場合、フレームバッファによって以前に割り当てられたグラフィック メモリをサードパーティ プロセスが占有することで、フレームバッファの再割り当て用のメモリが不足すしたり、メモリ容量が断片化されたりする可能性があります。
フレームバッファ管理のテスト
下に示すように、OEM はデバイスの解像度切り替えで適切なクライアント フレームバッファのメモリ管理をテストすることをおすすめします。
ホットプラグ イベントの場合は、異なる解像度の 2 つの異なるディスプレイを電源から外し、再び接続します。
モード切り替えの場合は、
ModeSwitchingTestActivity
CTS 検証ツールテストを使用して、フレームバッファのメモリ動作をテストするためのモード切り替えを開始します。このテストでは、プログラムで検出するのが難しい問題を視覚的に識別できます。