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

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