Windows Mobile 6.5 Raw Display Buffer APIs
Rendering high-performance graphics, games, and video playback on
Windows Mobile 6.5 required developers to bypass standard Graphics
Device Interface (GDI) rendering pipelines to minimize latency and
overhead. In native C++, developers relied on a handful of specialized
interfaces to gain direct, raw access to display buffers: DirectDraw,
the driver-level GETRAWFRAMEBUFFER escape code, and legacy
Game API (GAPI) implementations. This article examines these low-level
APIs, detailing how they provided direct linear frame buffer pointers
and how they functioned within the Windows CE 5.2 architecture
underlying Windows Mobile 6.5.
DirectDraw (DirectX for Windows CE)
DirectDraw was the official, Microsoft-recommended native C++ API for
hardware-accelerated 2D graphics and direct video memory manipulation on
Windows Mobile 6.5. It was exposed via COM-style interfaces declared in
ddraw.h.
To access the raw display memory using DirectDraw:
- Initialize the DirectDraw object via
DirectDrawCreate(). - Set the cooperative level to full-screen or normal using
IDirectDraw::SetCooperativeLevel(). - Create a primary surface representing the physical display via
IDirectDraw::CreateSurface(). - Call
IDirectDrawSurface::Lock()to obtain a direct pointer to the video memory buffer. - The resulting
DDSURFACEDESCstructure returned thelpSurfacemember (a linear pointer to raw pixel data) along with the pitch/stride of the display line. - Once drawing finished, calling
IDirectDrawSurface::Unlock()released the hardware lock, allowing the screen to update.
DirectDraw took advantage of hardware acceleration if supported by the original equipment manufacturer (OEM) display driver, while still offering a software emulation fallback.
GDI ExtEscape:
GETRAWFRAMEBUFFER
Because DirectDraw support varied across OEM devices,
high-performance multimedia applications (such as media players and
console emulators) frequently utilized a native driver backdoor through
the GDI ExtEscape function.
Developers queried the display driver using the
GETRAWFRAMEBUFFER control code:
#define GETRAWFRAMEBUFFER 0x00020001
struct RawFrameBufferInfo {
WORD wFormat;
WORD wBPP;
VOID *pFrameBuffer;
LONG lStride;
LONG lCx;
LONG lCy;
};
HDC hdc = GetDC(NULL);
RawFrameBufferInfo rfbi = { 0 };
if (ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(rfbi), (LPSTR)&rfbi) > 0) {
void* pBuffer = rfbi.pFrameBuffer; // Direct linear pointer to screen memory
long stride = rfbi.lStride;
}
ReleaseDC(NULL, hdc);If the underlying display driver supported this call, it returned the
physical base address or a mapped virtual pointer
(pFrameBuffer), the bits per pixel (wBPP), and
the scanline stride (lStride). This bypassed the entire
window manager and compositor, allowing uninterrupted, blisteringly fast
writes directly to hardware memory.
Game API (GAPI)
The Windows Mobile Game API (gx.h, linked with
gx.lib) was Microsoft’s original raw access API introduced
in early Pocket PC systems.
GAPI provided a simple procedural C-style interface:
GXOpenDisplay(): Initialized the display for exclusive graphics mode.GXGetDisplayProperties(): Populated aGXDisplayPropertiesstruct containing the linear display pointer (cbxPitch,cbyPitch, and screen dimensions).GXBeginDraw(): Locked the display buffer and returned the write pointer.GXEndDraw(): Released the display buffer to trigger the screen refresh.GXCloseDisplay(): Cleaned up the session.
By the release of Windows Mobile 6.5, GAPI was officially deprecated.
Most devices implemented GAPI as an emulation wrapper over DirectDraw or
GDI, which often degraded performance. However, legacy native C++
applications continued to use GAPI by deploying custom wrapper libraries
(such as GXOpen or PocketHAL) that redirected GAPI
calls into raw ExtEscape or DirectDraw implementations.
Software Framebuffers:
CreateDIBSection
When hardware display buffers were locked down or driver access was
restricted by OEM security policies, the standard fallback was
allocating an off-screen software frame buffer using
CreateDIBSection.
While this did not write directly to the screen's physical memory:
CreateDIBSection()provided a raw pointer (void** ppvBits) to an in-memory pixel array.- The application wrote raw pixel data into this memory array via native C++ pointers.
- The updated buffer was blitted to the display device context using
BitBlt()orStretchBlt().
Although not a true hardware frame buffer mechanism, it remained the standard fail-safe approach for native graphics code requiring deterministic memory layouts across every Windows Mobile 6.5 device.