[4/6] d3dx9: Implement ID3DXFont_GetDC

Tony Wasserka tony.wasserka at freenet.de
Wed Jun 17 13:52:08 CDT 2009


Stefan Dösinger schrieb:
> Am Wednesday 17 June 2009 18:29:57 schrieb Tony Wasserka:
>
>   
>> @@ -300,6 +301,12 @@ HRESULT WINAPI 
>>     
> D3DXCreateFontIndirectW(LPDIRECT3DDEVICE9 device, CONST D3DXFONT_
>   
>>      object->device=device;
>>      object->desc=*desc;
>>
>> +    object->hdc = CreateCompatibleDC(NULL);
>>     
> Device contexts are scarce resources, please avoid holding one all the time. 
> Instead, create it in GetDC and destroy it in ReleaseDC. Besides this, after 
> ReleaseDC the DC is supposed to be invalid - the only way to do this is to 
> destroy it.
> (Yes, I know that's broken in wined3d too. Needs fixing there as well)
>
> You'll also have to attach the DC to the font bitmap, or whatever you have, to 
> have it draw to the correct device. I think the current code means that the 
> DC will draw to the screen directly, which is maybe not what you want.
>
> If the font has a d3d surface underneath, you should use d3dsurface9::GetDC
>
>
>   
Hi, thanks for your comment
I must admit that I am not that experienced with GDI, but I think
creating the DC is inevitable:
The function ID3DXFont_GetGlyphData uses GetGlyphOutline (with
GGO_GRAY8_BITMAP, i.e. no drawing to screen or bitmap) to get the pixel
data of a specific glyph which is (manually) copied to an internal 
texture then. Thus, I'll need a DC whenever GetGlyphData is called. 1)
The handle to the DC returned by GetDC must always have the same value
(at least I think so, I'll test that tomorrow) and more important 2)
GetGlyphData is called once per Glyph in a string passed to DrawText,
which might be VERY often depending on the usage of the ID3DXFont
object. Because of that, DCs would need to be created and deleted very
often per frame (lateron maybe not as often as we're caching the
glyphs), so I think holding the DC all the time is better than creating
and deleting them that often (correct me if I'm wrong here).
By the way, ID3DXFont does not provide any ReleaseDC method, so there'd
also be quite a problem when to delete the DC again after it was created
in GetDC ;)

About the IDirect3DSurface/Texture9_GetDC approach: I also thought about
that (I even hoped it could solve the format conversion hell from the
texturing code), but it only supports a bunch of formats (not so bad as
I'm using A8R8G8B8 anyways), but no alpha channels, and without alpha
the fonts look ugly. Again, correct me if MSDN is just wrong documented
and the alpha channel does actually work well.

I'm not sure whether that explanation makes the first point about
ReleaseDC redundant - at least I don't understand it :D
I'm already calling DeleteDC in ID3DXFont_Release, that should be
enough, shouldn't it?


Best regards, Tony




More information about the wine-devel mailing list