Chasing 240 Hz: how frame pacing actually works
Removing Android's default 60 FPS ceiling is the easy 10% of the problem. The hard 90% is making sure the frames you've unlocked actually land somewhere useful.
Uncapped isn't the same as smooth
A game rendering 180 frames a second on a 144Hz panel isn't giving you 144Hz of motion. It's giving you an uneven mix of frames that get shown for different lengths of time, because nothing is pacing them to your display's refresh cycle. That mismatch is what most people are actually describing when they say an emulator feels "laggy" even though the frame counter looks fine.
Side by side: unpaced frame delivery versus paced delivery on the same panel
Emulade paces frames to your GPU's real output timing rather than Android's internal clock, which was never designed with a 240Hz desktop monitor in mind. In practice that means:
- The frame that gets shown is the most recent one available when your display is ready for it, not whatever finished rendering first.
- Frame pacing sits below the game, in the native engine, so it applies whether or not a given app was built with a desktop display in mind.
- Input is polled more often than a frame renders, so a tap doesn't wait behind a frame that's already committed.
Why this only works with a native engine
None of this is possible on top of a shared translation layer, because that layer doesn't have a reliable signal for when your display actually wants the next frame. It's abstracted away. A native hypervisor path keeps that signal intact from your monitor down to the guest.
If your panel does 240Hz, Emulade will use it. If it does 60, you'll get a clean 60 instead of an uneven approximation of one.