Rock on, Jer! That’s the coolest CornflowerBlue I’ve seen all day! :-p
(Can’t wait to see what you really cook up with this!)
> />>
>
Dr. WPF - Online Office at http://www.drwpf.com/blog/
More great questions! This lets me know where I’ve fallen short in the article. J
The window represents a very small perf cost. A few cycles are used to create it and then it consumes a small amount of memory. I wouldn’t worry about it too much. Afterall, if you open Spy++ at any given moment, you’ll likely see dozens of non-visible windows, all existing for different reasons.
In this scenario, the hwnd exists only because it is required by CreateDevice(). We never actually show the window or present our back buffer.
In a normal DX app, the window would be used for two purposes: 1) monitoring focus changes, and 2) determining where to render on the display.
Wrt focus, you’ve probably noticed that if you have multiple DX apps running simultaneously, the one in the foreground has much smoother animations than the windows in the background. DX monitors focus explicitly for this reason so that it can give preferential treatment to a device when it is associated with the foreground window.
Wrt rendering, the only time the hwnd would be used by DX for rendering is when the back buffer is transferred to the front buffer. This is called “presenting” the back buffer. We never do that in a D3DImage scenario.
This is the really cool part of how the whole D3DImage mechanism works... We render our scene to a custom surface, but we never present it. Instead, we let WPF copy the contents of that surface to its own render target. Then WPF will present its own back buffer (which now contains the composed scenes) to its front buffer.
The way this works on Vista is even cooler... Since we create a 9Ex device on Vista, WPF can actually use our device to create a temporary surface that is ”shared” with WPF’s surface (shared surfaces are only supported via 9Ex devices). It can then copy our surface to the shared surface via a hardware accelerated operation.
Clearly, this approach isn’t possible on a D3D9 device on XP. The XP approach involves using a lockable surface to do the copy. This still affords decent perf, but it’s not as performant as the shared surface approach (which, btw, is very similar to how the DWM works to get its excellent perf... you can think of the D3DImage architecture on Vista as a little microcosm of the DWM architecture... okay, there are some notable differences, but the surface sharing approach is similar J).
I digress... getting back to the hwnd question... If it really bothers you to have this almost useless window lying around, you do have another option. You could use the handle of the main window in your WPF app to create the D3D device. Just supply it to the unmanaged library via InitializeScene() or some such mechanism. In WPF, you can get the hwnd for a Window instance using (PresentationSource.FromVisual(this) as HwndSource).Handle (assuming “this” represents the Window or a Visual within it).
Was that a lot more information than you wanted? J
Quoting
"wpf-di...@googlegroups.com"
<wpf-di...@googlegroups.com>:
> So what is the proper
thing to do with the window you use for D3D content
> (the hWnd the
device is initialized with)? I might be reading your D3D
> example
incorrectly, but it seems you make a 0x0 window. Is it safe to say
>
the window should just be hidden? Are there any performance impacts with
> this? For instance, is D3D rendering to the surface and then to the
window
> also even though its hidden? Sorry I'm a little confused on
how some of
> this stuff works.
>
> -Jer
>
> BTW, if anyone uses that XNA backbuffer snippet, you will probably get
a
> LoaderLock exception. Loaderlocks are not *really*
exceptions...You can
> just hit play to continue on or just turn off
the loaderlock exceptions in
> VS.
>
>
>
> On Sat, Aug 9, 2008 at 6:35 PM, Dr. WPF <a...@drwpf.com> wrote:
>
>> Rock on, Jer! That's the coolest CornflowerBlue I've seen
all day! :-p
>>
>> (Can't wait to see what you *really* cook up with this!)