How to check if v-sync is actually enabled

I’ve looked for an answer to this question, but to no avail.

When using a BufferStrategy, how can I check whether VSync is currently enabled? I know that it can be overridden to “off” by graphics driver settings, and some situations may not support it, so I’d like to know when it fails so that I can compensate accordingly within my code.

Bonus question: when using triple buffering, is there any way I can synchronize some logic to the vsync pulse, despite my render thread being able to run at unlimited speed?

Well, your FPS should be locked to a certain frame per second. Most likely 60.

Yes, I can tell whether vsync is enabled based on my in-game FPS counter… but making my rendering engine’s code depend on the average results of the FPS counter to “guess” whether vsync is enabled seems like a very poor solution. Not to mention, framerate fluctuations could trigger false positives or negatives.

So then have it always enabled or not. Your code really shouldn’t be dependent on vSync anyway. I don’t understand what you need to change when vSync is enabled?

You can’t “always” enable vsync. Sometimes it is not supported or the graphics drivers override it, and then (it seems) there is no way to notice it’s off, other than measuring the current framerate.

My rendering engine uses two different scrolling methods; one if vsync is enabled and one if vsync is disabled. The vsync-enabled method looks much nicer because it scrolls at whole pixel intervals per screen refresh, but this makes the scrolling speed (partially) dependent upon the framerate, and should be disabled if vsync is off.

In the end I’ve settled on measuring whether the current framerate is within ±5% of the monitor’s refresh rate. This technique works well because it reverts to the non-vsync method if the rendering rate falls too far below the refresh rate.

Well, I didn’t think about that! Sorry about that :slight_smile:
I would wait to see if anyone else has a solution because no offense, but your’s seems a little to hackish. There has to be a better way!

The only problem I have with your solution is that well, vSync targets 60 FPS correct? So if your computer is to slow to even render at 60 FPS, then your code would fail, at least I think.

Of course, if you have vSync on and your computer can’t handle it, you should probably not even have it on in the first place, so my problem isn’t really relevant anymore… I think.

You could always adjust your scrolling code. The math behind your scroll code should have nothing to do with frame rate what-so-ever. Common technique is delta timing, making movement independent of frame rate by multiplying your math by the time between frames. If you still get issues after that, try flooring your values to Integers when you draw, making them line up with individual pixels nicely.

my two cents.

Damn I totally forgot about this. Definitely, your code should not be dependent on vSync, it should be dependent on the frame rate. Whether or not you have vSync enabled is irrelevant. Your code should not be hard coded to only scroll this way if vSync is enabled, and the other if it isn’t. Just multiply your transition variables by the delta. I don’t know if I would floor the transitions to Integers though, because then you would have a more “jumpy” affect. It might not be super noticeable on a fast computer, but on a slower computer, you’ll see every single pixel transition, which wouldn’t be good.

Edit: Modified for clarity.

@zngga: If you want scrolling to be perfectly smooth, simple delta timing isn’t good enough. It will result in an inconsistent number of pixels scrolled per frame. Calculating the distance based upon the time delta then flooring/rounding the result works well, but the result is highly dependent upon the current framerate, since it is functionally very similar to scrolling a specified number of pixels per frame (assuming the framerate stays constant). Either way, absolutely smooth scrolling requires moving the same number of pixels per screen refresh; this makes scrolling speed partly to directly proportional to the current framerate while using this technique. And thus, it is only a good idea if the FPS meets four conditions: 1) not too high, 2) not too low, 3) stable, 4) in sync with the monitor’s refresh rate to prevent strobe/tearing effects. VSync ensures that all of these conditions are typically true (assuming the framerate does not drop from rendering issues).

This kind of perfectly smooth scrolling is much more apparent in a low-res pixelated 2d game engine, so it isn’t much of an issue in higher-res or 3d games. Perhaps you haven’t seen just how smooth it can look while using this technique, but it is very impressive. It makes purely delta-based timing look horrible in a side-by-side comparison.

The downside is that if you attempt this kind of scrolling without vsync, it creates an extremely distracting strobe-like effect, in addition to the typical screen tearing issues.

@opiop65: I agree that it is “hackish”… I suppose I will have to give up on detecting actual vsync status since there seems to be no airtight way to do it.

Instead, I will make “smooth scrolling” a graphics option within my game engine, off by default, and recommend its use only if vsync is enabled. Technically illiterate end-users might wind up turning it on without knowing about vsync, and the smooth scrolling effect will have distracting tears and jerks… but if they notice it looks bad, hopefully they will be smart enough to turn it back off.

Wait… how is there no way to detect if vSync is on or not? Just create a boolean and set it to true when you enable it. Why can’t you just do that? Or am I missing something blatantly obvious here?

You can’t just “enable” vsync, you have to create a bufferstrategy and that object internally decides whether to use it or not based on whether it’s possible under the current conditions. There seems to be no way to simply ask it whether it’s using vsync or not.

Oh, you’re using Java2D. Well then, just restart the game with a new bufferstrategy and enable vSync? Then set the boolean to true? Honestly, I have no idea. I’m just throwing things out there.

Whether vsync works or not just depends upon the conditions of the computer that’s running the program. Some people have vsync forced to off in their graphics driver options; some computers just don’t support it under certain circumstances. There’s no perfect way to predict or observe the outcome from within the code (using java2d at least). In the end this just amounts to an extra graphics option that I wanted to automatically enable if vsync was detected, but now I’ll have to leave that up to the end user.

I am currently using java2d; perhaps LibGDX has better vsync support? I somehow doubt it, but I’d be pleasantly surprised if it were true. I do plan to switch to it at a certain point, anyway.

@Grimmov: My friend, welcome to frame clamp loops! (it is what I call them anyway)

I assume that your run loop functions similar to this:

  • Gather input
  • Update the scene
  • Render the scene
  • repeat

What you want to do is remove the frame rates dependence on how fast the game can update. So instead of the above do something similar to this:

target frame rate = 60 frames
time between frames = 1 second / target frame rate

render time = 0;
delta time

start loop

while render time < time between frames,
record the current time
gather user input
update the scene(using delta)
subtract the recorded time from the current time and set delta equal to it
then add delta to render time
As soon as render time becomes equal to, or greater than, time between frames this loop ends and you move on to rendering

render
set render time = 0

repeat

Now your loop keeps updating the scene (doing calculations, gathering user input, and running all your math) until you need to render. Then you render, reset some variables and repeat the process.

obviously the above is not code, but when you implement this right, you get rock solid frame rates, and a loop that preforms the same on most computers (I only say most because there are some dinosaurs out there)

This is a fairly common approach to your problem (not the vsync part, but the reason you think you HAVE to have vsync)
If I wasn’t so lazy I would link you to a good post from this forum on game loops, but for now I hope this is helpful.

I’ve seen it referred to as CPU sync (as opposed to vsync). It clamps framerate to the target interval by waiting to draw each graphics update. I prefer not to use this method, as non-vsync users can actually get a better experience by allowing graphics to update as quickly as possible, even if they are not rendered, as the frame that does get rendered will be more up-to-date this way. It also interferes with vsync because the CPU sync is not perfectly matched to the vsync rate.

I am trying to attain a level of smoothness that goes beyond the typical methods. In the end, I found that the best appearance was achieved by simply using delta-based scrolling combined with rounding the result to the nearest integer. My main problem with this was that extremely high FPS would cause the result to round down to 0. However, I added a check for this and use the non-rounded value when this happens, and all is well. Effectively it is a hybrid of my previous (vsync and non-vsync) approaches that works well regardless of vsync status, however, it only exhibits the actual smooth scrolling effect while vsync is enabled.

If anyone is curious, I’ve actually gone so far as to use a concurrent rendering thread while waiting for vsync to finish in my quest for smoothness… This basically gives me the benefits of double buffering (every graphics update is pushed to the screen, necessary for smooth scrolling) and triple buffering (game state and certain graphical updates can continue mid-frame) at the same time. Of course, concurrency leads to nightmares, but after a few days studying the concepts I’ve gotten a handle on it.

Grimmov; the answer is to use a better API.

Java2D has many limitations; its inability to query hardware capabilities is one of the big ones.

If you want to have smoother movement, don’t use vsync. vsync is just a technique where the renderer limits the framerate to the refresh rate of the monitor so you don’t waste the cpu cycles by doing unnecessary renders which enables more cpu for logic, however this is not required for us. The best thing is to forget about the vsync and do as many renders you can do after one logic and keep constant update rate. An example would be


private void gameLoop()
{
    long now = getCurrentTime();
    long gameTime = getCurrentTime();

    long updatesPerSecond = 60;
    long updateRate = updatesPerSecond / 1000;

    long maxFrameSkips = 2;
    long skippedFrames = 0;

    while (gameRunning)
    {
        skippedFrames = 0;
        now = getCurrentTime();

        while (now + updateRate > gameTime && skippedFrames <= maxFrameSkips)
        {
            update();
            gameTime += updateRate;

            skippedFrames++;
        }

        render();
    }
}

This game loop prefers game updates first while doing some frameskipping. After the updates are done, it keeps re-drawing the scene until the next update is required. This gives me a large frame-rate on my pc ranging from 750-790 with Java2D. If you really want to use vsync, just query the refresh rate of the monitor and limit the frame-rate. For example, this gameloop does this.


private void gameLoop()
{
    long now = getCurrentTime();
    long gameTime = getCurrentTime();

    // Query the monitor refresh rate
    int refreshRate = GraphicsEnvironment.getLocalGraphicsEnivironment().getDefaultScreenDevice.getRefreshRate();

    // update rate
    long updatesPerSecond = refreshRate == DisplayMode.UNKNOWN_REFRESH_RATE ? 60 : refreshRate;
    long updateRate = updatesPerSecond / 1000;

    while (gameRunning)
    {
        now = getCurrentTime();

        while (now + updateRate > gameTime)
        {
            // Use the updateRate as the delta time.
            update(updateRate);
            render();

            gameTime += updateRate;
        }
    }
}

This only does required frames.

This is the most correct answer in the thread… I will do this at some point, but I wanted to get the basics of my game sorted in Java2D before switching to a better API, so that I can understand the differences.

@SHC: as I have explained in depth in this thread, the method you have presented is insufficient for my purposes. Vsync with double buffering is the only way to ensure that each frame is rendered to the screen in sequence without skips, which is the only way to perfectly scroll by the same number of pixels per displayed frame. As I mentioned before, “CPU-sync” has its own limitations.

Nope. The main point of V-sync is to prevent the GPU from updating the front buffer while it is being sent to the monitor, causing a visible tear where it started reading from the new frame. That it limits the FPS to the refresh rate of the monitor is just a side effect that can be worked around by using triple buffering.

[quote=“SHC,post:17,topic:44696”]
There’s a bug in your code. [icode]long updateRate = updatesPerSecond / 1000;[/icode] should be [icode]1000 / updatesPerSecond;[/icode], but it still won’t be accurate due to integer rounding resulting in 16 instead of 16.6666… causing an update rate of 62,5 instead of 60. Use nano time instead or floating point values.

The first game loop is decent for when a computer can render at <=60 FPS, but there’s no point in re-rendering the exact same frame multiple times. If you only have 60 unique frames each second to render, why render at 750 FPS in the first place?

The second game loop has even more problems.

  • You should probably not base the update speed on the screen’s refresh rate. Sure, it’ll help with getting enough unique frames each second, but things like physics may behave very differently depending on the update rate. Example: I run my monitor at 90Hz, but I can run it at as low as 29Hz, which is a 3x difference in the time step.
  • It’ll start slowing down if the computer can’t maintain 60 FPS, and if the load lessens afterwards it’ll run as fast as it can until it catches up again.
  • Although you’re not needlessly rendering duplicate frames, you’re instead spinning until it’s time for an update. That’s a 100% CPU load on one core for no good reason.

For Java2D I’d probably recommend the first game loop since it works well in the most important cases, although it could be improved to only render when there’s anything new to render at all. The ultimate solution which handles both low and high frame rates while still having a fixed time step is to use interpolation when rendering to generate unique frames. Probably a bit overkill for a simple 2D game though.

You can read more about game loops in this excellent article: http://gafferongames.com/game-physics/fix-your-timestep/

@theagentd
Thanks for a long informative post. Also thanks for pointing out that bug, I wrote that post during the college lab and I’m being worried about the chemistry assignment I didn’t complete. That ate my mind. I too wondered about the more number of updates than the required, thank you so much for explaining. And finally the article you referenced is very more informative. +1. Why didn’t I find that before ???