В Android 11 добавлена поддержка устройств с несколькими частотами обновления. Эта функция состоит из трех основных компонентов:
- Новые HAL API представлены в
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 композитора
- getDisplayVsyncPeriod
- Для лучшего контроля и предсказуемости при изменении частоты обновления добавлен
getDisplayVsyncPeriod
.getDisplayVsyncPeriod
возвращает текущую частоту обновления (с точки зрения периода вертикальной синхронизации), с которой работает дисплей. Это особенно полезно, когда переход между частотой обновления и текущей частотой обновления необходим платформе, чтобы решить, когда начинать следующий кадр. - сетактивеконфигвисконстрейнтс
- Метод
setActiveConfigWithConstraints
является новым расширением существующего методаsetActiveConfig
и предоставляет дополнительные сведения об изменении конфигурации. Ограничения задаются как часть параметровvsyncPeriodChangeConstraints
и содержат следующие параметры. - желаемыйTimeNanos
- Время в
CLOCK_MONOTONIC
после которого период vsync может измениться (то есть период vsync не должен изменяться до этого времени). Это полезно, когда платформа хочет заранее спланировать изменение частоты обновления, но у нее уже есть буферы в очереди для представления. Платформа устанавливает это время соответствующим образом, чтобы учесть эти буферы и убедиться, что переход частоты обновления будет максимально плавным. - бесшовныйОбязательный
- Если задано значение true, требуется, чтобы изменение периода вертикальной синхронизации происходило плавно, без заметного визуального артефакта. Этот флаг используется платформой, когда требуется изменение частоты обновления в результате изменения контента (например, устройство простаивает и начинается анимация). Это дает поставщику возможность не разрешать определенные изменения конфигурации, если они могут привести к заметному визуальному артефакту. Если конфигурации не могут быть изменены
seamlessRequired
, а для SeamlessRequired задано значениеtrue
, ожидается, что реализация вернетSEAMLESS_NOT_POSSIBLE
в качестве кода возврата и вызовет новый обратный вызовonSeamlessPossible
когда то же самое изменение конфигурации может быть выполнено без проблем. В случае успеха реализация возвращает
VsyncPeriodChangeTimeline
, который сообщает платформе, когда следует ожидать изменения частоты обновления. ПараметрыnewVsyncAppliedTimeNanos
должны быть установлены на время вCLOCK_MONOTONIC
когда новый дисплей начнет обновляться в новом периоде vsync. Это, вместе сdesiredTimeNanos
, позволяет платформе заранее планировать переключение частоты обновления и заранее начинать отмечать приложения для новой частоты обновления. Это обеспечивает плавный переход частоты обновления.Некоторые реализации требуют отправки кадра обновления перед отправкой частоты обновления. Для этого в HAL есть параметр
refreshRequired
, указывающий, что необходим кадр обновления, иrefreshTimeNanos
, указывающий на первую вертикальную синхронизацию, после которой необходимо отправить кадр обновления.- onVsyncPeriodTimingChanged [обратный вызов]
- Новый обратный вызов, который может быть вызван HAL, чтобы указать платформе, что какой-то параметр временной шкалы изменился, и платформе необходимо скорректировать свою временную шкалу. Ожидается, что этот обратный вызов будет вызван, если по какой-то причине старая временная шкала была пропущена из-за длительного времени обработки в HAL или позднего обновления кадра.
Как платформа решает изменить частоту обновления?
Выбор частоты обновления происходит в следующих двух системных службах:
- DisplayManager
-
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 .
Варианты для разработчиков
В меню добавлена новая опция разработчика, которая переключает наложение на дисплей с текущей частотой обновления. Новая опция находится в разделе « Настройки »> « Система» > «Параметры разработчика »> « Показать частоту обновления».