SFML community forums

Help => General => Topic started by: AFS on April 14, 2017, 10:56:04 pm

Title: [Solved] Stuttering on windowed mode
Post by: AFS on April 14, 2017, 10:56:04 pm
Hello.

I hate to ask, but this has been bothering me for months and I still can't find a solution on my own.

I experience stuttering every second or so on my desktop (Win 7, i5 3.0 ghz, GeForce 780, 8 GB RAM), but only if I run the application on a window that's smaller than the desktop resolution. In other words, it works smoothly either at fullscreen or on a borderless window the same size as the desktop, but smaller windows get stutter, borderless or not. This happens either with Vsync or or off, or with a fixed or variable timestep. 

Weirdly enough, I don't experience this on my much less powerful laptop (Surface Pro 2, with Intel Integrated Graphics).

At first I thought it was a problem with my project, but then I realized that it also happens with the following minimal code. It draws a circle shape on screen and uses the A and D keys to move the view left and right respectively, which makes the stutter noticeable.

int main() {

    // Options.

    int resolutionX = 1920;
    int resolutionY = 1080;

    bool fullscreen = false;
    bool borderless = false;

    bool vsync = true;

    bool unlimitedFrames = false;
    bool variableTimestep = false;

    bool printFPS = true;

    // Create window.

    int style = sf::Style::Default;

    if (fullscreen)
        style = sf::Style::Fullscreen;

    else if (borderless)
        style = sf::Style::None;

    sf::RenderWindow window( sf::VideoMode(resolutionX, resolutionY), "Frame Test", style );

    if (vsync)
        window.setVerticalSyncEnabled(true);
    else if (unlimitedFrames)
        window.setFramerateLimit(0);
    else
        window.setFramerateLimit(60);

    // Shape.
    sf::CircleShape shape(100.f);
    shape.setFillColor(sf::Color::Red);

    // Game loop.
    sf::Clock frameClock;
    float frameTime = 0;

    while ( window.isOpen() ) {

        // Poll events.
        sf::Event event;
        while ( window.pollEvent(event)) {

            if (event.type == sf::Event::Closed)
                window.close();
        }

        // Close window with either ESC or Delete.
        bool esc = sf::Keyboard::isKeyPressed( sf::Keyboard::Escape );
        bool del = sf::Keyboard::isKeyPressed( sf::Keyboard::Delete );

        if (esc || del)
            window.close();

        // Move camera with keyboard.
        bool left = sf::Keyboard::isKeyPressed( sf::Keyboard::A );
        bool right = sf::Keyboard::isKeyPressed( sf::Keyboard::D );

        if ( left || right ) {

            float movement = 1000;
            if (left)
                movement *= -1;

            if (variableTimestep)
                movement *= frameTime;
            else
                movement *= 1 / 60.0;

            sf::View view = window.getView();
            view.move( movement, 0 );
            window.setView(view);
        }

        // Draw.
        window.clear(sf::Color::White);
        window.draw(shape);
        window.display();

        // Get frame time, just in case.
        frameTime = frameClock.restart().asSeconds();

        if ( printFPS ) {

            int framesPerSecond = 1 / frameTime;
            std::cout << framesPerSecond << "\n";

        }

    }

    return 1;

}
 

Unfortunately I couldn't record the stuttering, because Shadowplay itself also causes stutter, even at fullscreen, and recording with Fraps kind of stops the stuttering a little bit for some reason. However, I found a similar topic (https://en.sfml-dev.org/forums/index.php?topic=16449.0) which has the following video that perfectly describes my problem:

 (https://vimeo.com/107787021)

Some considerations:

- As mentioned, it happens either with Vsync on or off. I have Vsync enabled in my Nvidia Control Panel. It also happens if I force Vsync on it.
- I have "Threaded optimization" disabled in the control panel. Doesn't make a difference.
- I don't have F.lux installed. I did have it months ago, but I unistalled it, restoring Windows default color settings.
- I just updated to SFML 2.4.2, but the problem persists. I also updated my Nvidia drivers, but no dice.
- Recording with Shadowplay (or enabling it to always record the last 5 minutes) causes the stutter to happen even at fullscreen, as mentioned. It only happens with SFML; I can record other games smoothly.
- Fully disabling Shadowplay doesn't make a difference.
- It happens both on my 720p monitor or my 1080p TV.
- I don't get stutter on other non-SFML games. I haven't tested other people SFML games, though.

Finally, in the code snippet above you can print the FPS counter in the console, getting interesting numbers. I'm aware that this affects performance, but the stutter happens even without doing it.

With Vsync, it usually prints the following sequence: ..., 59, 60, 59, 60, 59, 31, 190, 59, 60, 59, 60..., every second or so. It usually prints 30 or a very close number first, and then prints a high number like 150, 200, sometimes even 500.

Without Vsync, limiting it to 60 frames per second, it usually prints the folllowing sequence: ..., 62, 62, 62, 62, 62, 30, 62, 62, 62..., every second or so. It usually is 30 or some very close number.

On fullscreen, with or without Vsync, it prints: 59, 59, 59, 60, 59, 59..., as expected. It looks very smooth.

Honestly, I'm baffled, I have no idea what's causing it. Probably it's something on my end, but unfortunately I'm not knowledgeable enough to guess what exactly is happening.

Thanks in advance for any help.
Title: Re: Stuttering on windowed mode
Post by: eXpl0it3r on April 14, 2017, 11:24:12 pm
Try the SFML master branch (you can also use the CI artifacts (https://www.sfml-dev.org/artifacts/by-branch/master/) if you don't want to build SFML yourself) and see if that helps. We had some problem with the joystick API, that randomly caused relatively large lag spikes and could vary from system to system.
Title: Re: Stuttering on windowed mode
Post by: AFS on April 15, 2017, 01:27:21 am
Wow, I made a build from the master branch and it was fixed, just like that. :o

The stuttering is gone with Vsync, even if windowed. There's some stuttering without Vsync, which I'm sure it's not tearing, but it's much less jumpy than before, it only fluctuates between 62 and 68 frames, so it's ok. The best thing is now that Shadowplay doesn't cause stuttering no more, so now I can record! I could record fine with Fraps and OBS, but my game has a bug that makes most letters in texts missing while recording for some bizarre reason, but that's a topic for another day.

I did read about that joystick issue, but I could've sworn it was already fixed in 2.4.2, how silly of me.

Thanks a lot! ;D