问题
When resizing down in DirectX I noticed a flicker along the bottom/right edges.
If you fix the size of the swapchain (in red), and set the win32 background to green you will get the following on a resize down:
It appears that the window size lags behind the mouse position ("Drag Rectangle") but the area DirectX fills (in red and black) matches the Drag Rectangle, with the remainder to be painted with the window background color (green).
The DirectX Utility Toolkit (DXUT) didn't have this problem. Experimenting with their settings I found that setting DXGI_SWAP_CHAIN_DESC::SwapEffect = DXGI_SWAP_EFFECT_DISCARD
would just paint the screen green (the window background color) during a sizemove. I assume that DXUT has their own special handling for when win32 enters a modal sizemove loop in order to display DirectX content during a sizemove.
DXGI_SWAP_EFFECT_DISCARD
is part of the old blit mode presentation model. Notably it cant have DXGI_SWAP_CHAIN_DESC1::Scaling = DXGI_SCALING_NONE
the scaling must be stretched to the window size. So my best guess is this behavior is due to the implementation of the flip presentation model (it flips a rectangle too small (black) and then covers by painting the rest green).
Does anyone know how to stop the win32 background from showing?
Edit:
Thanks to IInspectable! I can confirm the WS_EX_NOREDIRECTIONBITMAP
extended style works: it stops the artifact from the win32 background showing
回答1:
I reproduced the exact same behavior when using CreateSwapChainForComposition()
with DirectComposition as I got using CreateSwapChainForHwnd()
.
This means that there are two path for pixels to get to the screen. The green pixels are going through the Redirection Surface. Hence, explicitly requesting WS_EX_NOREDIRECTIONBITMAP
prevents any drawing through a Redirection Surface stopping the win32 background from showing.
The other path is the flip presentation behavior which is how the red and black pixels are get displayed. Hence, not using flip presentation when resizing also stops the win32 background from being shown.
There must be a bug with DWM: when there is a Redirection Surface, the clipping to prevent the swapchain's contents extending past the window is smaller than the redirection surface allowing it to be seen along the bottom/right edges.
There are two observations of interest:
- when using
WS_EX_LAYOUTRTL
or manually positioning aIDCompositionVisual
to the right edge of the screen withGetClientRect()
, the swapchains contents are correctly position, but still clipped. - when using
WS_EX_NOREDIRECTIONBITMAP
the window`s nonclient area lines up with the contents of the swapchain rather than the swapchains contents being clipped
These observations would seam to imply that the cause of the issue is that DWM is using it's prefered size for the window size sometimes and the size of the redirection surface othertimes.
来源:https://stackoverflow.com/questions/63096226/directx-resize-shows-win32-background-at-edges