Istrebitel's picture

Two problems with VSync

Greetings!

I have two different problems with VSync. I'm making a simple app that has to show an image to the user (string of text) for a very small amount of time. Basically, 1 frame on 60hz monitor. Obviously, this is a very simple program and if I unlock fps (VSync off), It's getting 130 FPS on an old Compaq 6510b notebook or 200 (max) on my PC.

In order to test both if the VSync is working, and if the 1 out of 60 frames is actually showing, I've made at test program. All relevant code is in the rendering event :

protected override void OnRenderFrame(FrameEventArgs e)
        {
            frames++;
            time_elapsed += e.Time;
 
            if (time_elapsed >= ttl_max) // const double ttl_max = 1.0
            {
                double fps = frames / time_elapsed;
                SetText(fps.ToString());
 
                frames = 0.0;
                time_elapsed = 0.0;
            }
 
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            if (frames == 0.0)
            {
                GL.MatrixMode(MatrixMode.Projection);
                GL.LoadIdentity();
                GL.Ortho(0, Width, Height, 0, -1, 1);
 
                GL.Enable(EnableCap.Texture2D);
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
 
                GL.BindTexture(TextureTarget.Texture2D, text_texture);
 
                GL.Begin(BeginMode.Quads);
 
                GL.TexCoord2(0f, 0f); GL.Vertex2(0f, 0f);
                GL.TexCoord2(1f, 0f); GL.Vertex2(1920, 0f);
                GL.TexCoord2(1f, 1f); GL.Vertex2(1920, 1200);
                GL.TexCoord2(0f, 1f); GL.Vertex2(0f, 1200);
 
                GL.End();
            }
 
            this.SwapBuffers();
        }

Basically, I'm measuring FPS, and outputting it once per second. Of course, in the OnLoad of the GameWindow I've set VSync property to On.

Here are my two problems:

1) It doesn't work on some machines even if it is enabled in the application and allowed in drivers.

I've tested it on some PC's with different graphics cards and OS'es (XP and 7). On all of them, VSync worked , meaning, despite running the window with 200 target fps, It was showing 60 (or 75 for a 75Hz monitor). Now, am testing on a Compaq 6510b notebook (it has mobile intel 965 express chipset for a graphics cart) and it doesn't - it shows ~130 FPS. I've double checked, and in the OpenGL settings of the driver (Intel Graphics Media Accelerator Driver for mobile) it's set to default setting - which is Off for Asynchronous Flip - which means, Vsync is enabled (http://www.intel.com/support/graphics/sb/CS-030506.htm Figure 3). However, I just CANNOT get Vsync to work.

What can I be doing wrong? Is there any way to debug this?

2) Frames get skipped despite Vsync being on and working

On the PC I'm testing, sometimes the frame is skipped! PC is a quite modern one, GTX460 video card and Intel i7 processor 3GHz 4cores, Win7 x64, with vsync off I get up to 700 FPS (somehow, even though I specify 200 as target, because that's the maximum allowed). So, I'm running the app and I'm noticing every once in a while, about 2 seconds (instead of 1) pass between text flashing on the screen. Basically, sometimes a frame is skipped!

How can this be happening?

From what I understand, Vsync means that every buffer flip waits until the monitor requests the next frame, and flips right after. Therefore, there is absolutely no chance for any single "flipped" image NOT to appear on the monitor, whatever the frame rate (even if the frame rate would slow to a crawl due to a busy scene, which is not the case because as I said, the PC is quite fast and the task is trivial). Because in order for the image not to ever appear, only one thing can happen: before it got sent to the monitor, another image took its place. But it cannot happen because of the Vsync!

So, what can allow it to happen?

Thanks in advance!


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Wow, thanks for the follow up, lots of information to digest.

I don't have an off-hand explanation for the difference between 1.0, 1.1-native and 1.1-sdl. The timing code between 1.0 and 1.1 is almost identical (one extra check to protect against broken non-monotonic clocks), and there is absolutely no difference between 1.1-native and 1.1-sdl. The biggest addition in 1.1 is the new input handling code. Could this be the root cause?

I will have to think about this for a while.

(I should add that erratic timing is *not* intended behavior, so I will try to get to the bottom of this.)

Edit: I'm still preparing release documentation and packages. You can always download the latest code here: https://github.com/opentk/opentk/archive/master.zip (just open OpenTK.sln, change the configuration to "Release" and build)

Istrebitel's picture

Well, this problem is hard to track for you, as you said, you only have windows via VM, and for me, because my current workplace PC is horribly borked (BSOD's and hang ups like every hour, faulty videocard or PSU, waiting for replacement). And because it requires staring at a blinking screen for minutes...

But I tried on different PCs, just to be sure this is not just my PC issue, and confirmed the above on at least two (my home PC - Win764, GTX560Ti etc, and another PC at work - XP32, some medicore graphics card) - confirmed, that is, the fact that frame skips do happen on 1.1, but not on 1.0 or 1.1+SDL.