Рендер у SDL программный. Перерисовывать каждый кадр полностью выходит дорого. Можно уменьшить уровень графики или сделать вид что тормоза это типа нормально. Но это всё не по джедайски. В SDL есть такая возможность как обновление части изображения. Для этого надо сначала определить какие части картинки изменились, нарисовать только их и указать SDL_UpdateRects перенести их на экран. Всё хорошо, но SDL_UpdateRects тупой, при неверном подходе может выйти медленнее чем при перерисовке всего. Так же не будет толку если перерисовывать большую часть изображения в закадровом буфере при обновлении только части.
Сейчас игра во время обновления состояния должна указать какие части экрана будут перерисованы. Между обновлением игры и рисованием вызывается функция что объединяет пересекающиеся области в большие блоки. Лишних областей получается больше чем если делать точно, но всё равно рисуется заметно меньше чем весь кадр. Функция что непосредственно рисует на экране теперь проверяет пересечение изображения с такими блоками и рисует только то что попадает в отмеченные зоны.
Это всё должно обеспечить стабильные 30 кадров в секунду на практически любом железе.