Note that there are some explanatory texts on larger screens.

plurals
  1. POWpf's InteropBitmap together with GDI+: high cpu usage
    text
    copied!<p>I've created a little wpf test application which renders some random rectangles every 30 msec using <strong>System.Drawing.Graphics</strong> and wpf's <strong>InteropBitmap</strong>. I thought InteropBitmap would be faster than WriteableBitmap: It has the ability to update itself from the memory section.</p> <p>While executing the app (screen size 1600 * 1200) the cpu usage of the app is only about <strong>2-10%</strong> with a dual core 3GHz. But the overall cpu usage is about <strong>80-90%</strong>, because the process "System (NT Kernel &amp; System") rises up to 70% ! <strong>EDIT:</strong> And I noticed that the RAM usage periodically increases by more than 1 GB within 15 seconds and then suddenly falls back to its normal level and so on.</p> <p>Maybe the following code can be optimized ? :</p> <pre><code>namespace InteropBitmapTest{ using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using Color = System.Drawing.Color; public partial class Window1 : Window { private System.Drawing.Bitmap gdiBitmap; private Graphics graphics; InteropBitmap interopBitmap; const uint FILE_MAP_ALL_ACCESS = 0xF001F; const uint PAGE_READWRITE = 0x04; private int bpp = PixelFormats.Bgr32.BitsPerPixel / 8; private Random random; private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); SolidBrush[] brushes = new SolidBrush[] { new SolidBrush(Color.Lime), new SolidBrush(Color.White) }; [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap); public Window1() { InitializeComponent(); Loaded += Window1_Loaded; WindowState = WindowState.Maximized; timer.Tick += timer_Tick; timer.Interval = 30; random = new Random(); } void Window1_Loaded(object sender, RoutedEventArgs e) { // create interopbitmap, gdi bitmap, get Graphics object CreateBitmaps(); // start drawing 100 gdi+ rectangles every 30 msec: timer.Start(); } void timer_Tick(object sender, EventArgs e) { int width = 50; // Draw 100 gdi+ rectangles : for (int i = 0; i &lt; 100; i++) { int left = random.Next((int)(ActualWidth - width)); int top = random.Next((int)(ActualHeight - width)); graphics.FillRectangle(brushes[left % 2], left, top, width, width); } interopBitmap.Invalidate(); // should only update video memory (and not copy the whole bitmap to video memory before) } void CreateBitmaps() { uint byteCount = (uint) (ActualWidth * ActualHeight * bpp); //Allocate/reserve memory to write to var sectionPointer = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, PAGE_READWRITE, 0, byteCount, null); var mapPointer = MapViewOfFile(sectionPointer, FILE_MAP_ALL_ACCESS, 0, 0, byteCount); var format = PixelFormats.Bgr32; //create the InteropBitmap interopBitmap = Imaging.CreateBitmapSourceFromMemorySection(sectionPointer, (int)ActualWidth, (int)ActualHeight, format, (int)(ActualWidth * format.BitsPerPixel / 8), 0) as InteropBitmap; //create the GDI Bitmap gdiBitmap = new System.Drawing.Bitmap((int)ActualWidth, (int)ActualHeight, (int)ActualWidth * bpp, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, mapPointer); // Get good old GDI Graphics graphics = Graphics.FromImage(gdiBitmap); // set the interopbitmap as Source to the wpf image defined in XAML wpfImage.Source = (BitmapSource) interopBitmap; } }} </code></pre> <p>XAML:</p> <pre><code>&lt;Window x:Class="InteropBitmapTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"&gt; &lt;Image Name="wpfImage" Stretch="None" /&gt; &lt;/Window&gt; </code></pre>
 

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