Background Color Artifact in Window's Composition Engine (DWM)

781 views Asked by At

Context from Kenny Kerr's blog:

Windows Vista introduced a service called the Desktop Window Manager. The name was and continues to be misleading. Think of it as the Windows composition engine or compositor. This composition engine completely changed the way application windows are rendered on the desktop. Rather than allowing each window to render directly to the display, or display adapter, every window renders to an off-screen surface or buffer. The system allocates one such surface per top-level window and all GDI, Direct3D and, of course, Direct2D graphics are rendered to these surfaces. These off-screen surfaces are called redirection surfaces because GDI drawing commands and even Direct3D swap chain presentation requests are redirected or copied (within the GPU) to the redirection surface.

At some point, independent of any given window, the composition engine decides it’s time to compose the desktop given the latest batch of changes. This involves composing all of these redirection surfaces together, adding the non-client areas (often called window chrome), perhaps adding some shadows and other effects, and presenting the final result to the display adapter.


Background from previous SO question (see pictures):

When resizing down in DirectX there is an artifact of the win32 background appearing at the right/bottom edges. This can be corrected by applying the WS_EX_NOREDIRECTIONBITMAP style. Since it doesn't matter whether the swapchain is smaller or larger than the window, it appears that without WS_EX_NOREDIRECTIONBITMAP the Composition Engine copies too small a rectangle to the Redirection Surface (because the window size lags behind the mouse position/"Drag rectangle").


Actual Question

However, WS_EX_NOREDIRECTIONBITMAP only works for top level windows and I'm trying to embed DirectX as a child window into WPF, and the artifact from the child window's background is still coming through. This leads me to some relate questions:

  1. (Optional) When when the swapchain is smaller than the window size, the remainder of the window is filled in black (see pictures). Is this a result of the copy from the swapchain to the Redirection Surface where the remainder of the destination stride (after the source width) is zeroed out?
  2. (Optional) How is the artifact from the win32 background appearing? Is the Redirection Surface filled with this color before the copy from the swapchain?
  3. (Optional) Are the Redirection Surfaces being resized every-time the window is resized?
  4. (Required) Does each child window have a Redirection Surface that in turn gets copied to the top level window's Redirection Surface. If not, how is the child's win32 background artifact appearing?
  5. (Required) Does this mean that the frame rate a win32 window embedded into WPF is limited to WPF's variable frame rate? (The purpose of embedding a DirectX window into WPF was to get a constant 60fps frame rate)
1

There are 1 answers

0
Tom Huntington On BEST ANSWER

What I missed was that there are two paths for pixels to get to the screen

  1. through a Redirection Surface
  2. through the Flip Presentation model

Without WS_EX_NOREDIRECTIONBITMAP the swapchain's contents get copied over the Redirection Surface's content. However, there is a bug when resizing down and the clipping to prevent the swapchain's contents, from extending past the window, clip too small a rectangle allowing the Redirection Surface to be seen. I realized this when I got the exact same behavior using CreateSwapChainForComposition() with DirectComposition as I got for CreateSwapChainForHwnd().

To answer my required questions: No, using the flip presentation model from a HwndHost does not limit your to WPF's refresh rate.