グラフィック メモリの消費を抑える

グラフィック スタックでは、レイヤごとのバッファ キャッシュが Composer HAL と SurfaceFlinger の間に配置され、IPC 経由でのファイル記述子の送信に関連するオーバーヘッドが削減されます。Android 14 より前では、GraphicBufferProducer が SurfaceFlinger GraphicBufferConsumer から切断されても、このバッファ キャッシュはパージされませんでした(MediaCodec が SurfaceView から切断されたときなど)。Android 14 以降では、このバッファ キャッシュを強制的にパージして、グラフィック メモリの消費を抑えられます。

次の 2 つのオプションのいずれかを選択します。

  • Android 14 以降を搭載してリリースするデバイスの場合、新しい Composer HAL API バージョン 3.2 を実装する必要があります。このオプションはデフォルトで有効であり、メモリを最も節約できます。Android 14 以降にアップグレードするデバイスも、このオプションを利用してメモリを最大限に活かせます。
  • Android 14 にアップグレードするデバイスで、Composer HAL 3.2 API を実装したくない場合は、下位互換オプションを有効にできます。このオプションでは前のオプションとほぼ同じだけメモリを節約できます。

次の 2 つのセクションで各オプションの実装方法を説明します。

Composer HAL 3.2 API を実装する

バッファメモリを最大限に活かすには、次の手順を実行します。

  1. Composer HAL 実装をバージョン 3.2 にアップデートします。
  2. リスト内のスロット番号で指定されたバッファ キャッシュ エントリを削除することで LayerCommand::bufferSlotsToClear を処理します。

LayerCommand:bufferSlotsToClear を含め、グラフィック バッファメモリに関連する Composer HAL 3.2 API は LayerCommand.aidl- にあります。

下位互換オプションを有効にする

下位互換メモリ削減オプションでは、キャッシュ スロットの実際のバッファを 1x1 プレースホルダ バッファに置き換えることで、現在アクティブなバッファ スロットを除くすべてのパージされたスロットのメモリを節約できます。surface_flinger.clear_slots_with_set_layer_buffer sysprop を true に設定して下位互換オプションを有効にすることで、一定のメモリ節約効果が得られます。この sysprop は property_contexts ファイルにあります。

この sysprop を設定するには、Composer HAL の実装が、同じレイヤの複数の setLayerBuffer コマンドを一度のサイクルで正しく処理する必要があります。

下位互換オプションを有効にすると、次のような影響があります。

  • AIDL HAL の場合: SurfaceFlinger は、それぞれ 1 つの BufferCommand を持つ複数の LayerCommand インスタンスを単一のレイヤに送信します。各 BufferCommand には、1x1 プレースホルダ バッファ ハンドルと、パージする必要があるキャッシュ バッファ スロットのスロット番号が含まれます。

  • HIDL HAL の場合: SurfaceFlinger は複数の SELECT_DISPLAYSELECT_LAYERSET_BUFFER コマンドを送信します。これらのコマンドには、1x1 プレースホルダ バッファ ハンドルと、パージする必要があるキャッシュ バッファ スロットのスロット番号が含まれます。

下位互換オプションにより、Composer HAL が一部のデバイスでクラッシュする可能性があります。Composer HAL を変更することでこの問題を解決できる場合があります。この動作をコントロールするコードについてはこちらをご覧ください。

グラフィック バッファのキャッシュ メモリ消費をテストする

テストでは、HAL 実装でキャッシュ スロットがパージされたかどうかを確認できません。しかし、デバッグツールを使用することでグラフィック バッファの使用状況を監視できます。監視すると、YouTube で複数の異なる動画を連続して停止し再生するシナリオで、メモリ不足によるエラーが減っているのが確認できます。

VTS テストにより、新しい API 呼び出し(HAL バージョン 3.2+)または下位互換実装のための複数の setLayerBuffer コマンドを、HAL 実装が機能的に受け取れることを検証できます。しかし、VTS テストに合格しても、実際のユースケースで不合格になるデバイスがあるため、適切な機能性のテストとして十分ではありません。

新しい VTS テストについては、以下のリンクをご覧ください。