我目前正在开发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 +对于我们希望做的事情来说还不够快,或者仍然有机会改进代码?
-edit -
BackBuffer表示在系统启动期间创建的位图。它的大小与屏幕分辨率相匹配。在诸如鼠标悬停和点击之类的各种事件期间,在其上绘制了各种区域。它的创建非常简单:
this.BufferBmp = new Bitmap(screenWidth, screenHeight);
this.Gfx = Graphics.FromImage(BufferBmp);
Gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
答案 0 :(得分:3)
此外,还可以选择使用BitBlt。请点击此处查看similar question and solution。
答案 1 :(得分:3)
创建自己的“后台缓冲区”而不是使用内置的双缓冲支持很难获得高效率。重要的是伟大的交易是缓冲区的像素格式。在大多数现代机器上,无论如何,我尝试的任何一种机器,32bppPArgb格式都是十倍的速度。支持内置的双缓冲支持,以实现卓越的性能。
另一种可能的损失是您尝试保持裁剪区域尽可能小。当区域变得复杂时,这可以字节。如果你让快速鼠标移动产生小的矩形更新区域,听起来就像你那么接近。当绘画落后时,它几乎总是会因为鼠标获得更高的优先级,你可以建立一个非常复杂的小矩形链。首先通过使整个区域无效来测试它。接下来的方法是自己扩展区域,始终保持一个矩形。在OnPaint运行时重置。
答案 2 :(得分:1)
我认为你想要创建一个继承自Form
的新类,然后在OnPaint
方法中进行绘制,而不是从表单中监听Paint
事件。 / p>