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