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

В Android 11 добавлена ​​поддержка устройств с несколькими частотами обновления экрана. Эта функция состоит из трех основных компонентов:

  • В версии android.hardware.graphics.composer@2.4 представлены новые API HAL.
  • Код платформы для анализа конфигураций устройств с различными частотами обновления и установки желаемой частоты обновления.
  • Новые API для SDK и NDK позволяют приложениям устанавливать желаемую частоту кадров.

Выполнение

В эту версию добавлена ​​специальная поддержка переключения частоты обновления… Мы настоятельно рекомендуем использовать эту версию, поскольку предыдущие версии Composer HAL имели ограниченную поддержку переключения частоты обновления.

Группы конфигурации

В IComposerClient::Attribute добавлен новый атрибут CONFIG_GROUP , который можно запросить с помощью API getDisplayAttribute_2_4 . Этот атрибут позволяет поставщикам группировать конфигурации дисплея. В большинстве случаев конфигурации в одной группе позволяют беспрепятственно переключаться между ними. Платформа использует группу конфигураций для различения тех конфигураций, между которыми можно переключаться для изменения частоты обновления, и тех, которые не могут переключаться между другими атрибутами конфигурации.

Рассмотрим следующий пример, демонстрирующий преимущества использования групп конфигураций с устройством, поддерживающим четыре варианта отображения:

  • 1080p@60Hz
  • 1080p@90Hz
  • 1080i@72Hz
  • 1080i@48Hz

Несмотря на то, что устройство поддерживает частоты обновления 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 , по истечении которого период вертикальной синхронизации может изменяться (то есть период вертикальной синхронизации не должен изменяться до этого времени). Это полезно, когда платформа хочет заранее спланировать изменение частоты обновления, но у нее уже есть буферы в очереди для отображения. Платформа устанавливает это время соответствующим образом, чтобы учесть эти буферы и обеспечить максимально плавный переход частоты обновления.
    seamlessRequired
    Если значение истинно, это означает, что изменение периода синхронизации происходит плавно, без заметных визуальных артефактов. Платформа использует этот флаг, когда изменение частоты обновления необходимо в результате изменения контента (например, устройство находится в режиме ожидания, и начинается анимация). Это дает поставщику возможность не разрешать определенные изменения конфигурации, если они могут привести к заметным визуальным артефактам. Если изменения конфигурации не могут быть выполнены плавно, и seamlessRequired установлено в true , ожидается, что реализация вернет код возврата SEAMLESS_NOT_POSSIBLE и вызовет новый коллбэк onSeamlessPossible , когда то же изменение конфигурации может быть выполнено плавно.

В случае успеха реализация возвращает объект VsyncPeriodChangeTimeline , который сообщает платформе, когда следует ожидать изменения частоты обновления. Параметры newVsyncAppliedTimeNanos необходимо установить на время в CLOCK_MONOTONIC , когда новый дисплей начнет обновляться с новым периодом вертикальной синхронизации. Это, вместе с desiredTimeNanos , позволяет платформе заранее спланировать переключение частоты обновления и начать запускать приложения для новой частоты обновления. Это обеспечивает плавный переход частоты обновления.

В некоторых реализациях требуется отправка кадра обновления перед отправкой частоты обновления. Для этого HAL имеет параметр refreshRequired , указывающий на необходимость отправки кадра обновления, и refreshTimeNanos , указывающий на первую синхронизацию vsync, после которой необходимо отправить кадр обновления.

onVsyncPeriodTimingChanged [callback]
Новая функция обратного вызова, которую HAL может вызвать, чтобы сообщить платформе об изменении какого-либо параметра временной шкалы и необходимости ее корректировки. Ожидается, что эта функция обратного вызова будет вызвана, если по какой-либо причине старая временная шкала была пропущена из-за длительного времени обработки в HAL или задержки обновления кадра.

Как платформа принимает решение об изменении частоты обновления?

Выбор частоты обновления происходит в следующих двух системных службах:

Дисплейменеджер
DisplayManager задает политику верхнего уровня в отношении частоты обновления. Он устанавливает конфигурацию дисплея по умолчанию, которая совпадает с конфигурацией Composer 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, то при включении дисплея (или при выходе из режима Always On Display) в течение заданного времени будет использоваться частота обновления по умолчанию.

API частоты кадров

API частоты кадров позволяет приложениям сообщать платформе Android о желаемой частоте кадров и доступен для приложений, ориентированных на Android 11. Чтобы узнать больше об API частоты кадров, ознакомьтесь с документацией для разработчиков на developer.android.com .

Параметры разработчика

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