Start of an opengl-based gdi driver

Stefan Dösinger stefan at
Mon May 28 15:23:39 CDT 2007


One of our remaining fundamental d3d problems is the slowness of 
IDirectDrawSurface7::GetDC(and d3d9). This call allows performing gdi 
operations on surfaces. Currently this is handled through downloading the 
opengl surface, performing the gdi operation, and uploading it again. This is 
slow, especially on render targets. On textures this is rarely used, and 
wined3d can better cache the texture. 

Most applications use it to render text text on the back buffer. Applications 
I have are the d3d7 sdk demos, Empire Earth, Prince of Persia 3D, Age of 
Empires 2. Sometimes it is also used to load textures with a BitBlt.

I have discussed two ways of solving this issue with alexandre. One was to 
tell the X server to perform the calls in opengl(EXT_texture_from_pixmap 
looked promissing), the other one was writing an opengl gdi driver in 
wined3d. The X server approach failed because there is just no API to get 
that handled, and EXT_texture_from_pixmap explicitly doesn't do that job, and 
even if there is a hacky way driver support will be bad. So I spent the last 
days to check how an implementation in wined3d would work - and here it is.

So far this driver handles only ExtTextOutW, and I only successfully used it 
with the directx sdk samples. ExtTextOut uses a Helper device context(normal 
gdi) to get the glyphs with GetGlyphOutline, loads it into an opengl 
texture(GL_ALPHA) and records 256 display lists to draw textured quads. So 
far no unicode support, no custom pens, but custom fonts work. I have 2 
screenshots of a dx7 sdk demo with classic getdc and the opengl driver(radeon 
M9, 1.6 ghz pentium M, 512 mb ram). There seems to be some parameter missing, 
the text is slightly displaced. Tex.gif(attached) is the created font 
white text on transparent background).

One problem of this approach is that the driver has to handle everything. 
However, I keep a DIB section of the size of the surface, and if I encounter 
some unsupported call I can print a FIXME, download from gl and call the dib 
section to do the job. After ReleaseDC the surface code has to upload it 
again. Its the slow old behavior, so we don't gain anything for unsupported 
calls, but its no loss either. So far most forward functions are missing, so 
the DIB driver refuses to initialize itself - Edit CreateDC in 
dlls/wined3d/gdi.c to activate it. ExtTextOut has an example how the 
forwarding looks like.

A big problem I still have are operations that involve 2 device contexts. 
Prince of Persia 3D(good test case for custom fonts) calls StretchBlit 
from/to my gl dc. So in X11drv one of the physdevs is a WineD3DSurfaceImpl * 
instead of a WINEX11DRV_PHSYDEV * - not good. So far I haven't found a way to 
let x11drv access my surface data, or enforce that my function is called, 
fetch the hdc from the x11 phsydev and call my fallback dc, or request the 
device's content from x11drv and handle the blit myself.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0034-WineD3D-Start-an-opengl-based-gdi-driver-for-improv.patch.bz2
Type: application/x-bzip2
Size: 6896 bytes
Desc: not available
Url :
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tex.gif
Type: image/gif
Size: 3202 bytes
Desc: not available
Url :

More information about the wine-devel mailing list