简体   繁体   中英

Fast copying of GUI in C#?

Right now I'm copying window graphics from one window to another via BitBlt from WinApi. I wonder if there is any other fast / faster way to do the same in C#.

Keyword is performance here. If I should stay with WinApi I would hold HDC in memory for quick drawing and if .NET Framework has other possibilities I would probably hold Graphics objects. Right now I'm something to slow when I have to copy ~ 1920x1080 windows.

So how can I boost performance of gui copying in C# ?
I just want to know if I can get better than this. Explicit hardware acceleration (OpenGL, DirectX) is out of my interest here. I decided to stay pure .NET + WinApi.

// example to copy desktop to window
Graphics g = Graphics.FromHwnd(Handle);
IntPtr dc = g.GetHdc();
IntPtr dc0 = Windows.GetWindowDC(Windows.GetDesktopWindow());
Windows.BitBlt(dc, 0, 0, Width, Height, dc0, 0, 0, Windows.SRCCOPY);
// clean up of DCs and Graphics left out

Hans's questions:

  • How slow is it?
    • Too slow. Feels (very) stiff.
  • How fast does it need to be?
    • The software mustn't feel slow.
  • Why is it important?
    • User friendliness of software.
  • What does the hardware look like?
    • Any random PC.
  • Why can't you solve it with better hardware?
    • It's just software that runs on Windows machines. You won't goy and buy a new PC for a random software that runs slow on your old ?

Get a better video card!

The whole point of the GDI, whether you access it from native code or via .Net, is that it abstracts the details of the graphics subsystem. The downside being that the low level operations such as blitting are in the hands of the graphic driver writers. You can safely assume that these are as optimised as it's possible to get (after all, a video card manufacturer wants to make their card look the best).

The overhead of using the .Net wrappers instead of using the native calls directly pale into insignificance compared to the time spent doing the operation itself, so you're not going to gain much really.

Your code is doing a non-scaling, no blending copy which is possibly the fastest way to copy images.

Of course, you should be profiling the code to see what effect any changes you do to the code is having.

The question then is why are you copying such large images from one window to another? Do you control the contents of both windows?

Update

If you control both windows, why not draw to a single surface and then blit that to both windows? This should replace the often costly operation of reading data from the video card (ie blitting from one window to another) with two write operations. It's just a thought and might not work but you'd need timing data to see if it makes any difference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM