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

Author Topic: Detect if vsync is active  (Read 6797 times)

0 Members and 1 Guest are viewing this topic.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Detect if vsync is active
« on: July 20, 2014, 03:02:28 am »
It's fairly annoying that setVerticalSyncEnabled(true) can fail to enable vsync - although that's not really any fault of SFML's. But it would be really nice to be able to detect if it is in effect or not.

Basically I find myself forced to enable user configurable options to enable/disable vsync (and then use setFramerateLimit() when users set it to 'Off') so that users at least have some way to avoid my game loops burning up 100% CPU.
I could of course just always use setFramerateLimit() and avoid having to add a config setting, but although that fixes the "burn 100% CPU" problem it doesn't fix tearing issues, which setVerticalSyncEnabled(true) does.

So basically what I would like would be either of these two:

1) Let setVerticalSyncEnabled() return a bool that indicates if the requested operation was a success or not. So basically setVerticalSyncEnabled(true) would return true if it successfully enabled vsync, false otherwise and setVerticalSyncEnabled(false) would return true if vsync was definitely disabled when it returned and false otherwise.

or

2) Add a "bool verticalSyncEnabled() const" function that tells you if vsync is currently active or not, so you can try and enable it and if it didn't take (since drivers forced it off or whatever other reason) you can at least find out and then just fall back on calling setFramerateLimit() without ever having to bother your users with switches they manually have to toggle.

AlejandroCoria

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
    • alejandrocoria.games
    • Email
Re: Detect if vsync is active
« Reply #1 on: July 20, 2014, 04:33:07 am »
One way to know if Vsync is enabled is to calculate the number of frames that are drawn in, say, a second. Then you compare it to the amount that should be (refresh rate monitor).

The way I get the monitor refresh rate in Windows is with the code below:

DEVMODE lpDevMode;
memset(&lpDevMode, 0, sizeof(DEVMODE));
lpDevMode.dmSize = sizeof(DEVMODE);
lpDevMode.dmDriverExtra = 0;
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &lpDevMode))
    rate = lpDevMode.dmDisplayFrequency;    // rate = refresh rate monitor

For Linux I have the following code, but I never tried:

Display *dpy = XOpenDisplay(NULL);
Window root = RootWindow(dpy, 0);
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
rate = static_cast<int>(XRRConfigCurrentRate(conf));
XCloseDisplay(dpy);

Unfortunately I could not find it for Mac.
« Last Edit: July 20, 2014, 04:35:08 am by AlejandroCoria »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Detect if vsync is active
« Reply #2 on: July 20, 2014, 04:39:18 am »
I am perfectly well aware that there are low-level ways to get at the information I want or hack'ish ways to try and detect it. The whole point is that I don't want to do that even though I most certainly can. SFML should let me query the information easily so I don't have to write low-level code (that I believe belongs inside SFML) or leave it up to users to manually flip a switch.
This is something that (IMHO) SFML can do and should do for me.

AlejandroCoria

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
    • alejandrocoria.games
    • Email
Re: Detect if vsync is active
« Reply #3 on: July 20, 2014, 05:06:18 am »
I know that if SFML can do, one would expect that the library does. The question is whether SFML can really do (and on all platforms). I have no idea if you can check if for example the video driver disabled the vertical sync. Or if there is a system function that allows to know the current state of vsync.

AlejandroCoria

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
    • alejandrocoria.games
    • Email
Re: Detect if vsync is active
« Reply #4 on: July 20, 2014, 05:15:36 am »
I found this post in the forum. I do not know if you had seen: http://en.sfml-dev.org/forums/index.php?topic=12224.0

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Detect if vsync is active
« Reply #5 on: July 20, 2014, 09:38:11 am »
Quote
This is something that (IMHO) SFML can do and should do for me.
I'm very interested in the "can" part. Without further investigation, I would rather say that this is impossible to do.
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Detect if vsync is active
« Reply #6 on: July 20, 2014, 11:28:31 am »
Well... first of all, one has to differentiate between where the VSync is set. In the application or system wide.

If the system doesn't have an override setting and lets each application decide for itself whether VSync should be enabled or not, and most importantly, the SFML application is the only one requesting VSync, then maybe it might be possible.

VSync is an OpenGL thing. Operating systems more often than not don't have any concept of vsync, because frankly, they don't need to. According to the specifications for swap_control on Linux and Windows:
https://www.opengl.org/registry/specs/EXT/swap_control.txt
https://www.opengl.org/registry/specs/SGI/swap_control.txt
https://www.opengl.org/registry/specs/EXT/wgl_swap_control.txt
There is always a way to query the current setting from the GL. But that setting might be local to the application, and doesn't take into account whether the setting would have made a system-wide difference or not. It is simply a number out of many numbers that the driver ends up taking into consideration when performing the real vertical synchronization.

You can have 4 situations:
  • True positive: setVerticalSyncEnabled returns true and the system-wide vsync is enabled
  • True negative: setVerticalSyncEnabled returns false and the system-wide vsync is disabled
  • False positive: setVerticalSyncEnabled returns true and the system-wide vsync is disabled
  • False negative: setVerticalSyncEnabled returns false and the system-wide vsync is enabled
In a perfect world, we would never have false positives or negatives. If the application could take exclusive control of the graphics hardware, then maybe that would be the case. If running in windowed mode while other applications are running, it might be the case that the return value is telling the truth, that your application is causing the vsync, or it might be lying because some other application is already causing the vsync and your application's setting doesn't matter at all.

If SFML were to return whether setting vsync was "successful" or not, it would be localized to the application only, and the developer would have to use their good judgement to act on that information. Chances are, if your application is fullscreen and setVerticalSyncEnabled returns true, you are synchronized. If your application isn't fullscreen, it's anybody's guess as to whether vsync was really enabled and whether it even makes a difference.

The other problem I see, is that unlike DirectX, OpenGL doesn't have a concept of "taking exclusive control" of the hardware. For example on Linux, "fullscreen" is often nothing more than a hack: a window without any decorations that just covers the entire screen. There can be multiple "fullscreen" applications running at the same time, and they might all be rendering via OpenGL as well. So even if the developer was smart in this case, they wouldn't be able to discern based on the return value of setVerticalSyncEnabled whether it was really enabled or not.

And finally, nothing prevents the user from disabling vsync all together from their driver control panel. SFML would still return true in this case, and you will have to assume based on that that vsync is enabled?!

Sure... SFML can return a bool for you, but the question is: Will that actually change anything in practice?
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

 

anything