Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

オーバードローの低減

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

このドキュメントではオーバードローの概要について説明し、その診断方法と、排除または緩和するために使用できる戦略を紹介します。

オーバードローの概要

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

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

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

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

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

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

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

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

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

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

詳しくは、GPU レンダリング速度のプロファイルを作成する方法をご覧ください。

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

オーバードローの低減または排除のために推進可能な戦略として、以下のようなものがあります。

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

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

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

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

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

オーバードローの原因を突き止めるには、Layout Inspector ツールで階層を調べます。その際、ユーザーから見えない削除可能な背景を探します。多くのコンテナが共通の背景色を共有するケースでは、別の方法で不要な背景を削除できます(ウィンドウの背景をアプリのメインの背景色に設定し、その上のすべてのコンテナで背景の値を未定義にします)。

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

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

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

透明度を下げる

画面上での透明なピクセルのレンダリング(アルファ レンダリング)はオーバードローに大きく寄与します。標準的なオーバードロー(既存の描画済みのピクセルの上に不透明なピクセルが描画され、その既存のピクセルが完全に見えなくなる)とは異なり、透明なオブジェクトの場合は既存のピクセルを先に描画する必要があります。こうすることで、ブレンディングを適切に均一化できるようになります。透明なアニメーション、フェードアウト、ドロップ シャドウなどの視覚効果はすべて、ある種の透明性が必要なため、オーバードローに大きく寄与することがあります。このような状況では、レンダリングする透明なオブジェクトの数を減らすことによってオーバードローを改善できます。たとえば、TextView に黒色のテキストを描画し、その上に半透明のアルファ値を設定することで、灰色のテキストにすることができます。しかし、単にテキストを灰色で描画することで、パフォーマンスを大幅に向上しつつ同じ効果を得ることができます。

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