9

I'm using a WriteableBitmap to display images I process myself at around 20 frames per second.

This question (WPF: More efficient way of displaying quickly-changing images?)
and this question (How to display quick-updating images without large memory allocation?)
indicate that the best way to do this is by using a WriteableBitmap.

The documentation for WriteableBitmap indicates that calling WritePixels() on the UI thread will cause the rendering thread to redraw the image:

MSDN documentation:
The UI thread writes content to the back buffer. The render thread reads content from the front buffer and copies it to video memory. Changes to the back buffer are tracked with changed rectangular regions.

< snip / >

When updates are sent to the rendering thread, the rendering thread copies the changed rectangles from the back buffer to the front buffer. The rendering system controls this exchange to avoid deadlocks and redraw artifacts, such as "tearing".

I process my images on a background thread, then use Dispatcher.BeginInvoke() to call WritePixels(), to ensure that WritePixels() is called on the UI thread.

I'm finding that tearing still occurs with WriteableBitmap, and in the application I'm working on, it looks awful (its a medical imaging application). Is there anything I can do?

Community
  • 1
  • 1
Rob
  • 25,984
  • 32
  • 109
  • 155
  • After so many years....did you fixed this problem? – qakmak Mar 23 '15 at 10:51
  • @qakmak, it's hard to remember back that far, but I believe that moving to a more modern OS was the answer. See the accepted answer. – Rob Mar 23 '15 at 14:40
  • This answer not good enough for me. but still thank you – qakmak Mar 25 '15 at 18:03
  • Not sure you're going to get a better answer than that, unfortunately. All signs point to it being an OS-level issue. – Rob Mar 26 '15 at 13:09

3 Answers3

5

There was a lot of work put into WriteableBitmap to avoid tearing, but on some system configurations this is unavoidable. This mostly will happen on Windows XP or Vista w/ Aero (DWM) turned off.

  • We are running on Windows XP. I never thought about the OS being the problem, but it makes perfect sense - WPF apps that I write for fun at home run orders of magnitude better on Vista and Windows 7 than they do on XP. Just out of curiousity, how do you know about that? – Rob Jun 30 '09 at 15:11
  • I've done a lot of work with video in WPF so some knowledge just comes with the territory and with face palms. Not sure what the technical reasons are, but Vista w/ Aero on, ensures (mostly) that your WPF application draws at the same hertz as your video card, therefore no tearing. XP seems to be hit or miss depending on video card and drivers. Many people think that Aero/DWM slows the computer down, but this is incorrect. It greatly hinders performance all around. –  Jul 01 '09 at 20:46
1

While you are calling WritePixels() you may be overwriting your bitmap. Using Dispatcher.Invoke() rather then BeginInvoke() might help.

Ray
  • 2,974
  • 20
  • 26
  • I concur. BeginInvoke() is asynchronous. Use Invoke() and it should synchronize nicely (though you might notice lag). – apandit Jun 26 '09 at 19:23
  • No dice - same tearing when using Invoke() instead of BeginInvoke() :-( – Rob Jun 26 '09 at 19:39
  • WritePixels is supposed to lock the back buffer which prevents the render thread from copying a partial back buffer to the front buffer (hence causing tearing). BeginInvoke vs Invoke *shouldn't* make a difference based on the documented behavior of WritePixels. – James Schek May 03 '11 at 18:07
0

I know this is an old thread but we had exactly the same issue and in our case it was caused by calling our update display method using Dispatcher.BeginInvoke - the moment we changed to Dispatcher.Invoke it cleared up instantly.

Peter Jarrett
  • 115
  • 1
  • 10