Буферизация и синхронизация кадров
Плавная картинка требует согласования времени — когда GPU закончил рисовать кадр, когда монитор его показывает, и видит ли пользователь целый кадр или "половинку".
Двойная буферизация
Монитор постоянно читает пиксели из видеопамяти (scan-out). Если рисовать в тот же буфер одновременно — на экране мерцание и "строительство" кадра.
Double buffering — два буфера:
| Буфер | Кто использует |
|---|---|
| Front | монитор читает сейчас |
| Back | GPU рисует следующий кадр |
Swap / Present — обмен указателей (часто без копирования 8 МБ).
| API | Swap |
|---|---|
| OpenGL / GLFW | glfwSwapBuffers() |
| SDL | SDL_GL_SwapWindow() |
| Pygame | pygame.display.flip() |
| Браузер | compositor после rAF + отрисовки canvas |
Tearing
Tearing (разрыв кадра) — монитор обновляет строки сверху вниз. Swap между строками → верх от старого кадра, низ от нового.
Кадр N: ████████░░░░ ← монитор здесь
Кадр N+1: ░░░░████████ ← swap посередине сканирования
На экране: ██████░░████ ← tearing
V-Sync
V-Sync (vertical sync) — swap разрешён только в blanking interval (пауза между кадрами монитора).
| Плюс | Минус |
|---|---|
| нет tearing | +1 кадр input lag |
| стабильный ритм | FPS cap = refresh (60/144) |
glfwSwapInterval(1) — включить в GLFW.
Если рендер дольше 16.7 ms при V-Sync 60 Гц — FPS падает до 30 (ждём следующий vsync).
Triple buffering
Три буфера: front, back, spare. Если кадр не успел до vsync — рисуем в третий, GPU не простаивает. Меньше просадки FPS, возможен больший lag.
G-Sync / FreeSync — монитор подстраивает refresh под GPU; меньше компромисса между tearing и lag.
Синхронизация в коде
| Среда | Механизм |
|---|---|
| Web | requestAnimationFrame — vsync compositor |
| Pygame | clock.tick(60) — ограничение + измерение dt |
| OpenGL | SwapBuffers; glFinish() только для отладки |
| Vulkan | semaphores, fences, present queue |
Не вызывайте glFinish() каждый кадр в проде — CPU ждёт GPU, теряется параллелизм.
Frame time и бюджет
Frame time — миллисекунды на полный цикл: input → update → render → present.
| FPS | Бюджет на кадр |
|---|---|
| 60 | 16.7 ms |
| 120 | 8.3 ms |
| 144 | 6.9 ms |
Превысили бюджет → даунскейл: меньше разрешение, эффекты, LOD, частицы.
Play ITЗагрузка интерактивного демо…
CPU time и GPU time
- CPU frame — логика, подготовка draw lists
- GPU frame — растеризация; может отставать на 1–2 кадра
Профилируйте оба — узкое место не всегда там, где кажется.
Fixed timestep
Физика на фиксированном шаге (1/60 с), render с интерполяцией между состояниями — стабильность при рывках V-Sync. Подробнее — игровой цикл.
Типичные проблемы
| Проблема | Причина |
|---|---|
| 60 FPS cap несмотря на мощный GPU | V-Sync, tick(60), rAF |
| Micro-stutter | нестабильный frame time, GC |
| Input lag на консоли | TV + V-Sync + triple buffer |