Частота кадров

Библиотека Android Frame Pacing, также известная как Swappy, входит в состав Android Game SDK. Она помогает играм, использующим OpenGL и Vulkan, обеспечивать плавную отрисовку и правильную смену кадров на устройствах Android.

Синхронизация кадров – это синхронизация логики игры и цикла отрисовки с подсистемой дисплея ОС и базовым оборудованием дисплея. Подсистема отображения Android была разработана таким образом, чтобы избежать определенных визуальных артефактов, таких как разрывы. Подсистема отображения предотвращает разрывы, выполняя следующие действия:

  • Внутреннее буферирование предыдущих кадров
  • Обнаружение задержек при отправке кадров
  • Продолжать показывать текущий кадр при обнаружении запоздавшего кадра.

Несоответствие времени показа кадров возникает, когда цикл отрисовки игры выполняется с частотой, отличной от частоты, поддерживаемой встроенным оборудованием дисплея. Проблемы возникают, когда цикл отрисовки игры выполняется слишком медленно для оборудования дисплея, что приводит к непостоянному времени отображения. Например, если игра с частотой 30 кадров/с запускается на устройстве, которое поддерживает 60 кадров/с, то из-за цикла рендеринга повторяющийся кадр остается на экране ещё на 16 мс. Это приводит к существенным несоответствиям во времени формирования кадра, например 33 мс, 16 мс и 49 мс. Слишком сложные сцены усугубляют проблему, поскольку приводят к пропуску кадров.

Библиотека синхронизации кадров выполняет следующие задачи:

  • Компенсирует заикание из-за коротких игровых кадров.
    • Добавляет временные метки, чтобы кадры показывались вовремя, а не раньше.
    • Использует расширения временных меток презентации EGL_ANDROID_presentation_time и VK_GOOGLE_display_timing.
  • Использует барьеры синхронизации для длинных кадров, которые приводят к задержкам и заиканию.
    • Внедряет в приложение задержки. Это позволяет конвейеру отображения догнать, а не позволяет наращивать противодавление.
    • Используются барьеры синхронизации (EGL_KHR_fence_sync и VkFence).
  • Выбирает частоту обновления, чтобы обеспечить гибкость и плавное воспроизведение, если устройство поддерживает несколько частот обновления.
  • Предоставляет статистику для отладки и профилирования с помощью статистики кадров.

Чтобы узнать, как настроить библиотеку для работы в разных режимах, ознакомьтесь со статьей Поддерживаемые режимы работы.

Чтобы реализовать рендеринг с помощью OpenGL или Vulkan, ознакомьтесь со следующими статьями:

Подробнее о библиотеке Frame Pacing…

Ограничение количества кадров в секунду

Ограничение количества кадров в секунду (FPS) позволяет играм работать с подходящим количеством кадров в секунду, используя только изменения на стороне платформы и не требуя никаких действий со стороны разработчиков.

При реализации ограничения частоты кадров используются следующие компоненты.

GameManagerService

Компонент GameManagerService хранит всю информацию о режиме и вмешательстве для каждого пользователя и каждой игры. Информация о частоте кадров в секунду хранится в GameManagerService вместе с другими данными о вмешательстве, например коэффициентом уменьшения разрешения, в сопоставлении <PACKAGE_NAME, Interventions> для каждого профиля пользователя. Информация о частоте кадров в секунду становится доступна при изменении игрового режима или обновлении вмешательства. UID уникален для каждого PACKAGE_NAME и пользователя и может быть преобразован в пару <UID, Frame Rate> для отправки в SurfaceFlinger.

SurfaceFlinger

Компонент SurfaceFlinger уже поддерживает ограничение частоты кадров приложения, если она является делителем частоты обновления экрана. При получении сигнала VSync SurfaceFlinger проверяет его действительность для приложения с ограничением частоты кадров. Для этого он сравнивает временную метку VSync с частотой кадров приложения. Если частота кадров не совпадает с VSync, SurfaceFlinger удерживает кадр, пока они не совпадут.

На рисунке ниже показано взаимодействие между GameManagerService и SurfaceFlinger:

Взаимодействие между GameManagerService и SurfaceFlinger

Рисунок 1. Взаимодействие между GameServiceManager и SurfaceFlinger.

SurfaceFlinger поддерживает пару <UID, Frame Rate>, чтобы задать новый приоритет ограничения частоты кадров. Значение UID уникально для каждого пользователя и игры, поэтому у разных пользователей одного устройства могут быть разные настройки частоты кадров в одной и той же игре. Чтобы ограничить частоту кадров в игре, GameManagerService вызывает SurfaceFlinger для переопределения частоты кадров для UID. С помощью этого механизма SurfaceFlinger обновляет сопоставление при каждом изменении игрового режима или вмешательства. SurfaceFlinger обрабатывает изменение частоты кадров, соответствующим образом фиксируя буферы.

Подробнее об ограничении частоты кадров…