Accessing the Frame-Buffer Directly

You can directly access surface memory in the frame-buffer or in system memory by using the IDirectDrawSurface3::Lock method. When you call this method, the lpDestRect parameter is a pointer to a RECT structure that describes the rectangle on the surface you want to access directly. To request that the entire surface be locked, set lpDestRect to NULL. Also, you can specify a RECT that covers only a portion of the surface. Providing that no two rectangles overlap, two threads or processes can simultaneously lock multiple rectangles in a surface.

The Lock method fills a DDSURFACEDESC structure with all the information you need to properly access the surface memory. The structure includes information about the pitch (or stride) and the pixel format of the surface, if different from the pixel format of the primary surface. When you finish accessing the surface memory, call the IDirectDrawSurface3::Unlock method to unlock it.

While you have a surface locked, you can directly manipulate the contents. The following list describes some tips for avoiding common problems with directly rendering surface memory:

·Never assume a constant display pitch. Always examine the pitch information returned by the IDirectDrawSurface3::Lock method. This pitch can vary for a number of reasons, including the location of the surface memory, the type of display card, or even the version of the DirectDraw driver. For more information, see Width and Pitch.

·Make certain you blit to unlocked surfaces. DirectDraw blit methods will fail, returning DDERR_SURFACEBUSY or DDERR_LOCKEDSURFACES, if called on a locked surface. Similarly, GDI blit functions fail without returning error values if called on a locked surface that exists in display memory.

·Limit your application's activity while a surface is locked. While a surface is locked, DirectDraw often holds the Win16Lock so that gaining access to surface memory can occur safely. The Win16Lock serializes access to GDI and USER, shutting down Windows for the duration between the IDirectDrawSurface3::Lock and IDirectDrawSurface3::Unlock calls. The IDirectDrawSurface3::GetDC method implicitly calls IDirectDrawSurface3::Lock, and the IDirectDrawSurface3::ReleaseDC implicitly calls IDirectDrawSurface3::Unlock.

·Copy aligned to display memory. Windows 95 uses a page fault handler, Vflatd.386, to implement a virtual flat-frame buffer for display cards with bank-switched memory. The handler allows these display devices to present a linear frame buffer to DirectDraw. Copying unaligned to display memory can cause the system to suspend operations if the copy spans memory banks.

Locking the surface typically causes DirectDraw to take the Win16Lock. During the Win16Lock all other applications, including Windows, cease execution. Since the Win16Lock stops applications from executing, standard debuggers cannot be used while the lock is held. Kernel debuggers can be used during this period.

If a blit is in progress when you call IDirectDrawSurface3::Lock, the method will return immediately with an error, as a lock cannot be obtained. To prevent the error, use the DDLOCK_WAIT flag to cause the method to wait until a lock can be successfully obtained.