The Evils of Layered Windows
EDIT 1/8/2009: Microsoft improved layered windows performance with .NET 3.5 SP1 + Vista SP1 and XP SP1, rendering this post outdated.
One feature of WPF is the ability to have transparent/layered windows by setting a window’s AllowsTransparency property to “True”. Setting this property makes it possible to easily create non-rectangular and/or semi-transparent windows. Without it, irregularly shaped windows would be difficult to create. However, there is a hidden cost when setting AllowsTransparency=”True”.
To put it bluntly, performance is crappy. In WPF, there are two aspects to rendering. First, the scene is composed, then presented. On Vista, layered windows are composed in the hardware pipeline via DirectX, but because DirectX cannot present that surface and retain its alpha channel information, it acquires a surface with IDirect3DSurface9::GetDC and presents to the screen via GDI. On Windows XP, DirectX does not support IDirect3DSurface9::GetDC of a surface with alpha channels. GDI is not hardware accelerated on Vista.
So what the hell am I babbling about? Basically, WPF layered windows in XP are composed and presented entirely in software. On Vista, although layered windows are composed in hardware, they are presented in software. Translation: layered windows in WPF are slow.
But things get more complicated. On Vista, because the scene is composed in the hardware pipeline but presented in software via GDI, rendering a layered window will result in a chain of bit-blits from the video card, to system memory, back to video memory. What this means is rendering layered windows on Vista with a grahics card that has dedicated memory can actually be much slower than on machines with shared memory.
To see for yourself, invalidate the client area of a layered window by resizing or scrolling and watch the frame rate dip below 10 fps using Perforator. One caveat: Visual Profiler will report that a layered window is being rendered in hardware. On Vista this technically true, but the surface is still presented in software via GDI.
Bottom line, layered windows in WPF incur a big rendering performance hit, so try to avoid them if you can. Here are some rough guidelines to help you decide if layered windows are absolutely necessary:
Is the window relatively small?
Does your window have only a few UIElements?
Does your window have to be non-rectangular? If so, use the Win32 CreateRgn functions (I’ll talk more about this in a future post)
Tags: layered-windows, performance, transparency, WPF
You can comment below, or link to this permanent URL from your own site.