Понимание необходимости сигналов VSYNC от Android

Я пытаюсь лучше понять подсистему отображения Android, но один элемент, который все еще запутывает меня, - это то, как обрабатываются сигналы VSYNC, и почему так много существует в первую очередь.

Android предназначен для использования VSYNC по своему ядру, но есть несколько сигналов VSYNC, которые он использует. Через https://source.android.com/devices/graphics/implement.html в разделе "Смещение VSYNC" имеется блок-схема, которая отображает три сигнала VSYNC: HW_VSYNC_0, VSYNC и SF-VSYNC. Я понимаю, что HW_VSYNC используется для обновления времени в DispSync и что VSYNC и SF-VSYNC используются приложениями и поверхностным фильтром, но почему эти отдельные сигналы необходимы вообще? Кроме того, как смещения влияют на эти сигналы? Есть ли временная диаграмма в любом месте, что лучше объясняет это?

Спасибо за любую помощь, которую вы можете предложить.

Ответ 1

Чтобы понять этот материал, лучше всего начать с графической архитектуры уровня системы, особо отметив раздел "Необходимость тройного буферизации" и соответствующую диаграмму (что идеально было бы анимированным GIF). Предложение, которое начинается: "Если приложение начинает рендеринг на полпути между сигналами VSYNC, речь идет конкретно о DispSync. Как только вы прочтете это, надеюсь, что раздел DispSync графического документа устройства имеет больше смысла.

Большинство устройств не имеют настроенных смещений DispSync, поэтому на самом деле есть только один сигнал VSYNC. В дальнейшем я предполагаю, что DispSync включен.

Аппаратное обеспечение предоставляет только один сигнал VSYNC, соответствующий первичному обновлению дисплея. Другие генерируются в программном обеспечении с помощью кода SurfaceFlinger DispSync, срабатывающего при фиксированных смещениях от фактического VSYNC. Некоторое умное программное обеспечение используется для того, чтобы тайминги не ускорялись.

Сигналы используются для запуска композиции SurfaceFlinger и рендеринга приложения. Если вы выполните раздел в документе архитектуры, вы увидите, что это устанавливает два фрейма латентности между тем, когда приложение отображает его содержимое, и когда содержимое появляется на экране. Подумайте об этом так: учитывая три появления VSYNC, приложение рисует на V0, система выполняет композицию на V1, а скомпилированный кадр отправляется на дисплей в V2.

Если вы пытаетесь отслеживать сенсорный ввод, возможно, перемещая карту вокруг пальца пользователя, любая латентность будет восприниматься пользователем как вялый сенсорный ответ. Цель состоит в том, чтобы минимизировать задержку, чтобы улучшить работу пользователя. Предположим, мы немного задержали события, поэтому приложение рисует на V0.5, мы композитно на V1.2, а затем поменяем на дисплей на V2. За счет смещения приложения и активности SF мы уменьшаем общую задержку с 2 кадров до 1,5, как показано ниже.

enter image description here

Для чего нужен DispSync. В диаграмме обратной связи на странице, которую вы связали, HW_VSYNC_0 является аппаратным обновлением для физического дисплея, VSYNC заставляет приложение отображать, а SF_VSYNC заставляет SurfaceFlinger выполнять композицию. Ссылаясь на них как "VSYNC", это немного неправильно, но на ЖК-панели, ссылаясь на что-либо, как "VSYNC", вероятно, является неправильным.

"Временные метки выхода на пенсию", отмеченные в диаграмме петли обратной связи, относятся к умной оптимизации. Поскольку мы не работаем над фактическим оборудованием VSYNC, мы можем быть немного более эффективными, если выключить сигнал обновления. Вместо этого код DispSync будет использовать временные метки из заборных отступлений (что является целым другим обсуждением), чтобы проверить, не выпадает ли оно из синхронизации, и временно перезапустит аппаратный сигнал, пока он не вернется на дорожку.

Изменить: вы можете увидеть, как настроены значения в Nexus 5 boardconfig. Обратите внимание на настройки для VSYNC_EVENT_PHASE_OFFSET_NS и SF_VSYNC_EVENT_PHASE_OFFSET_NS.