title: Write to buffered graphics surface via pointer manupilation
body: <p>I need to render a 1027 * 768 bitmap to the client window (same size) and I don't have more than <strong>10-15 ms</strong> to complete this task. I am using <strong>bufferedGraphics</strong> allocated from a <strong>bufferedGraphicsContect</strong> object and still notice huge performance issues.</p>
  
  <p>I am using unsafe code to perform my <strong>copy operations</strong> and <strong>found unbelievable results</strong>. I know the Graphics / BufferedGraphics objects should have some sort of a <strong>drawing surface in memory</strong>. I was wondering if someone could point me in the right direction on how to write to this surface using Marshal or some other unsafe low level method.</p>
  
  <p>I am in the process of porting an older c# graphics application. I know c# is not designed for heavy graphics and that there are better tools than GDI+ available, unfortunately I don't have those luxuries.</p>
  
  <p>This is what I have come up with so far... Any insight what so ever is greatly apperciated.</p>
  
  <pre><code>byte[] _argbs = null;
  static readonly Bitmap _bmUnderlay = Properties.Resources.bg;
  static Bitmap _bmpRender = new Bitmap(1024, 768, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
  int bmpHeight = Properties.Resources.bg.Height;
  int bmpWidth = Properties.Resources.bg.Width;
  static BufferedGraphicsContext _bgc = new BufferedGraphicsContext();
  
  internal unsafe void FillBackBuffer(Point cameraPos)
  {
          // lock up the parts of the original image to read (parts of it)
          System.Drawing.Imaging.BitmapData bmd = _bmUnderlay.LockBits(
              new Rectangle(cameraPos.X, cameraPos.Y, 1024, 768),
              System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
          // get the address of the first line.
          IntPtr ptr = bmd.Scan0;
  
          //if (_argbs == null || _argbs.Length != bmd.Stride * bmd.Height)
          //    _argbs = new byte[bmd.Stride * bmd.Height];
          if (_argbs == null || _argbs.Length != 1024 * 3 * 768)
              _argbs = new byte[1024 * 3 * 768];
  
          // copy data out to a buffer
          Marshal.Copy(ptr, _argbs, 0, 1024 * 3 * 768);
  
          _bmUnderlay.UnlockBits(bmd);
  
          // lock the new image to write to (all of it)
          System.Drawing.Imaging.BitmapData bmdNew = _bmpRender.LockBits(
              new Rectangle(0, 0, 1024, 768),
              System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
          // copy data to new bitmap
          Marshal.Copy(_argbs, 0, bmdNew.Scan0, 1024 * 3 * 768);
          _bmpRender.UnlockBits(bmdNew);
  }
  
  private unsafe void _btnGo_Click(object sender, EventArgs e)
  {
      // less than 2 ms to complete!!!!!!!!
      FillBackBuffer(new Point());
  
      using (BufferedGraphics bg = _bgc.Allocate(CreateGraphics(), ClientRectangle))
      {
          System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
          sw.Start();
          /////
          ///
          // This method takes over 17 ms to complete
          bg.Graphics.DrawImageUnscaled(_bmpRender, new Point());
          //
          ///
          /////
          sw.Start();
          this.Text = sw.Elapsed.TotalMilliseconds.ToString();
  
          bg.Render();
      }
  }
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>Forgot to mention I'm looking for a low level alternative to Graphics.DrawImage(), preferrably writing to Graphics surface memory, using pointers? Thanks again</p>