Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: verticalSync causes delay in MouseMoved events after MouseButtonPressed event.  (Read 3018 times)

0 Members and 1 Guest are viewing this topic.

nkrim

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
I have a cloth simulation program where the user can manipulate a cloth with their mouse, and I was noticing a strange delay in the invocation of MouseMoved events after clicking with the mouse. This delay would occur no matter how long I waited to move my mouse after the initial click (as long as the mouse button was held). After some investigation, I found that when I turned off v-sync this issue disappeared. I have included a very simple program that recreates this behavior on my machine:

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 800), "SFML works!");
   
    // -- toggle on/off the line below
    window.setVerticalSyncEnabled(true);    

    sf::CircleShape shape(100.f);
    shape.setFillColor(sf::Color::Green);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            else if (event.type == sf::Event::MouseMoved) {
                shape.setFillColor(sf::Color::Blue);
                std::cout << "moved" << std::endl;
            }
            else if (event.type == sf::Event::MouseButtonPressed) {
                shape.setFillColor(sf::Color::Red);
                std::cout << "PRESSED" << std::endl;
            }
        }

        window.clear();
        window.draw(shape);
        window.display();
    }

    return 0;
}
 

While v-sync is on, I can see the delay by clicking with the mouse, waiting with the mouse button held, and then moving the mouse with the button still held. If the event is MouseButtonPressed the circle becomes red, and if the event is MouseMoved the circle becomes blue (also printed to console during each event). I can see from this that, even in this small program, there is a short delay. In comparison, if you do not turn on v-sync, you can see that the color change and console output are as immediate as one would expect.

In my more complicated program, this delay is much more noticeable. My simulation's FPS doesn't drop during the delay, which makes me think something is affecting how the mouse events are added to the event queue.

I am on a mid-2014 Macbook Pro running MacOS 10.12 and SFML 2.5.1. I kind of suspect the likely cause is my outdated OS, but thought I might as well post this to see if anyone can reproduce what I'm seeing.
« Last Edit: February 23, 2022, 07:40:46 am by nkrim »

nkrim

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
I tried doing some timing tests without adding too much overhead, so what I have is a little less than optimal but I was able to get some semi-consistent numbers from it.

v-sync disabled:
t_diff: 0.011346s
t_diff: 1e-06s
t_diff: 0.012167s
t_diff: 0.026526s
t_diff: 1e-06s

v-sync enabled:
t_diff: 0.11651s
t_diff: 0.083314s
t_diff: 0.081267s
t_diff: 0.083336s
t_diff: 0.083301s

the additions to the code are as follows:
...
    // -- variable used for testing event state
    bool last_event_click = false;
    sf::Clock clock;

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            else if (event.type == sf::Event::MouseMoved) {
                shape.setFillColor(sf::Color::Blue);
                // std::cout << "moved" << std::endl;

                if(last_event_click) {
                    float t = clock.restart().asSeconds();
                    std::cout << "t_diff: " << t << "s" << std::endl;
                    last_event_click = false;
                }
            }
            else if (event.type == sf::Event::MouseButtonPressed) {
                shape.setFillColor(sf::Color::Red);
                // std::cout << "PRESSED" << std::endl;

                last_event_click = true;
                clock.restart();
            }
        }
...

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
To me it looks like your assumption that a mouse button press event triggers a mouse moved event is simply false. All you're measuring it how fast you can click and right after move your mouse. Just shake you mouse and randomly click around and your timing will automatically drop.

Not sure what you're trying to achieve exactly here, if you're interested in getting the mouse position when a button is pressed, then you don't need the mouse moved event, because that information is also encoded on the mouse button pressed event: https://www.sfml-dev.org/tutorials/2.5/window-events.php#the-mousebuttonpressed-and-mousebuttonreleased-events

Also the way VSync works is that the graphics driver/OpenGL will block as part of the window.display() call until the monitor is ready to receive the next frame. So if you have a 60Hz monitor, it will block somewhere arou 0.016s (1/60), that at least is the theory, in the end it's up to the GPU driver to implement this however they see fit.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

nkrim

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
My apologies, I am now pretty sure this issue is due to my computer. I knew my tests from before were a bit lazy so now I tried to record this problem via quicktime screen-capture and, while the screen-capture was on, there was a delay for all mouse events that was even more extreme than before for both v-sync enabled and disabled. So the graphics unit must be getting screwy. It's an old computer but I haven't really run into performance issues before, though its age may finally be getting the better of it. Though it is still strange to me how even during the screen capture (if I lower my simulation's settings) the output framerate looks fine but the inputs are still so delayed. But again I will assume this is my computer being wonky and old.
« Last Edit: March 02, 2022, 06:16:27 am by nkrim »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
But you do understand that the provided code doesn't actually test any specific input delay, right?

I still have a feeling that your input processing logic is flawed.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/