Search code examples
c++sdlframe-rate

Why is the frame rate in my SDL 2 application being halved unless I move the mouse around in a certain position?


There's this extremely odd bug, which came seemingly out of nowhere, where my SDL 2 application has had a massive drop in frame rate (from ~60 to ~30). What's really odd about this bug is that while I move my cursor around quickly and outside of the window the frame rate speeds up back to normal.

What could be the issue? Or, how can I properly limit the framerate to exactly 60 (or whatever I please)?

EDIT: Here's the skeleton code which successfully replicates the problem:

#include <cstdio>
#include <SDL.h>

#define WIDTH 640
#define HEIGHT 480
#define FPS 60

using namespace std;

int main(int argc, char** args) {

    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window* window = SDL_CreateWindow("Cool Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
    SDL_Surface* winsurf = SDL_GetWindowSurface(window);
    SDL_Renderer* winren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(winren, 255, 255, 255, 255);

    bool quit = false;
    int counter = 0;
    int looptime = SDL_GetTicks();

    while (!quit) {

        SDL_RenderClear(winren);

        SDL_Event e;
        while (SDL_PollEvent(&e))
            if (e.type == SDL_QUIT)
                quit = true;

        printf("%d\n", counter++); // notice how quickly the counter speeds up
                                   // while moving your cursor around outside
                                   // of the window

        if (SDL_GetTicks() - looptime < 1000/FPS)
            SDL_Delay(1000/FPS - (SDL_GetTicks() - looptime));
        looptime = SDL_GetTicks();

        SDL_RenderPresent(winren);
    }

    SDL_Quit();

}

Solution

  • If anyone's interested, I fixed the problem by enabling Vsync. I added the SDL_RENDERER_PRESENTVSYNC flag to my call, like so:

    SDL_Renderer* winren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    This makes animation much more fluid.