【问题标题】:Fast copying of GUI in C#?在 C# 中快速复制 GUI?
【发布时间】:2014-01-17 11:31:07
【问题描述】:

现在我正在通过 WinApi 中的BitBlt 将窗口图形从一个窗口复制到另一个窗口。我想知道在 C# 中是否有任何其他更快/更快的方法来做同样的事情。

这里的关键字是performance。如果我应该继续使用 WinApi,我会在内存中保存 HDC 以便快速绘图,如果 .NET Framework 有其他可能性,我可能会保存 Graphics 对象。现在,当我必须复制 ~ 1920x1080 的窗口时,我有点慢。

那么如何提高 C# 中 gui 复制的性能?
我只是想知道我是否能变得比这更好。显式硬件加速(OpenGL、DirectX)在这里不符合我的兴趣。我决定保持纯 .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

汉斯的问题:

  • 有多慢?
    • 太慢了。感觉(非常)僵硬。
  • 需要多快?
    • 软件不能感觉慢。
  • 为什么它很重要?
    • 软件的用户友好性。
  • 硬件是什么样的?
    • 任何随机 PC。
  • 为什么你不能用更好的硬件来解决它?
    • 它只是在 Windows 机器上运行的软件。你不会去买一台新电脑来换一个在旧电脑上运行缓慢的随机软件吗?

【问题讨论】:

  • 这个问题与性能问题有共同的问题。它有多慢?它需要多快?它为什么如此重要?硬件是什么样的?为什么不能用更好的硬件来解决?
  • 您是否也需要一匹镶有红宝石的小马和愿望清单?在决定您需要一定程度的性能之前,您确实需要评估它是否可行。

标签: c# winforms performance winapi graphics


【解决方案1】:

获得更好的视频卡!

GDI 的全部意义,无论您是从本机代码还是通过 .Net 访问它,都在于它抽象了图形子系统的细节。缺点是低级操作(例如 blitting)掌握在图形驱动程序编写者手中。您可以放心地假设这些已尽可能优化(毕竟,视频卡制造商希望使他们的卡看起来最好)。

与执行操作本身所花费的时间相比,使用 .Net 包装器而不是直接使用本机调用的开销微不足道,因此您不会真正获得太多收益。

您的代码正在执行非缩放、非混合复制,这可能是复制图像的最快方式。

当然,您应该分析代码以查看您对代码所做的任何更改都会产生什么影响。

那么问题是你为什么要将这么大的图像从一个窗口复制到另一个窗口?你控制两个窗口的内容吗?

更新

如果您控制两个窗口,为什么不绘制到一个表面,然后将它blit 到两个窗口?这应该用两个写操作代替从视频卡读取数据的成本高昂的操作(即从一个窗口到另一个窗口)。这只是一个想法,可能行不通,但您需要时间数据来查看它是否有任何不同。

【讨论】:

  • 是的,我确实控制着内容。它更像是大尺寸的单个控件。内容是通过图形绘制的。我也不能指望我的客户购买更好的视频卡。 ;)
  • 不涉及显卡,那是昨天的事。今天,Windows 将 Windows 渲染到 RAM。 Aero 工作方式的核心。
  • @HansPassant:你有引用吗?根据我的阅读,从 Vista 开始的驱动程序模型使用 Direct3D。我认为您的意思是 Windows 渲染到 D3D 表面,可能在 RAM 中或视频卡上。
  • 我不确定我是否会同意你所说的一切,但我会接受你的第 3 段,以确保我 BitBlt 是最快的复制方式(在问题出现之前关闭^^)。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2020-01-13
  • 2018-07-04
  • 2011-01-11
  • 1970-01-01
相关资源
最近更新 更多