Triple Buffering

In some cases, that is, when the display adapter has enough memory, it may be possible to speed up the process of displaying your application by using triple buffering. Triple buffering uses one primary surface and two back buffers. The following example shows how to initialize a triple-buffering scheme:

// The lpDDSPrimary, lpDDSMiddle, and lpDDSBack are globally

// declared, uninitialized LPDIRECTDRAWSURFACE variables.

DDSURFACEDESC ddsd;

ZeroMemory (&ddsd, sizeof(ddsd));

// Create the primary surface with two back buffers.

ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |

DDSCAPS_FLIP | DDSCAPS_COMPLEX;

ddsd.dwBackBufferCount = 2;

ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);

// If we successfully created the flipping chain,

// retrieve pointers to the surfaces we need for

// flipping and blitting.

if(ddrval == DD_OK)

{

// Get the surface directly attached to the primary (the back buffer).

ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

ddrval = lpDDSPrimary->GetAttachedSurface(&ddsd.ddsCaps,

&lpDDSMiddle);

if(ddrval != DD_OK) ;

// Display an error message here.

}

You do not need to keep track of all surfaces in a triple buffered flipping chain. The only surfaces you must keep pointers to are the primary surface and the back-buffer surface. You need a pointer to the primary surface in order to flip the surfaces in the flipping chain, and you need a pointer to the back buffer for blitting. For more information, see Flipping Surfaces.

Triple buffering allows your application to continue blitting to the back buffer even if a flip has not completed and the back buffer's blit has already finished. Performing a flip is not a synchronous event; one flip can take longer than another. Therefore, if your application uses only one back buffer, it may spend some time idling while waiting for the IDirectDrawSurface3::Flip method to return with DD_OK.