Time to stop talking about hwnd interop for a few moments and get back to some earlier questions. Lee asked what the mysterious renderer thread does. Good topic, and I happened to have some previously written material lying around on just that question. <g>
Avalon apps have one or more UI threads, which run message loops, aka Dispatcher.Run(). And there’s also the render thread, which is one per avalon process and should be completely hidden to the application author. The render thread is the one that actually talks to DirectX, the UI thread sends it a series of detailed instructions on what to draw, via what we call the “channel” interface. But the render thread doesn’t really know when to draw (because that notification comes in via the message loop). Interestingly, the actual Brush and Visual objects never leave the UI thread — the render thread doesn’t understand such complicated things.
So why did we put this on a separate thread at all? Well, a couple reasons. First, because the interface between the UI thread and render thread is also used for terminal services, which remotes things between machines. Essentially, the render thread runs on your local machine (mstsc.exe), and the UI thread runs on the server. This separation also enables some really powerful things that will be coming in the future (not sure whether that’s this version or the next) — we hope to make it so the render thread can act more independently of the UI thread — e.g., some animations (the so-called “independent animations”) don’t need any information from the UI thread, they could be done completely on the render thread and at a higher frame rate. Finally, although currently the application talks to the Longhorn Desktop Window Manager (DWM) via what is essentially a bitmap, in the future we may use the channel interface which enables a few new optimizations and rendering possibilities.