Quick answer: Confirm SwappyGL_init (or SwappyVk_init) returned true. Replace eglSwapBuffers with SwappyGL_swap. Set target frame rate via SwappyGL_setSwapIntervalNS.
A mobile game stutters when reaching demanding scenes. Frame Pacing library is in the build but stutter persists. Engine still uses eglSwapBuffers directly — library never gets called.
Verify Init
bool initOk = SwappyGL_init(env, activity);
__android_log_print(ANDROID_LOG_INFO, "Game", "Swappy init: %d", initOk);
Run, check logcat. False = device unsupported or activity context missing. True = library ready.
Replace Swap Call
// Before:
eglSwapBuffers(display, surface);
// After:
SwappyGL_swap(display, surface);
Single function replacement. Swappy handles pacing internally; falls back to eglSwapBuffers on init failure.
Set Target Frame Rate
SwappyGL_setSwapIntervalNS(16666666); // 60fps
SwappyGL_setAutoSwapInterval(true); // auto adapt
60fps target = 16.66ms interval. AutoSwapInterval lets Swappy drop to 30fps if 60 not sustainable; better than judder.
Disable Engine VSync
If using Unity/Unreal, the engine’s vsync setting may conflict. Disable engine-level vsync; let Swappy handle:
- Unity: QualitySettings.vSyncCount = 0.
- Unreal: r.VSync 0, then engage Swappy.
Vulkan Variant
For Vulkan: use SwappyVk_initAndGetRefreshCycleDuration + SwappyVk_queuePresent instead of vkQueuePresentKHR.
Verifying
logcat -s Swappy: per-frame pacing metrics. Stable 60fps in stat. Visual: smoother feel, no judder during scene transitions.
“Library needs to actually be in the swap call path. Replace eglSwapBuffers and confirm via logcat.”
For 120Hz devices (Pixel 7+, Galaxy S22+), set interval 8333333 (8.33ms) and watch thermal — sustained 120fps drains battery fast.