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

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

Варианты разработчика

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