/// <summary>
        /// Read back the data from the texture into a CPU buffer
        /// </summary>
        /// <param name="buffer"></param>
        public void ReadBack(byte[] buffer)
        {
            Stopwatch Timer = new Stopwatch();

            Timer.Start();
            try
            {
                FDevice.StretchRectangle(this.FTextureShared.GetSurfaceLevel(0), this.FTextureCopied.GetSurfaceLevel(0), TextureFilter.None);
                FDevice.GetRenderTargetData(this.FTextureCopied.GetSurfaceLevel(0), FSurfaceOffscreen);

                var rect = FSurfaceOffscreen.LockRectangle(LockFlags.ReadOnly);
                try
                {
                    rect.Data.Read(buffer, 0, buffer.Length);
                    FSurfaceOffscreen.UnlockRectangle();
                }
                catch (Exception e)
                {
                    FSurfaceOffscreen.UnlockRectangle();
                    throw;
                }
            }
            catch (Exception e)
            {
                FDevice.EndScene();
                throw;
            }
            Timer.Stop();
            Debug.Print(Timer.Elapsed.TotalMilliseconds.ToString());
        }
    /// <summary>
    /// Gets the specified region (identified in client coordinates) from the current surface
    /// </summary>
    /// <param name="region">The region (in client coordinates, e.g. <see cref="NativeMethods.GetClientRect"/> is the entire window content).</param>
    /// <returns>A new Bitmap object (must be Disposed by caller)</returns>
    public Bitmap GetSurfaceRegion(Rectangle region)
    {
        if (_captureHwnd == IntPtr.Zero)
        {
            return(null);
        }

        #region Create a copy of the surface image

        NativeMethods.UpdateWindowShared(_captureHwnd, 0, 0, 0, IntPtr.Zero, IntPtr.Zero);
        Surface.FromSurface(_renderTarget, _sharedSurface, Filter.None, 0);

        _deviceEx.GetRenderTargetData(_renderTarget, _systemMemorySurface);

        #endregion

        #region Put the data into a Bitmap

        // Note: during my tests I found that the captured area includes space for the window chrome
        //       but filled in black.

        // Take into consideration the window chrome
        Size chrome = NativeMethods.GetWindowChromeSize(_captureHwnd);
        region.X += chrome.Width;
        region.Y += chrome.Height;

        // We need to convert Width and Height to x2, and y2 respectively, because
        // Surface.ToStream(...) expects the rectangle to have x1,y1,x2,y2 not x1,y1,width,height
        // (SlimDX version 2.0.6.40)
        region.Width  += region.X;
        region.Height += region.Y;
        DataStream stream = Surface.ToStream(_systemMemorySurface, ImageFileFormat.Bmp, region);

        Bitmap surfaceBitmap = (Bitmap)Image.FromStream(stream);

        stream.Close();
        stream.Dispose();

        #endregion

        return(surfaceBitmap);
    }