What are Double Buffering, vsync and Triple Buffering?

When a computer needs to display something on a monitor, it draws a picture of what the screen is supposed to look like and sends this picture (which we will call a buffer) out to the monitor. In the old days there was only one buffer and it was continually being both drawn to and sent to the monitor. There are some advantages to this approach, but there are also very large drawbacks. Most notably, when objects on the display were updated, they would often flicker.


The computer draws in as the contents are sent out.
All illustrations courtesy Laura Wilson.


In order to combat the issues with reading from while drawing to the same buffer, double buffering, at a minimum, is employed. The idea behind double buffering is that the computer only draws to one buffer (called the "back" buffer) and sends the other buffer (called the "front" buffer) to the screen. After the computer finishes drawing the back buffer, the program doing the drawing does something called a buffer "swap." This swap doesn't move anything: swap only changes the names of the two buffers: the front buffer becomes the back buffer and the back buffer becomes the front buffer.


Computer draws to the back, monitor is sent the front.


After a buffer swap, the software can start drawing to the new back buffer and the computer sends the new front buffer to the monitor until the next buffer swap happens. And all is well. Well, almost all anyway.

In this form of double buffering, a swap can happen anytime. That means that while the computer is sending data to the monitor, the swap can occur. When this happens, the rest of the screen is drawn according to what the new front buffer contains. If the new front buffer is different enough from the old front buffer, a visual artifact known as "tearing" can be seen. This type of problem can be seen often in high framerate FPS games when whipping around a corner as fast as possible. Because of the quick motion, every frame is very different, when a swap happens during drawing the discrepancy is large and can be distracting.

The most common approach to combat tearing is to wait to swap buffers until the monitor is ready for another image. The monitor is ready after it has fully drawn what was sent to it and the next vertical refresh cycle is about to start. Synchronizing buffer swaps with the Vertical refresh is called vsync.

While enabling vsync does fix tearing, it also sets the internal framerate of the game to, at most, the refresh rate of the monitor (typically 60Hz for most LCD panels). This can hurt performance even if the game doesn't run at 60 frames per second as there will still be artificial delays added to effect synchronization. Performance can be cut nearly in half cases where every frame takes just a little longer than 16.67 ms (1/60th of a second). In such a case, frame rate would drop to 30 FPS despite the fact that the game should run at just under 60 FPS. The elimination of tearing and consistency of framerate, however, do contribute to an added smoothness that double buffering without vsync just can't deliver.

Input lag also becomes more of an issue with vsync enabled. This is because the artificial delay introduced increases the difference between when something actually happened (when the frame was drawn) and when it gets displayed on screen. Input lag always exists (it is impossible to instantaneously draw what is currently happening to the screen), but the trick is to minimize it.

Our options with double buffering are a choice between possible visual problems like tearing without vsync and an artificial delay that can negatively effect both performance and can increase input lag with vsync enabled. But not to worry, there is an option that combines the best of both worlds with no sacrifice in quality or actual performance. That option is triple buffering.


Computer has two back buffers to bounce between while the monitor is sent the front buffer.


The name gives a lot away: triple buffering uses three buffers instead of two. This additional buffer gives the computer enough space to keep a buffer locked while it is being sent to the monitor (to avoid tearing) while also not preventing the software from drawing as fast as it possibly can (even with one locked buffer there are still two that the software can bounce back and forth between). The software draws back and forth between the two back buffers and (at best) once every refresh the front buffer is swapped for the back buffer containing the most recently completed fully rendered frame. This does take up some extra space in memory on the graphics card (about 15 to 25MB), but with modern graphics card dropping at least 512MB on board this extra space is no longer a real issue.

In other words, with triple buffering we get the same high actual performance and similar decreased input lag of a vsync disabled setup while achieving the visual quality and smoothness of leaving vsync enabled.

Now, it is important to note, that when you look at the "frame rate" of a triple buffered game, you will not see the actual "performance." This is because frame counters like FRAPS only count the number of times the front buffer (the one currently being sent to the monitor) is swapped out. In double buffering, this happens with every frame even if the next frames done after the monitor is finished receiving and drawing the current frame (meaning that it might not be displayed at all if another frame is completed before the next refresh). With triple buffering, front buffer swaps only happen at most once per vsync.

The software is still drawing the entire time behind the scenes on the two back buffers when triple buffering. This means that when the front buffer swap happens, unlike with double buffering and vsync, we don't have artificial delay. And unlike with double buffering without vsync, once we start sending a fully rendered frame to the monitor, we don't switch to another frame in the middle.

This last point does bring to bear the one issue with triple buffering. A frame that completes just a tiny bit after the refresh, when double buffering without vsync, will tear near the top and the rest of the frame would carry a bit less lag for most of that refresh than triple buffering which would have to finish drawing the frame it had already started. Even in this case, though, at least part of the frame will be the exact same between the double buffered and triple buffered output and the delay won't be significant, nor will it have any carryover impact on future frames like enabling vsync on double buffering does. And even if you count this as an advantage of double buffering without vsync, the advantage only appears below a potential tear.

Let's help bring the idea home with an example comparison of rendering using each of these three methods.

Index Digging Deeper: Galloping Horses Example
Comments Locked

184 Comments

View All Comments

  • Schmide - Friday, June 26, 2009 - link

    Nice analysis.

    "In my explanation I'm going to refer to any buffer swapping as copying from one buffer to another; how it is implemented by the hardware is irrelevant."

    I think you have to elaborate on what's a copy and what's a swap as they are very different operations. Copying locks both surfaces preventing the use of both and takes processing power, while swapping locks nothing and takes no processing power.

    In your explanation, you would have very different results if it was a copy or a swap.
  • PrinceGaz - Friday, June 26, 2009 - link

    I understand if the card is actually copying blocks of memory between fixed buffers that it would have a performance impact. Whether it is copying or swapping is irrelevant as to what I was trying to explain, which is why I said how it is implemented by the hardware isn't relevant. It's best just to assume that in reality it is swapping buffers, which is equivalent to an instantaneous copy/move.

    The only thing is I've now realised there is a third way triple-buffering could work, which is roughly halfway between the two methods I proposed; if both B and C have been filled at the vertical-refresh meaning the card has been stalled, B is discarded, C is moved to A to be displayed, and the card now starts rendering to B, then to C. Again that makes no difference when the framerate is below the refresh-rate but it allows the card to render at up to double the refresh-rate to reduce the lag to a minimum of one instead of two refreshes when conditions allow.
  • Schmide - Friday, June 26, 2009 - link

    Ok I get it.

    3 buffers A, B and C all fully renderable. The rendering goes as so:

    A is rendered and queued to become the primary on the refresh after it's completion.

    B begins rendering right after A is completed then queued to become primary the refresh after A or the next refresh after B completes.

    C begins rendering after B finishes rendering and queues as B was queued to A.

    repeat.

    The advantage being, when vsinc is on, instead of starting the rendering of the next surface after the swap, you start a rendering immediately on 3rd surface rather than wait for the current primary to become available after the swap.

    Makes sense.
  • DerekWilson - Saturday, June 27, 2009 - link

    This is a good explanation of render ahead ... it's different than using triple buffering for page flipping.
  • PrinceGaz - Friday, June 26, 2009 - link

    ooops, made a slight error in my lag calculations when framerate can exceed refresh-rate.

    Two frames ago (my method) is correct- 0.033 seconds always because that is how long two refreshes take at 60hz.

    Your method (constant back-buffer updating) will be between one and two frames ago, not zero to one frames like I said, so at 100fps the lag would actually be between 0.010 and 0.020 seconds, not 0 and 0.010 seconds like I said earlier.

    Sorry about that.
  • DerekWilson - Friday, June 26, 2009 - link

    Actually, this is precisely why I wanted to write this article.

    The technique you describe here:

    "The way I understand triple-buffering works is that once B and C both have frames rendered to them waiting to be displayed, the graphics-card then pauses until the vertical-refresh, at which point B is copied to A to be displayed, C is moved to B, and the card is free to start work on rendering a new frame to fill the now empty C. No frames are thrown away, and the card is not constantly churning out frames which won't be displayed."

    While it uses 3 buffers, is actually called render ahead. I'm talking about a page flipping method (which can actually be combined with render-ahead, but that's beyond the scope of this piece).

    The benefit of the DirectX render ahead approach (which can be up to 8 frames iirc), is that it incurs a higher potential latency in order to achieve much smoother action.

    If my framerate fluctuates a lot between high and low rates, it's possible that the game will feel "jerky." But using render ahead, I can essentailly cache up to X (the default is 3) quickly rendered frames so that the next long frametime I hit doesn't cause the monitor to keep showing the exact same image for multiple frames while it waits -- instead, if i have my 3 frames rendered ahead, if the frametime of my next frame is anything up to 50ms, my rendered ahead frames can be spat out, one after the other, sequentially until my 4th frame is ready. if frame rate goes back up after this, then i've successfully smoothed things out.

    the price is, of course, that high framerate means we will see lag because no frames are dropped.

    but this is not triple buffering.

    DirectX does not support actual triple buffering out of the box -- it has to be programmed by the developer. OpenGL does actually support triple buffering inherently as I described.

    I promise that the description I gave in the article is what triple buffering is supposed to be. calling render ahead triple buffering because the default uses 3 buffers has definitely caused a lot of confusion (especially when the wikipedia page cites this as a reason that render ahead is "an implementation" of triple buffering ... which is disingenuous in my mind).

    we don't, afterall, call anything that uses 2 buffers double buffering -- like if I use 2 MRTs while I'm rendering something, am I double buffering then? in the same sense that 3 frame render ahead is triple buffering then sure ... but not if we are talking about page flipping.

    ... so ...

    also, the lag between 0 and 1 frames that i was talking about is lag between the END of rendering the frame and when it is displayed. If frametime is taken into account, the input that generated that frame will have happened, at a maximum of (frametime + 16.67ms) ... so it could be longer ago than just one frame but not /because/ of triple buffering.



  • GreyMulkin - Friday, June 26, 2009 - link

    VSYNC for life!

    This article has convinced me that I only want to use double buffering + vsync. I despise tearing - your example of "only seeing it on fast turns" is disingenuous. When vsync is off, even games with simple graphics tear, everywhere. I find it distracting and undesirable. But I also don't want the input lag associated with being 1 more frame away from the action.

    "While enabling vsync does fix tearing, it also sets the internal framerate of the game to, at most, the refresh rate of the monitor (typically 60Hz for most LCD panels)."

    I see no problem with this. I'd much rather have the game running near a constant framerate than to have it bounce back and forth between high and low performance. Consistency is what I want.

    "This can hurt performance even if the game doesn't run at 60 frames per second as there will still be artificial delays added to effect synchronization. Performance can be cut nearly in half cases where every frame takes just a little longer than 16.67 ms (1/60th of a second). In such a case, frame rate would drop to 30 FPS despite the fact that the game should run at just under 60 FPS."

    Well, if your frames are taking longer than 16.67ms to render, then you're not actually rendering 60 fps. Duh! Longer rendering times mean lower framerates. If you don't like the framerate you're seeing, turn down some settings (resolution, quality, AA, AF, etc). Triple buffering won't fix the problem of render times which are too long for the desired framerate.
  • GreyMulkin - Friday, June 26, 2009 - link

    To elaborate on the "while enabling vsync..." thing. Vsync off usually makes the game try to run as fast (high fps) as possible which is generally recognized as a good thing. But because scenes differ in complexity, the frames rendered per second will vary wildy and that will affect input processing which is usually tied directly to fps. So what I don't want is the *feel* of the game, the smoothness of mouse movements, etc, to be affected.
  • MadMan007 - Friday, June 26, 2009 - link

    Depends upon the game. For online competitive FPS I disable vsync, for single player games or less twitchy ones I enable it. There's no poll option for this.
  • TonyB - Friday, June 26, 2009 - link

    I still use my 21" CRT, i run at 100hz refresh rate with vsync on w/ triple buffering.

    at 100hz, your input lag is only 10ms (1/100) compared to 16.6ms (1/60) not to mention i'm capped at 100 fps instead of 60fps.

    this is why i'm still using CRT instead of LCD.

Log in

Don't have an account? Sign up now