Множественная частота обновления

В Android 11 добавлена ​​поддержка устройств с несколькими частотами обновления. Эта функция состоит из трех основных компонентов:

  • Новые API-интерфейсы HAL, представленные в android.hardware.graphics.composer@2.4 .
  • Код платформы для анализа конфигураций устройств на предмет различных частот обновления и установки желаемой частоты обновления.
  • Новые API SDK и NDK, позволяющие приложениям устанавливать желаемую частоту кадров.

Выполнение

В android.hardware.graphics.composer@2.4 HAL добавлена ​​специальная поддержка переключения частоты обновления. Мы настоятельно рекомендуем использовать эту версию, поскольку предыдущие версии композитора HAL имели ограниченную поддержку переключения частоты обновления.

Группы конфигурации

В IComposerClient::Attribute был добавлен новый атрибут CONFIG_GROUP , который доступен для запроса с помощью API getDisplayAttribute_2_4 . Этот атрибут позволяет поставщикам группировать конфигурации дисплея. Конфигурации в одной группе в большинстве случаев позволяют плавно переключаться между ними. Группа конфигурации используется платформой, чтобы различать конфигурации, которые можно переключать между ними, чтобы переключать частоту обновления, а не другие атрибуты конфигурации.

Рассмотрим следующий пример, демонстрирующий преимущества использования групп конфигурации с устройством, поддерживающим четыре конфигурации дисплея:

  • 1080p при 60 Гц
  • 1080p при 90 Гц
  • 1080i@72Гц
  • 1080i@48Гц

Несмотря на то, что устройство поддерживает частоту обновления 48 Гц, 60 Гц, 72 Гц и 90 Гц, дисплей работает в другом режиме, а переключение с 60 Гц на 72 Гц меняет конфигурацию дисплея с 1080p на 1080i, что может быть нежелательным. Это решается использованием групп конфигурации. Путем группировки 60 Гц и 90 Гц в одну группу конфигурации и 48 Гц и 72 Гц в другую группу конфигурации. Платформа знает, что она может переключаться между 60 Гц и 90 Гц и между 48 Гц и 72 Гц, но не между 60 Гц и 72 Гц, поскольку это приведет к изменению конфигурации, а не просто к изменению частоты обновления.

Обновления API Composer

getDisplayVsyncPeriod
Для лучшего контроля и предсказуемости при изменении частоты обновления был добавлен getDisplayVsyncPeriod . getDisplayVsyncPeriod возвращает текущую частоту обновления (в терминах периода вертикальной синхронизации), с которой работает дисплей. Это особенно полезно, когда переход между частотой обновления и текущей частотой обновления необходим платформе, чтобы решить, когда начинать следующий кадр.
setActiveConfigWithConstraints
Метод setActiveConfigWithConstraints — это новое расширение существующего метода setActiveConfig , предоставляющее дополнительную информацию об изменении конфигурации. Ограничения задаются как часть параметров vsyncPeriodChangeConstraints и содержат следующие параметры.
    желаемоеВремяНанос
    Время в CLOCK_MONOTONIC , после которого период вертикальной синхронизации может измениться (то есть период вертикальной синхронизации не должен меняться до этого времени). Это полезно, когда платформа хочет заранее спланировать изменение частоты обновления, но у нее уже есть несколько буферов в очереди для представления. Платформа устанавливает это время соответствующим образом, чтобы учесть эти буферы и обеспечить максимально плавный переход частоты обновления.
    бесшовныйОбязательно
    Если это правда, требуется, чтобы изменение периода вертикальной синхронизации происходило плавно, без заметных визуальных артефактов. Этот флаг используется платформой, когда требуется изменение частоты обновления в результате изменения контента (например, устройство находится в режиме ожидания и запускается анимация). Это дает поставщику возможность не допускать определенных изменений конфигурации, если они могут привести к заметным визуальным артефактам. Если конфигурации не могут быть изменены плавно и seamlessRequired установлено значение true , ожидается, что реализация вернет SEAMLESS_NOT_POSSIBLE в качестве кода возврата и вызовет новый обратный вызов onSeamlessPossible , когда то же самое изменение конфигурации можно выполнить плавно.

В случае успеха реализация возвращает VsyncPeriodChangeTimeline , который сообщает платформе, когда ожидать изменения частоты обновления. Параметры newVsyncAppliedTimeNanos должны быть установлены на время в CLOCK_MONOTONIC , когда новый дисплей начнет обновляться в новом периоде vsync. Это, вместе с desiredTimeNanos , позволяет платформе заранее планировать переключение частоты обновления и заранее начинать отмечать приложения для новой частоты обновления. Это обеспечивает плавный переход частоты обновления.

В некоторых реализациях перед отправкой частоты обновления требуется отправить кадр обновления. Для этого в HAL есть refreshRequired указывающий, что необходим кадр обновления, и refreshTimeNanos , указывающий первую vsync, после которой необходимо отправить кадр обновления.

onVsyncPeriodTimingChanged [обратный вызов]
Новый обратный вызов, который может быть вызван HAL, чтобы указать платформе, что какой-то параметр временной шкалы изменился и платформе необходимо скорректировать свою временную шкалу. Ожидается, что этот обратный вызов будет вызван, если по какой-то причине старая временная шкала была пропущена из-за длительного времени обработки в HAL или позднего кадра обновления.

Как платформа решает изменить частоту обновления?

Выбор частоты обновления происходит в следующих двух системных службах:

ДисплейМенеджер
DisplayManager устанавливает политику высокого уровня в отношении частоты обновления. Он устанавливает конфигурацию отображения по умолчанию, которая совпадает с конфигурацией HAL композитора. Кроме того, он устанавливает диапазон минимальных и максимальных значений, которые SurfaceFlinger может выбрать в качестве частоты обновления.
ПоверхностьФлингер
Определяет частоту обновления, устанавливая конфигурацию, которая находится в той же группе конфигурации, что и конфигурация по умолчанию, и с частотой обновления в диапазоне мин/макс.

Диспетчер отображения выполняет следующие шаги для определения политики:

  • Находит идентификатор конфигурации по умолчанию, запрашивая активную конфигурацию у SurfaceFlinger
  • Ограничение диапазона минимальных и максимальных значений путем перебора условий системы.
    • Настройка частоты обновления по умолчанию : значение частоты обновления по умолчанию устанавливается в наложении конфигурации R.integer.config_defaultRefreshRate . Это значение используется для определения стандартной частоты обновления устройства для анимации и сенсорного взаимодействия.
    • Настройка пиковой частоты обновления : значение пиковой частоты обновления считывается из Settings.System.PEAK_REFRESH_RATE . Это значение изменяется во время выполнения, чтобы отразить текущие настройки устройства (например, из пункта меню). Значение по умолчанию установлено в наложении конфигурации R.integer.config_defaultPeakRefreshRate .
    • Настройка минимальной частоты обновления . Минимальное значение частоты обновления считывается из Settings.System.MIN_REFRESH_RATE . Это значение можно изменить во время выполнения, чтобы отразить текущие настройки устройства (например, из пункта меню). Значение по умолчанию — 0, поэтому минимума по умолчанию нет.
    • Приложение запрашивает ModeId : приложения могут установить WindowManager.LayoutParams.preferredDisplayModeId чтобы отразить предпочтительную конфигурацию, с которой должен работать дисплей. В большинстве случаев DisplayManager соответствующим образом устанавливает идентификатор конфигурации по умолчанию и устанавливает минимальную и максимальную частоту обновления, соответствующую частоте обновления конфигурации.
    • Экономия заряда батареи : частота обновления ограничивается 60 Гц или ниже, когда устройство находится в режиме пониженного энергопотребления, что указывается в Settings.Global.LOW_POWER_MODE.

После того как DisplayManager устанавливает политику, SurfaceFlinger устанавливает частоту обновления на основе активных слоев (слоев, которые ставят обновления кадров в очередь). Если владелец слоя устанавливает частоту кадров , SurfaceFlinger пытается установить частоту обновления, равную множителю этой частоты. Например, если два активных слоя установили частоту кадров 24 и 60, SurfaceFlinger выберет 120 Гц, если это доступно. Если такая частота обновления недоступна для SurfaceFlinger, он попытается выбрать частоту обновления, которая имеет минимальную ошибку для частоты кадров. Дополнительную информацию см. в документации для разработчиков на сайте Developer.android.com.

SurfaceFlinger поддерживает следующие флаги для управления определением частоты обновления:

  • ro.surface_flinger.use_content_detection_for_refresh_rate: если установлено, частота обновления определяется на основе активных слоев, даже если частота кадров не была установлена. SurfaceFlinger поддерживает эвристику, позволяющую определить среднее значение частоты кадров в секунду, которое слой отправляет в буферы, просматривая временную метку представления, прикрепленную к буферу.
  • 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 .

Опции разработчика

В меню добавлена ​​новая опция разработчика, которая включает наложение на дисплей текущей частоты обновления. Новая опция находится в разделе «Настройки» > «Система» > «Параметры разработчика» > «Показать частоту обновления».