Accessing Surface Memory Directly

Surface memory can be accessed directly by using the Surface.LockRectangle method. When this method is called, the rect parameter is a reference to a RectangleLeave Site structure that describes the rectangle on the surface to access directly. To request that the entire surface be locked, either call one of the Surface.LockRectangle overloads that do not take a RectangleLeave Site structure, or set the rect parameter to the dimensions of the entire surface. It is also possible to specify a RectangleLeave Site 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. Note that a multisample back buffer cannot be locked.

Depending on which Surface.LockRectangle method overload is called, the method returns either a GraphicsStream object or an ArrayLeave Site that describes the locked region. The method call returns the pitch value in the pitch parameter. When access to the surface memory is finished, the Surface.UnlockRectangle method should be called to unlock it.

While a surface is locked, its contents can be manipulated directly. The following list provides some tips for avoiding common problems associated with directly rendering surface memory.

  • Never assume a constant display pitch. Always examine the pitch information returned by the Surface.LockRectangle method. This pitch can vary for a number of reasons, including the location of the surface memory, the display card type, or even the version of the Microsoft Direct3D driver. For more information, see Width vs. Pitch.
  • Be sure to copy to unlocked surfaces. Direct3D copy methods will fail if called on a locked surface.
  • Limit the application's activity while a surface is locked.
  • A surface cannot be locked if it belongs to a resource assigned to the Pool.Default memory pool, unless it is a dynamic texture or was created using Device.CreateOffscreenPlainSurface. Back buffer surfaces, which can be accessed using the Device.GetBackBuffer and SwapChain.GetBackBuffer methods, can be locked only if the swap chain was created with the PresentFlag property of the PresentParameters structure set to PresentFlag.LockableBackBuffer.