В Android 11 добавлена поддержка устройств с несколькими частотами обновления. Эта функция состоит из трех основных компонентов:
- Новые API HAL представлены в
android.hardware.graphics.composer@2.4
. - Код платформы для анализа конфигураций устройств для разных частот обновления и установки желаемой частоты обновления
- Новые API SDK и NDK позволяют приложениям устанавливать желаемую частоту кадров
Выполнение
Специальная поддержка переключения частоты обновления была добавлена в android.hardware.graphics.composer@2.4 HAL
. Мы настоятельно рекомендуем использовать эту версию, так как предыдущие версии composer HAL имели ограниченную поддержку переключения частоты обновления.
Группы конфигурации
Новый атрибут CONFIG_GROUP
был добавлен в IComposerClient::Attribute
, который можно запросить с помощью 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
возвращает текущую частоту обновления (в терминах периода vsync), с которой работает дисплей. Это особенно полезно, когда переход между частотой обновления и текущей частотой обновления необходим платформе для определения того, когда начинать следующий кадр. - setActiveConfigWithConstraints
- Метод
setActiveConfigWithConstraints
— это новое расширение существующего методаsetActiveConfig
, которое предоставляет больше информации об изменении конфигурации. Ограничения задаются как часть параметровvsyncPeriodChangeConstraints
и содержат следующие параметры. - желаемоеВремяНанос
- Время в
CLOCK_MONOTONIC
, после которого период vsync может измениться (то есть период vsync не должен измениться до этого времени). Это полезно, когда платформа хочет заранее спланировать изменение частоты обновления, но у нее уже есть некоторые буферы в очереди для представления. Платформа устанавливает это время соответствующим образом, чтобы учесть эти буферы и убедиться, что переход частоты обновления будет максимально плавным. - бесшовныйТребуется
- Если true, требуется, чтобы изменение периода vsync происходило плавно, без заметного визуального артефакта. Этот флаг используется платформой, когда необходимо изменить частоту обновления в результате изменения контента (например, устройство находится в режиме ожидания и начинается анимация). Это дает поставщику возможность не разрешать определенные изменения конфигурации, когда они могут привести к заметному визуальному артефакту. Если конфигурации не могут быть изменены плавно, а
seamlessRequired
установлен вtrue
, реализация должна вернутьSEAMLESS_NOT_POSSIBLE
в качестве кода возврата и вызвать новый обратный вызовonSeamlessPossible
, когда то же изменение конфигурации может быть выполнено плавно. При успешном выполнении реализация возвращает
VsyncPeriodChangeTimeline
, который сообщает платформе, когда ожидать изменения частоты обновления. ПараметрыnewVsyncAppliedTimeNanos
должны быть установлены на время вCLOCK_MONOTONIC
, когда новый дисплей начнет обновляться с новым периодом vsync. Это вместе сdesiredTimeNanos
позволяет платформе заранее планировать переключение частоты обновления и заранее начинать отмечать приложения для новой частоты обновления. Это обеспечивает плавный переход частоты обновления.Некоторые реализации требуют отправки кадра обновления до отправки частоты обновления. Для этого в HAL есть параметр
refreshRequired
, указывающий на необходимость кадра обновления, иrefreshTimeNanos
, указывающий на первый vsync, после которого необходимо отправить кадр обновления.- onVsyncPeriodTimingChanged [обратный вызов]
- Новый обратный вызов, который может быть вызван HAL, чтобы указать платформе, что какой-то параметр временной шкалы изменился и платформе необходимо скорректировать свою временную шкалу. Ожидается, что этот обратный вызов будет вызван, если по какой-то причине старая временная шкала была пропущена из-за длительного времени обработки на HAL или позднего обновления кадра.
Каким образом платформа принимает решение об изменении частоты обновления?
Выбор частоты обновления происходит в следующих двух системных службах:
- ДисплейМенеджер
-
DisplayManager
устанавливает политику высокого уровня вокруг частоты обновления. Он устанавливает конфигурацию дисплея по умолчанию, которая совпадает с конфигурацией композитора HAL. Кроме того, он устанавливает диапазон минимальных и максимальных значений дляSurfaceFlinger
, которые можно выбрать в качестве частоты обновления. - 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 .
Варианты разработчика

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