Note that there are some explanatory texts on larger screens.

plurals
  1. POHigh CPU load when changing background image of Canvas containing overlay elements
    text
    copied!<p>I am working on an Application that loads live video images from a camera and displays an overlay on top of said image. The Overlay does not change often so it can be considered as still. However it usually contains about 1,000 to 10,000 Lines. When the video image is updated there is a notable impact to the CPU load depending on whether the overlay is visible or not. The overlay does neither get invalidated nor changed, just the image behind it is changing.</p> <p>My setup is this:</p> <pre><code>&lt;Canvas&gt; &lt;Image/&gt; &lt;Canvas&gt; &lt;OverlayElement 1/&gt; &lt;OverlayElement 2/&gt; &lt;OverlayElement 3/&gt; &lt;.../&gt; &lt;/Canvas&gt; &lt;/Canvas&gt; </code></pre> <p>The Image's Source is a WriteableBitmap. Every time a new camera image (type byte[]) is available, the main Canvas' Dispatcher is invoked to write the image data by using WriteableBitmap.WritePixels().</p> <p>The inner Canvas contains all Overlay Elements, being - a contour (PolyLine) - a circle (Path with EllipseGeometry) and - a set of Rays (Path with one Figure containing LineSgements). The number n of Points in the contour equals the number of line Segments in the last mentioned Path. n is usually around 1,000 - 3,000.</p> <p>Depending on the count and length of Lines shown in the overlay the CPU load for showing a live image varies (increases if length or count go up) even if the overlay does not change. At some point this affects the frame rate and makes the program unusable. Line length is mostly correlated with line intersection, so maybe the Path is struggling to calculate it's fill area despite it is not painted?</p> <p>So how could I improve the performance here? What bugs me most is that even if the overlay does not change, the render time increases with it's primitive count. I would expect to have constant render time once the overlay has been drawn in it's last set state. What could I do to achieve that aside from rendering the whole overlay to a bitmap?</p> <p>I am also open minded for suggestions on how to get the byte[] onto the screen more efficiently. Just keep in mind this problem is part of a bigger Application and i cannot change all paradigms concentrating on how to get the image drawn.</p> <p>What I have tried so far:</p> <ol> <li><p>Override the OnRender() method of the inner Canvas, drawing the overlay myself. This works fine but has the performance issue that brings me here ;)</p></li> <li><p>Use Shapes (PolyLine, Ellipse, Path) as the inner Canvas' children to hold the overlay elements. This works, too. It is faster to redraw the overlay when it changes but on the other hand worsens the performance issue when updating the background image.</p></li> <li><p>Like 2., but use Freeze() on Geometries wherever possible. Has no or little performance impact.</p></li> </ol> <p>Thanks for your help in advance.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload