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

В 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 .

Варианты для разработчиков

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