Hi,
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 texture(warning, white text on transparent background).
http://stud4.tuwien.ac.at/~e0526822/gl.png http://stud4.tuwien.ac.at/~e0526822/gdi.png
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.
Hi, A few additions to my previous mail - Why can't I think about all this when I'm writing the mail.
A GDI engine won't help Direct3D applications because the gdi engine still operates in system memory. It would not avoid the need of downloading from opengl and uploading again. A GDI engine can help DirectDraw Games(although this can be improved in wined3d too), and other apps making heavy use of DIB sections with direct access. DDraw can be improved by moving the rendering from wined3d's code to the X server. This would shift the expensive opertions away from GetDC to surface locking.
And my font manager: I'm aware that I can't store the font Handle, I have to store the LOGFONT structure, together with the pen settings. This was just a quick and dirty way which works for most apps. But in theory the font handle can be destroyed and another one recreated with the same value but different settings.
On 28.05.2007 22:23, Stefan Dösinger wrote:
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.
One trick I've seen (in CEGUI) is to use one font texture per Unicode plane. So the page you attached would be the texture for plane 0 (ie ISO-8859-1).
Also, why display lists? Each character is a quad. You could draw the text from simple quads, with some buffering to reduce overhead.
-f.r.
Am Dienstag 29 Mai 2007 00:31 schrieb Frank Richter:
On 28.05.2007 22:23, Stefan Dösinger wrote:
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.
One trick I've seen (in CEGUI) is to use one font texture per Unicode plane. So the page you attached would be the texture for plane 0 (ie ISO-8859-1).
Also, why display lists? Each character is a quad. You could draw the text from simple quads, with some buffering to reduce overhead.
To cache the texture coordinate calculations, and in the hope that the driver can cache something internally. The red book also recommends the use of display lists for this, and display lists are fairly easy to call and record.
As for the unicode planes, yes, that's my plan, but just not implemented yet :-)