I'm trying to render to a D3DImage about a second after user interaction by using a DispatcherTimer, but I'm getting a sporadic flicker (black frame). When rendering is immediately called upon receiving input, I do not have the flicker problem. The reason for the delay is to have an immediate fast render mode and a more expensive delayed quality mode.
When rendering on a background thread, the flicker was more frequent and tearing would also be present. I used a triple-buffered surface so main thread updates could be independent of the background rendering. Each frame is rendered in the background thread to a back buffer, which is then swapped with the intermediate buffer. Using a DispatcherTimer or similar, the main thread would update the D3DImage at a fixed interval by locking it, swapping the intermediate and front buffers, assigning the new front buffer pointer, setting the dirty region, and unlocking. Although I check for it, at no point has IsFrontBufferAvailable been false. According to the documentation, unlocking copies the assigned surface region to the D3DImage. I've been careful about locking appropriately so buffers on one thread are not touched by the other.
For reference, I'm using .NET 4.0/VS2010, DirectX Feb 2010, and an nVidia 260M.
When using .NET 3.5, I had noticed that the flickering occurred much more during WPF animations. I don't know if that is still an issue. There appears to be less flickering in general than with .NET 3.5, and I remember reading a post indicating some fixes had occurred with D3DImage.
I've noticed some differences in the amount of flicker when the time required to render a frame changes, for both main and background thread rendering. I wonder if D3D is not presenting to my surface when I think it is, in which case both D3D and WPF might be accessing it.
Does anyone have ideas about what might be happening or where I might look for more info?
Such kind of issues can be caused by so many cases. Could you please package the code in a small project and share it here, such as uploading it via sky driver? This can help us to reproduce the issue.
I have two suggestions:
1. Since the rendering via D3DImage will consume lots of resources and often not as fast as we expected, so it is better to decrease the frame rate(increase the interval of the timer). This will give the graphics more time to finish rendering.
2. Call some methods to refresh the WPF window manually, such as InvalidateVisual. It is possible that the two rendering systems are not synchronized.
Let me know if this does not help.
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
You need to synchronize the D3DImage updates with the Rendering of your WPF application.
Hook up to the render loop by using the 'CompositionTarget.Rendering' event. In this event handler, do your locking, adding dirty rect and unlocking.
Hope this helps.
- Proposed as answer by Steven Jeuris Monday, October 18, 2010 11:02 AM