VSync (Vertical Synchronization) — технология, която синхронизира извеждането на всеки нов кадър на GPU с честотата на опресняване на дисплея, премахвайки разкъсването на изображението. Според Apple Metal Documentation, синхронизацията с VBlank е задължителна за гладко рендиране на мобилни устройства. Screen tearing възниква, когато кадърът се актуализира по време на вертикалното сканиране, а VSync предотвратява това смесване.
Основни точки
VSync (Vertical Synchronization) — хардуерно-софтуерен механизъм, който принуждава GPU да изчака сигнала за вертикално затихване (VBlank) преди да изведе нов кадър. Без VSync, GPU може да изпраща кадри по всяко време, дори когато дисплеят е в процес на рендиране на текущия кадър, което води до разкъсване на изображението по хоризонтална линия.
На мобилни устройства VSync е имплементиран на ниво графичен драйвер и операционна система. iOS използва VBlank синхронизация чрез Metal, Android — чрез SurfaceFlinger и BufferQueue. При включена вертикална синхронизация, FPS на приложението не може да надвиши честотата на опресняване на дисплея — 60, 90 или 120 Hz в зависимост от модела на устройството.
Терминът вертикална синхронизация произлиза от механизма на работа на CRT мониторите, където електронен лъч рисуваше изображението ред по ред отгоре надолу. След завършване на кадъра, лъчът се връщаше в горния ляв ъгъл — този момент се наричаше вертикално затихване. Съвременните LCD и OLED дисплеи запазиха този термин, въпреки че физически работят различно.
GPU рендира кадри в back buffer, а дисплеят чете от front buffer. VSync гарантира, че превключването на буферите (swap) се случва само в момента на VBlank — когато дисплеят е завършил изобразяването на текущия кадър и е готов за следващия. Този механизъм се нарича двойно буфериране със синхронизация чрез VBlank.
Двойното буфериране използва два буфера: front buffer, показван на екрана, и back buffer, в който GPU записва текущия кадър. Когато кадърът е готов, буферите си разменят местата. С включен VSync, тази размяна се отлага до най-близкия VBlank. GPU е неактивен, ако кадърът е готов преди VBlank, което намалява производителността, но елиминира tearing.
// OpenGL — включване на VSync чрез WGL_EXT_swap_control
HDC hdc = wglGetCurrentDC();
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT =
reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(
wglGetProcAddress("wglSwapIntervalEXT"));
wglSwapIntervalEXT(1); // 1 = VSync включен, 0 = изключен
VBlank — кратък времеви интервал между последния ред на текущия кадър и първия ред на следващия. В този момент дисплеят не актуализира пиксели и превключването на буферите става без артефакти. Продължителността на VBlank зависи от честотата на опресняване: при 60 Hz на 1080p дисплей, VBlank трае приблизително 1.4 ms. Ако GPU не успее да завърши рендирането преди VBlank, кадърът се пропуска и дисплеят показва предишния кадър още един цикъл — това се възприема като заекване (stutter).
Тройното буфериране решава проблема с неактивността на GPU чрез добавяне на трети буфер. GPU може незабавно да започне рендиране на следващия кадър, дори ако един от back буферите чака VBlank. Това увеличава FPS с VSync, но добавя допълнителен кадър забавяне. На мобилни устройства, тройното буфериране се използва в някои игрови двигатели и във Vulkan чрез режим Mailbox.
Изключен VSync дава максимален FPS и минимален input lag, но за сметка на визуални артефакти. За мобилни игри и приложения с гладка анимация, изборът между VSync и изключването му е компромис между острота на изображението и отзивчивост на управлението.
Screen tearing — хоризонтално разкъсване, при което горната част на екрана показва предишния кадър, а долната част — вече следващия. Това се случва, когато GPU сменя буферите в средата на цикъла на сканиране на дисплея. На мобилни устройства, tearing е особено забележим при бързо превъртане или в динамични сцени с висока честота на кадрите. OLED дисплеите с незабавния си отклик правят tearing по-контрастен в сравнение с LCD.
Интензитетът на tearing зависи от съотношението на FPS към честотата на опресняване. При 60 FPS на 60 Hz екран, tearing се проявява като една статична линия, а при 300 FPS на 60 Hz — като множество вълнообразни разкъсвания, движещи се отгоре надолу. Колкото по-висок е FPS спрямо честотата на опресняване, толкова повече разкъсвания и толкова по-забележими са те.
Input lag при VSync — забавянето между натискане на бутон и показване на резултата на екрана. Вертикалната синхронизация добавя средно един кадър забавяне (16.7 ms при 60 Hz), а при тройно буфериране — до два кадъра. За обикновени приложения това забавяне е незабележимо, но за шутъри, файтинг игри и ритъм игри е критично: професионалистите забелязват дори 8 ms забавяне.
Според изследване на NVIDIA (2024), средният input lag в CS:GO при 60 FPS без VSync е 22 ms, а с VSync — 39 ms. При 144 FPS разликата намалява до 14 vs 18 ms съответно. На мобилни платформи, input lag на VSync е по-малко критичен поради сензорния вход, където хардуерното забавяне на тъчскрийна (10–30 ms) маскира допълнителното забавяне от синхронизация.
В мобилното разработване VSync се управлява чрез графични API, игрови двигатели и системни настройки на ОС. iOS предоставя по-малко контрол, Android — повече чрез Vulkan и OpenGL ES. Изборът на режим зависи от типа приложение: игри, UI или видео.
Unity използва настройката QualitySettings.vSyncCount: 0 — изключен, 1 — VSync при всеки VBlank, 2 — при всеки втори (FPS се намалява наполовина). В Unreal Engine VSync се управлява чрез конзолната команда r.VSync и DefaultEngine.ini. За мобилни компилации се препоръчва изключване на VSync в Unity и използване на собствен FPS ограничител, тъй като вграденият VSync в Android SurfaceFlinger може да създава непредвидими забавяния.
// Unity — управление на VSync и FPS
void Awake()
{
// 0 = VSync изключен, 1 = VSync включен
QualitySettings.vSyncCount = 0;
// Собствен FPS ограничител вместо VSync
Application.targetFrameRate = 60;
}
Vulkan дава пълен контрол чрез VkSwapchainPresentInfo и presentMode: VK_PRESENT_MODE_FIFO_KHR — класически VSync, VK_PRESENT_MODE_MAILBOX_KHR — тройно буфериране без изчакване, VK_PRESENT_MODE_IMMEDIATE_KHR — без синхронизация. Metal в iOS управлява VSync чрез CAMetalLayer.displaySyncEnabled. От iOS 14 насам, Apple препоръчва използване на displaySyncEnabled = true по подразбиране за всички приложения, освен игри с аркадни контроли.
| Режим | Описание | Забавяне |
|---|---|---|
| FIFO | Класически VSync с изчакване на VBlank | 1 кадър |
| Mailbox | Тройно буфериране, изхвърляне на стари кадри | 1–2 кадъра |
| Immediate | Без синхронизация, максимален FPS | 0 кадъра |
FPS ограничител — алтернатива на VSync, при която приложението програмно ограничава честотата на кадрите, без да чака VBlank. Този подход дава предвидимо забавяне и не зависи от честотата на опресняване на дисплея. На Android, ограничаването на FPS се реализира чрез Choreographer, на iOS — чрез CADisplayLink с ръчно управление на времето за извеждане.
Традиционният VSync има фундаментален недостатък: той е обвързан с фиксирана честота на опресняване на дисплея. Ако GPU произвежда 45 FPS на 60 Hz екран, VSync не може да показва 45 кадъра — показва 30 (пропускайки всеки втори VBlank) или редува 60 и 30 с неравномерни интервали. Това създава заекване (stutter), което разваля игровото изживяване повече от tearing.
Adaptive Sync (FreeSync, G-Sync, Apple ProMotion) решава този проблем чрез динамична промяна на честотата на опресняване на дисплея в съответствие с FPS на приложението. Ако приложението произвежда 47 FPS, дисплеят превключва на 47 Hz — всеки кадър се показва точно веднъж, без разкъсвания и заекване. ProMotion в iOS автоматично избира честота от 24 до 120 Hz, балансирайки плавността и консумацията на енергия.
На мобилни устройства Adaptive Sync става стандарт: iPad Pro (2017+) с ProMotion, Android флагмани с LTPO дисплеи (Samsung Galaxy S23 Ultra, Google Pixel 8 Pro) поддържат динамична честота на опресняване от 1 до 120 Hz. За разработчика това означава, че VSync в традиционния смисъл се заменя от системно управление — достатъчно е да зададете targetFrameRate, а ОС сама ще настрои честотата на опресняване за оптимален баланс между плавност и живот на батерията.
Често задавани въпроси
Не. В динамични игри (шутъри, файтинг игри) VSync увеличава input lag без значима полза — tearing на мобилни OLED екрани е по-малко забележим поради малкия размер на дисплея. За обикновени игри и UI, VSync подобрява възприятието за плавност.
VSync намалява консумацията на енергия, защото GPU не рендира излишни кадри. При изключен VSync, GPU работи на максимална честота и всеки непоказан кадър губи енергия и нагрява устройството без полза за потребителя.
VSync синхронизира извеждането на кадри с VBlank на дисплея, докато FPS ограничителят просто ограничава честотата на рендиране в кода на приложението. FPS ограничителят не премахва tearing, но дава предвидимо забавяне без обвързване с честотата на опресняване на екрана.
Когато GPU не успее да завърши кадъра преди VBlank, VBlank се пропуска и кадърът се показва за два цикъла на опресняване. При 60 Hz това дава 30 FPS. Тройното буфериране смекчава този ефект, позволявайки на GPU да започне следващия кадър без изчакване.
Да. iOS ProMotion (iPad Pro, iPhone 13 Pro+) поддържа динамична честота 24–120 Hz. Android чрез LTPO панели поддържа 1–120 Hz. Разработчикът не трябва да управлява това ръчно — системата избира оптималната честота автоматично.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също