c# – System.Drawing对我们想做的事情来说太慢了吗?

我目前正在开发win表单应用程序的用户界面.主窗口是无边框形式,其表面区域几乎完全在Form.Paint事件中呈现.创建一个后台缓冲区并按常规绘制:

private void form_Paint(object sender, PaintEventArgs e) {
  e.Graphics.DrawImage(BackBuffer, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel);
}

后缓冲区的某些区域在各种条件下重绘;鼠标悬停效应很常见.仔细重绘的类只会使适用的区域无效.尽管如此,只需在表格上滑动鼠标就足以将高端CPU驱动到> 50秒使用几秒钟.

我已经分析了应用程序,并且在上面调用DrawImage时,超过80%的CPU时间被烧毁.我知道GDI很慢并且没有(很少?)使用GPU ……并且应用程序的目标平台并不能保证GPU不会首先集成.但我不知道这是坏事.

我是否应该面对这样一个事实:GDI对于我们想要做的事情来说还不够快,或者是否有机会改进代码呢?

-编辑-

BackBuffer表示在系统启动期间创建的位图.它的大小与屏幕分辨率相匹配.在诸如鼠标悬停和点击之类的各种事件期间,在其上绘制了各种区域.它的创建相当简单:

this.BufferBmp = new Bitmap(screenWidth, screenHeight);
this.Gfx = Graphics.FromImage(BufferBmp);

Gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
最佳答案
创建自己的“后台缓冲区”而不是使用内置的双缓冲支持很难获得高效率.重要的是缓冲区的像素格式.在大多数现代机器上,无论如何我尝试过,32bppPArgb格式的速度是其他任何机器的十倍.支持内置的双缓冲支持,以实现卓越的性能.

另一种可能的损失是你试图保持裁剪区域尽可能小.当区域变得复杂时,这可以字节.如果你让快速鼠标移动产生小的矩形更新区域,听起来就像你那么接近.当绘画落后时,它几乎总是会因为鼠标获得更高的优先级,你可以建立一个非常复杂的小矩形链.首先通过使整个区域无效来测试它.接下来的方法是自己扩展区域,始终保持一个矩形. OnPaint运行时重置.

转载注明原文:c# – System.Drawing对我们想做的事情来说太慢了吗? - 代码日志