オーバードローの低減

このページではオーバードローの概要について説明し、その診断方法とそれを排除または緩和する方法を紹介します。

アプリが単一フレーム内の同じピクセルを複数回描画することをオーバードローと呼びます。通常、オーバードローは不要なため、発生しないようにするのが一番です。画面に表示されるものと関係のないピクセルのレンダリングに GPU の時間が浪費された場合、オーバードローはパフォーマンスの問題につながります。

オーバードローの概要

オーバードローとは、単一フレームのレンダリングにおいてシステムが画面上の 1 つのピクセルを複数回描画することです。たとえば、複数の UI カードが積み重なっている場合、カードの一部はその上にあるカードによって見えなくなります。

しかし、システムはカードの隠れた部分も描画する必要があります。これは、カードがペインタ アルゴリズムに従って、つまり下から上にレンダリングされるためです。このレンダリングの順序により、シャドウなどの半透明のオブジェクトに適切なアルファ ブレンディングを適用できます。

オーバードローの問題を検出する

プラットフォームには、オーバードローがアプリのパフォーマンスに影響を及ぼしているかどうかを判断するのに役立つ以下のツールが用意されています。

GPU オーバードローのデバッグツール

GPU オーバードローのデバッグツールは色分けを利用して、アプリが画面上の各ピクセルを描画した回数を示します。この回数が多いほど、オーバードローがアプリのパフォーマンスに影響している可能性が高くなります。

詳しくは、GPU オーバードローの視覚化をご覧ください。

GPU レンダリングのプロファイル作成ツール

GPU レンダリングのプロファイル作成ツールは、レンダリング パイプラインの各ステージで単一フレームの表示にかかった時間をスクロール ヒストグラムとして表示します。オレンジ色で示される各バーの「Process」は、システムがバッファを交換しているときに表示されます。この指標から、オーバードローに関する重要な手がかりが得られます。

性能が低い GPU では、利用可能なフィルレート、つまり GPU がフレーム バッファを充填する速度が低くなる可能性があります。フレームの描画に要求されるピクセル数の増加に伴い、GPU による新しいコマンドの処理時間が長くなり、その処理が完了するまでシステムの残りの部分に待機を求めるという事態が発生する場合があります。できる限り速くピクセルを描画しようとして GPU が過負荷になると、Process が急に増大します。生のピクセル数以外の問題によって Process が急に増大することもあります。たとえば、GPU オーバードローのデバッグツールで重度のオーバードローや Process の急な増大が示された場合、オーバードローに関する問題がある可能性があります。

詳しくは、GPU レンダリング速度のプロファイリングをご覧ください。

オーバードローを修正する

次のことを実行すると、オーバードローを低減または排除できます。

  • レイアウト内の不要な背景を削除する
  • ビュー階層をフラット化する
  • 透明度を下げる

このセクションでは、これらの各アプローチについて説明します。

レイアウト内の不要な背景を削除する

デフォルトでは、レイアウトに背景はありません。つまり、レイアウトが単独で何かを直接レンダリングすることはありません。ただし、レイアウトに背景が存在すると、オーバードローにつながる可能性があります。

不要な背景を削除することで、レンダリングのパフォーマンスを改善できます。不要な背景はアプリがそのビューの上に描画する他のものによって完全に覆われるため、見えることはありません。たとえば、システムが親の背景の上に子ビューを描画すると、親の背景は完全に覆われます。

オーバードローの原因を突き止めるには、Layout Inspector ツールで階層を調べます。ユーザーには表示されない背景を見つけて、それを削除できます。共通の背景色を共有しているコンテナが多数ある場合は、不要な背景を削除できます。ウィンドウの背景をアプリのメインの背景色に設定し、その上のすべてのコンテナで背景の値を未定義にします。

ビュー階層をフラット化する

最新のレイアウトを使用すると、ビューをスタックして階層化し、美しいデザインを作成できます。ただし、そうすることでオーバードローが発生し、パフォーマンスが低下することがあります。スタックされた各ビュー オブジェクトが不透明なシナリオでは、画面に表示されるピクセルと表示されないピクセルの両方を描画する必要があるため、特にパフォーマンスが低下します。

このような問題が発生した場合は、ビュー階層を最適化して重複する UI オブジェクトの数を減らすことにより、パフォーマンスを改善できることがあります。これを行う方法について詳しくは、パフォーマンスとビュー階層をご覧ください。

透明度を下げる

画面上での透明なピクセルのレンダリング(アルファ レンダリング)はオーバードローに大きく寄与します。標準的なオーバードロー(既存の描画済みのピクセルの上に不透明なピクセルが描画され、その既存のピクセルが完全に見えなくなる)とは異なり、透明なオブジェクトの場合は既存のピクセルを先に描画する必要があります。こうすることで、ブレンディングを適切に均一化できるようになります。

透明なアニメーション、フェードアウト、ドロップ シャドウなどの視覚効果ではある種の透明性が必要なため、オーバードローに大きく寄与することがあります。このような状況では、レンダリングする透明なオブジェクトの数を減らすことによってオーバードローを改善できます。たとえば、TextView に黒色のテキストを描画し、その上に半透明のアルファ値を設定することで、灰色のテキストにできます。ただし、テキストをグレーで描画することにより、同じ効果でパフォーマンスが向上します。

透明性によって描画パイプライン全体に課されるパフォーマンス コストについて詳しくは、透明性の隠れたコストの動画をご覧ください。