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

  • vegemeister - Tuesday, August 6, 2013 - link

    >in fact, at higher framerates there is always a higher chance of tearing than at lower frame rates (at 300 FPS tears will happen every frame, whereas at 40 FPS, tears cannot possibly happen every frame -- the lower the frame rate, the less likely or often tearing occurs).

    With vsync off, effectively every rendered frame tears. The only time you render a frame and don't get tearing is if you get lucky and accidentally swap during vblank.
  • Schmide - Friday, June 26, 2009 - link

    Actually if you read PrinceGaz and my discussion.

    When vsinc is on, the rendering of the next frame actually starts immediately after the previous frame and would provide no delay as long as the rendering time was less than the current refresh rate.

    The only real cost is memory.
  • DerekWilson - Friday, June 26, 2009 - link

    When rendering time is more than refresh time, double buffering with vsync can incur up to almost two full frames of lag (~33ms) in addition to the frame time.

    with triple buffering, this will be reduced to at most one frame of lag (~16.7ms) but this is the worst case scenario for triple buffering. average case will absolutely be less than this. average case for double buffering without vsync will be equal to this for the first frame that started being drawn to the screen (before any tear that may or may not happen). average case for double buffering with vsync will always be higher than triple buffering.
  • SonicIce - Friday, June 26, 2009 - link

    if you think vsync with triple buffering has the same performance as double buffering then i feel sorry for you
  • PrinceGaz - Friday, June 26, 2009 - link

    Your explanation of double-buffering and enabling vertical-sync are certainly correct, but your explanation of how triple-buffering works is not how I understand it works (I've read a few articles on such things over the years, yeah... sad).

    I believe triple-buffering is as follows:

    You have three buffers: A (front-buffer), B (back-buffer), C (third-buffer or second back-buffer). 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.

    Your explanation is correct up until the point that all three buffers have a frame written to them, so A is currently being displayed, B has the next frame to be displayed, and C has just been filled with another frame. At that point, you say C is moved to B, and a new frame starts being rendered into C; in other words the card is constantly rendering frames to the two back-buffers as fast as possible and updating B at every opportunity. So that a recently completed frame is available in B to be moved to A at the vertical-refresh.

    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.

    The whole point behind triple-buffering was to prevent framerate slowdowns caused by stalling when using double-buffering with vsync at framerates BELOW the refresh rate, NOT to minimise lag caused by vsync with double-buffering at framerates ABOVE the refresh rate (slight lag when the card was churning out frames faster than the refresh-rate was not seen as a problem with vsync, but big framerate drops like from 55fps to 30fps when it couldn't keep up were a major problem worth fixing).

    It should be noted that there is no difference between the two methods (constantly updating the back-buffers like you say, or stalling once both are filled like I've read elsewhere) at framerates below the refresh-rate as the two back-buffers are never both filled; a frame will always be moved from B to A to be displayed, before the one being drawn to C is completed (which means it can be immediately be moved to B and work continued on another one to fill C).

    The difference is when the framerate is considerably higher than the refresh-rate. In your scenario, when the refresh occurs, the last frame the card has just rendered is displayed. At 100fps, that would be a frame completed no more than 0.01 seconds ago (because thats how quickly the card is churning out frames and pushing them into buffer B), meaning there is negligible lag (between 0 and 0.010 seconds).

    In my scenario, the new frame is one which began rendering two refreshes previous (it was rendered into C very quickly two refreshes back, moved to B at the last refresh, and at this refresh is finally moved to A and displayed). The lag is therefore always exactly two frames provided the card is capable of rendering a frame faster than the refresh-rate. At 60hz refresh the lag will therefore be a constant 0.033 seconds regardless of the framerate the card is capable of (provided it can maintain at least 60fps).

    Whilst the longer lag (0.033 vs 0-0.010) would be a disadvantage in some cases (your best option there is to use double-buffering with no vsync), it is a consistent lag which in most games will feel better. It also means your graphics-card isn't constantly producing frames many of which will never be seen.

    The only problem is I don't know who is right. What I've said happens is what I've read on several other sites over quite a few years. Your article today Derek is the first time I've heard of a triple-buffering which involves the card continually updating the back-buffers.
  • Touche - Friday, June 26, 2009 - link

    I agree. Every site and topic I've read about triple buffering said that it works like you've explained. That's why most people hate it. It does resolve framerate drop issues of DB+vsync, but introduces too much lag. I would really like Anandtech to check this and get back to us.
  • DerekWilson - Saturday, June 27, 2009 - link

    The problem and discrepancy come from the fact that MS implements render ahead in DX, and because the default is 3 frames people took this to be "triple buffering", but you could do 2 frame render ahead and no one is going to call it "double buffering" ...

    It's really a render queue rather than a page flipping method.

    This article describes what, when people are talking about page flipping, "triple buffering" should refer to. This is also the way OpenGL works when triple buffering is enabled.
  • Touche - Sunday, June 28, 2009 - link

    Have you seen this?

    http://msdn.microsoft.com/en-us/library/ms796537.a...">http://msdn.microsoft.com/en-us/library/ms796537.a...
    http://msdn.microsoft.com/en-us/library/ms893104.a...">http://msdn.microsoft.com/en-us/library/ms893104.a...
  • DerekWilson - Wednesday, July 1, 2009 - link

    What they are showing is 1 frame render ahead with vsync. In MS DX terms, this is a flip chain with 2 back buffers and a present interval of one.

    This is them calling it triple if uses three total buffers. This is still a flip queue and should be referred to as such to avoid confusion.
  • DerekWilson - Saturday, June 27, 2009 - link

    Actually, I need to clarify and say that this is my understanding of the way triple buffering with OpenGL works under windows at this time.

Log in

Don't have an account? Sign up now