3
votes

I was wondering if there is a frame rate cap built into SDL 2.0? If so, how could one modify the default cap?

I am creating a game engine using C++ and SDL 2.0. When I display what I believe to be the frame rate as rendered text onto the screen, the displayed result constantly fluctuates between 58 and 62 frames per second.

This seems odd to me as no matter how many images I render on the screen, or how much logic code work I put into a single cycle, the displayed frame rate remains within 58 to 62 frames per second.

Here is how I am calculating the frame rate:

// FPS
//Record the current system ticks
mSystemTicksCurrent = Timer::GetSystemTicks();

//Calculate the time it takes for a single cycle to run
mSingleCycle = mSystemTicksCurrent - mSystemTicksPrevious;

//to prevent division by zero...
if(mSingleCycle != 0)
{
    mFPS = 1000.0f / mSingleCycle;
}
//...indicate that a miniscule amount of time has elapsed, thus leading to an extremely fast frame rate
else
{
    mFPS = 9999.9f;
}


//Since we are done calculating the time it has taken for a single cycle to elapse,
//record the time that was used to calculate the elapsed cycle time for future use.
mSystemTicksPrevious = mSystemTicksCurrent;

and now I take the calculated frame rate and render it to the screen:

if(mpTimerFPS != nullptr)
{
    if(mpTimerFPSText != nullptr)
    {
        sprintf_s(mTimerFPSTextBuff, "FPS: %.1f", mFPS);
        mpTimerFPSText->SetTexture(Window::UpdateText(mTimerFPSTextBuff, mpTimerFPSFont, mTimerFPSColor));
    }
}

Where the Timer::GetSystemTicks() function is simply as follows:

Uint32 Timer::GetSystemTicks()
{
    return timeGetTime();
}

I can provide more code if necessary.

1
I don't know for sure, but I would imagine that SDL is set to not render any faster than the screen's refresh rate (usually 60Hz). What would be the point of displaying at a faster rate than that? If you want a faster rate for other things (e.g., physics), then run that in a loop on a separate thread.Mikael Persson
timeGetTime() is not precise. It's precision on Windows is usually around 16 ms, which would give up to 62 FPS.Collin Dauphinee
Did you create the renderer with the SDL_RENDERER_PRESENTVSYNC flag ? wiki.libsdl.org/…olevegard
I tested the methods outlined in SDL Average FPS Measurement with SDL2 (hw accel renderer) and the last method (Last-second FPS) shows ticks around 3500. You might want to give it a try too. Anyway I don't think SDL2 limits frame rate.jpw

1 Answers

12
votes

After testing your responses, I have determined that it is indeed the renderer being limited by the screen's refresh rate because I used the SDL_RENDERER_PRESENTVSYNC flag in creating the renderer. The following line of code is what is limiting the framerate:

mpRenderer.reset(SDL_CreateRenderer(mpWindow.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC));

Even if I remove the SDL_RENDERER_ACCELERATED flag, the framerate stays at whatever the monitor is set to refresh at. I tested and proved this by changing my monitor's refresh rate to 75Hz instead of 60Hz and my tests increased to 74-77 fps. The moment I remove the SDL_RENDERER_PRESENTVSYNC flag, the frame rate skyrockets.

As a side note: I tested this using timeGetTime() as well as other tick count retrieving functions, and all returned the same results.

Reference to SDL_CreateRenderer(): https://wiki.libsdl.org/SDL_CreateRenderer