複数のリフレッシュレート

Android 11は、複数のリフレッシュレートを備えたデバイスのサポートを追加します。この機能には、次の3つの主要なコンポーネントがあります。

  • android.hardware.graphics.composer@2.4で導入された新しいHALAPI。
  • さまざまなリフレッシュレートのデバイス構成を解析し、必要なリフレッシュレートを設定するためのプラットフォームコード
  • アプリが希望のフレームレートを設定できるようにする新しいSDKおよびNDKAPI

実装

リフレッシュレート切り替えの専用サポートがandroid.hardware.graphics.composer@2.4 HALに追加されました。以前のバージョンのcomposerHALではリフレッシュレートの切り替えのサポートが制限されているため、このバージョンを使用することを強くお勧めします。

構成グループ

getDisplayAttribute_2_4を使用してクエリ可能な新しい属性CONFIG_GROUPIComposerClient::Attributeに追加されました。この属性により、ベンダーは表示構成をグループ化できます。同じグループ内の構成では、ほとんどの場合、それらをシームレスに切り替えることができます。構成グループは、構成の他の属性ではなくリフレッシュレートを切り替えるために、どの構成を切り替えることができるかを区別するためにプラットフォームによって使用されます。

4つのディスプレイ構成をサポートするデバイスで構成グループを使用する利点を示す次の例を検討してください。

  • 1080p @ 60Hz
  • 1080p @ 90Hz
  • 1080i @ 72Hz
  • 1080i @ 48Hz

デバイスは48Hz、60Hz、72Hz、および90Hzのリフレッシュレートをサポートしていますが、ディスプレイは異なるモードで動作し、60Hzから72Hzに切り替えると、ディスプレイ構成が1080pから1080iに変更されます。これは、望ましい動作ではない可能性があります。これは、構成グループを使用することで解決されます。 60Hzと90Hzを1つの構成グループにグループ化し、48Hzと72Hzを別の構成グループにグループ化する。プラットフォームは、60Hzと90Hzの間、および48Hzと72Hzの間で切り替えることができるが、60Hzから72Hzの間では切り替えることができないことを認識しています。これにより、単にリフレッシュレートを変更するのではなく、構成が変更されるためです。

ComposerAPIの更新

getDisplayVsyncPeriod
リフレッシュレートを変更する際の制御と予測性を向上させるために、 getDisplayVsyncPeriodが追加されました。 getDisplayVsyncPeriodは、ディスプレイが動作している現在のリフレッシュレート(vsync期間の観点から)を返します。これは、リフレッシュレートと現在のリフレッシュレートの間を移行するときに、プラットフォームが次のフレームをいつ開始するかを決定するために必要な場合に特に便利です。
setActiveConfigWithConstraints
setActiveConfigWithConstraintsメソッドは、既存のsetActiveConfigメソッドの新しい拡張機能であり、構成の変更に関する詳細情報を提供します。制約はvsyncPeriodChangeConstraintsパラメーターの一部として指定され、次のパラメーターが含まれています。
    desiredTimeNanos
    CLOCK_MONOTONIC期間が変更される可能性があるCLOCK_MONOTONICの時間(つまり、vsync期間はこの時間より前に変更されてはなりません)。これは、プラットフォームがリフレッシュレートの変更を事前に計画したいが、提示するためにキューにすでにいくつかのバッファーがある場合に役立ちます。プラットフォームは、これらのバッファを考慮し、リフレッシュレートの移行が可能な限りスムーズになるように、この時間を適宜設定します。
    シームレス必須
    trueの場合、vsync期間の変更は、目立った視覚的なアーティファクトなしにシームレスに行われる必要があります。このフラグは、コンテンツの変更の結果としてリフレッシュレートの変更が必要な場合(たとえば、デバイスがアイドル状態でアニメーションが開始される場合)にプラットフォームによって使用されます。これにより、ベンダーは、目立った視覚的なアーティファクトが発生する可能性がある場合に、特定の構成変更を許可しない機会が与えられます。構成をseamlessRequiredに変更できず、seamlessRequiredがtrueに設定されている場合、実装は戻りコードとしてSEAMLESS_NOT_POSSIBLEを返し、同じ構成変更をシームレスに実行できるときに新しいonSeamlessPossibleコールバックを呼び出すことが期待されます。

成功すると、実装はVsyncPeriodChangeTimelineを返します。これは、リフレッシュレートの変更がいつ発生するかをプラットフォームに通知します。 newVsyncAppliedTimeNanosパラメータは、新しいvsync期間に新しい表示が更新を開始するCLOCK_MONOTONICの時刻に設定する必要があります。これは、 desiredTimeNanosとともに、プラットフォームがリフレッシュレートの切り替えを事前に計画し、新しいリフレッシュレートのアプリを事前にチェックし始めることを可能にします。これにより、リフレッシュレートのシームレスな移行が可能になります。

一部の実装では、リフレッシュレートを送信する前に、リフレッシュフレームを送信する必要があります。そのために、HALには、リフレッシュフレームが必要であることを示すrefreshRequiredパラメーターと、リフレッシュフレームを送信する必要がある最初のrefreshTimeNanosを示すrefreshTimeNanosがあります。

onVsyncPeriodTimingChanged[コールバック]
HALが呼び出すことができる新しいコールバックで、タイムラインの一部のパラメーターが変更され、プラットフォームがタイムラインを調整する必要があることをプラットフォームに示します。このコールバックは、HALでの処理時間が長いか、更新フレームが遅いために、何らかの理由で古いタイムラインが失われた場合に呼び出されることが期待されます。

プラットフォームはどのようにしてリフレッシュレートを変更することを決定しますか?

リフレッシュレートの選択は、次の2つのシステムサービスで行われます。

DisplayManager
DisplayManagerは、リフレッシュレートに関する高レベルのポリシーを設定します。これは、コンポーザーのHAL構成と同じデフォルトの表示構成を設定します。さらに、リフレッシュレートとして選択するSurfaceFlingerの最小値と最大値の範囲を設定します。
SurfaceFlinger
デフォルトの構成と同じ構成グループにあり、最小/最大範囲内のリフレッシュレートを持つ構成を設定することにより、リフレッシュレートを決定します。

表示マネージャは、次の手順を実行してポリシーを決定します。

  • SurfaceFlingerからアクティブな構成を照会して、デフォルトの構成IDを検索します
  • システム条件を反復処理して最小値と最大値の範囲を制限する
    • デフォルトのリフレッシュレート設定:デフォルトのリフレッシュレート値は、 R.integer.config_defaultRefreshRateオーバーレイで設定されます。この値は、アニメーションとタッチ操作の標準デバイスリフレッシュレートを決定するために使用されます。
    • ピークリフレッシュレートの設定:ピークリフレッシュレートの値は、 Settings.System.PEAK_REFRESH_RATEから読み取られます。この値は、現在のデバイス設定を反映するために実行時に変更されます(メニューオプションなどから)。デフォルト値は、 R.integer.config_defaultPeakRefreshRateオーバーレイで設定されます。
    • 最小リフレッシュレート設定:最小リフレッシュレート値は、 Settings.System.MIN_REFRESH_RATEから読み取られます。この値は、現在のデバイス設定を反映するように実行時に変更できます(メニューオプションなどから)。デフォルト値は0であるため、デフォルトの最小値はありません。
    • アプリケーションが要求したModeId :アプリはWindowManager.LayoutParams.preferredDisplayModeIdを設定して、ディスプレイが動作する優先構成を反映できます。ほとんどの場合、 DisplayManagerはそれに応じてデフォルトの設定IDを設定し、設定のリフレッシュレートと一致するように最小および最大のリフレッシュレートを設定します。
    • バッテリーセーバー:デバイスが低電力モードの場合、リフレッシュレートは60Hz以下に制限されます。これは、 Settings.Global.LOW_POWER_MODE.

DisplayManagerがポリシーを設定すると、 SurfaceFlingerはアクティブなレイヤー(フレームの更新をキューに入れるレイヤー)に基づいてリフレッシュレートを設定します。レイヤーの所有者がフレームレートを設定する場合、SurfaceFlingerはリフレッシュレートをそのレートの乗数であるものに設定しようとします。たとえば、2つのアクティブなレイヤーがフレームレートを24と60に設定した場合、SurfaceFlingerは120Hzを選択します(使用可能な場合)。そのようなリフレッシュレートがSurfaceFlingerで利用できない場合、フレームレートのエラーが最小のリフレッシュレートを選択しようとします。詳細については、developer.android.comの開発者向けドキュメントを参照してください。

SurfaceFlingerは、リフレッシュレートの決定方法を制御するために、次のフラグを保持しています。

  • ro.surface_flinger.use_content_detection_for_refresh_rate:設定されている場合、フレームレートが設定されていなくても、リフレッシュレートはアクティブなレイヤーに基づいて決定されます。 SurfaceFlingerは、バッファーに添付されたプレゼンテーションタイムスタンプを確認することにより、レイヤーがバッファーをポストしている平均fpsを検出するヒューリスティックを維持します。
  • ro.surface_flinger.set_touch_timer_ms :> 0の場合、ユーザーが設定されたタイムアウトのために画面に触れたときに、デフォルトのリフレッシュレートが使用されます。このヒューリスティックは、アニメーションのデフォルトのリフレッシュレートで準備できるように行われます。
  • ro.surface_flinger.set_idle_timer_ms :> 0の場合、設定されたタイムアウトの画面更新がない場合、最小リフレッシュレートが使用されます。
  • ro.surface_flinger.set_display_power_timer_ms :> 0の場合、設定されたタイムアウトでディスプレイをオンにするとき(またはAODを終了するとき)にデフォルトのリフレッシュレートが使用されます。

フレームレートAPI

フレームレートAPIを使用すると、アプリはAndroidプラットフォームに目的のフレームレートを通知でき、Android 11を対象とするアプリで利用できます。フレームレートAPIの詳細については、developer.android.comの開発者向けドキュメントをご覧ください。

開発者向けオプション

メニューに新しい開発者向けオプションが追加され、ディスプレイのオーバーレイを現在のリフレッシュレートに切り替えます。新しいオプションは、 [設定] >[システム]>[開発者向けオプション]>[リフレッシュレートの表示]の下にあります。