red*_*sky 5 c# system.drawing gdi+ .net-3.0 c#-3.0
背景
我正在开发一个应用程序,该应用程序应该以相同的方式在从 XP 开始的每个 Windows 平台上运行。通过 .NET 框架,这在大多数情况下都非常容易。该应用程序可在各种触摸表面上运行。该应用程序面向 .Net 3.0,但如果由于某种原因我应该迁移到 .Net 3.5,我可以这样做。我无法使用4.0。
该应用程序通过 System.Drawing 命名空间大量使用 GDI+。现在,我了解到 GDI+ 要么根本没有硬件加速,要么只在极少数显卡中加速,所以我预计会出现一些性能问题。然而,这个问题很明显,并且使应用程序的可用性显着降低。如果可以通过简单的修复来避免的话,我宁愿不将整个应用程序重写为目标 DirectX 或 OpenGL。
问题
我们最近在其中一张触摸桌上安装了 Windows 7 64 位。这是该应用程序首次在 Windows 7 64 位计算机上运行。无论如何,一次使用多个手指在设备上进行任何绘图(特别是 DrawLine)都会导致严重的延迟。这种延迟在 32 位 Windows XP 或 32 位 Windows 7 上并不明显,因此我认为它可能特定于 64 位 Windows 7(我没有 64 位 XP 机器来测试)。
该应用程序还被迫作为 32 位应用程序运行,因为其中一个 .dll 文件只有 32 位库可用于编译它。我在某处读到,在 64 位系统上强制进程进入 32 位模式可能会导致性能问题,但是当我升级我们正在使用的 SDK 并制作 64 位特定的 .dll 和应用程序时,问题仍然存在。
我在 StackOverflow 的另一个帖子中读到,在 GDI+ 方面,32 位和 64 位应用程序之间应该没有区别。这里的情况似乎并非如此。
那么问题来了:你们知道为什么 Windows 32 位和 Windows 64 位之间的性能差异如此之大吗?如果我找不到解决方案,我将不得不花一些时间让一切都使用硬件加速绘图。如果可能的话,我想避免这种情况。
感谢大家!
编辑:请求的代码片段
public delegate void drawLineDelegate(Color color, float width, int x1, int y1, int x2, int y2);
public void drawLine(Color color, float width, int x1, int y1, int x2, int y2)
{
if (InvokeRequired)
{
Invoke(new drawLineDelegate(drawLine), new object[] { color, width, x1, y1, x2, y2 });
}
else
{
try
{
lock (drawLock)
{
pen.Width = width;
pen.Color = color;
scaledPen.Width = width * this.Width / Canvas.Width;
scaledPen.Color = color;
Point p1 = scalePointToScreen(new Point(x1, y1));
Point p2 = scalePointToScreen(new Point(x2, y2));
graphics.DrawLine(pen, x1, y1, x2, y2);
scaledGraphics.DrawLine(scaledPen, p1.X, p1.Y, p2.X, p2.Y);
this.Invalidate(new Rectangle(Math.Min(p1.X, p2.X) - (int)scaledPen.Width, Math.Min(p1.Y, p2.Y) - (int)scaledPen.Width,
Math.Abs(p2.X - p1.X) + 2 * (int)scaledPen.Width, Math.Abs(p2.Y - p1.Y) + 2 * (int)scaledPen.Width));
}
}
catch (Exception ex)
{
if (Scribbler.Properties.Settings.Default.LogLevel >= 2)
{
Scribbler.ScribblerForm.WriteLogMessage(ex.ToString());
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:进一步研究 我在互联网上对我们机器上使用的 NVidia 卡进行了更多搜索。这让我在 NVidia 开发者论坛上看到了几篇关于遇到相同问题的人的帖子。常见的答案是 GDI 在 Windows 7 上已被弃用,并且较新的 NVidia 图形驱动程序(从 182.5 开始)存在 GDI 性能问题。解决方案是更新到 Direct3D 或使用旧驱动程序。有谁确切知道这是否是最好的行动方案?
首先,我不确定使用 WPF 是否会带来很多性能优势。如果您确实决定重写图形代码,我建议转向Direct2D(您仍然可以用 C# 编写代码)。这是一篇比较所有三个库的性能的文章:http://www.teechart.net/reference/articles/WhitePaper_Direct2D.htm
我是Maperitive的开发人员,它大量使用 GDI+ 来渲染地图。我不能说我注意到 64 位 Windows 7 上有任何重大性能问题,但话又说回来,我并没有真正在任何其他系统上测试它(除了上网本上的 Ubuntu Mono,这是可以理解的,它要慢得多)。
我想如果您向我们展示一些画线代码的片段,讨论这个问题会更容易。另一方面,问题可能与硬件相关(显卡驱动程序?)。您在多少种不同的 Win 7 64 位配置上进行了测试?
更新:
关于 Windows 7 上“已弃用”的 GDI:我非常怀疑这是否属实,因为您不仅会注意到应用程序上的性能问题,而且我怀疑 Microsoft 出于向后兼容性的原因会足够大胆地做这样的事情。您有任何链接可以证明这一说法吗?
关于您的代码:您没有显示所有内容及其真正目的,但从上下文来看,我怀疑您使用Graphics
使用Control.CreateGraphics()
方法创建的对象(并且您也从其他线程调用线条绘制,这本身可能是一个性能问题)。我怀疑您这样做是为了交互式地绘制线条(而不是通过OnPaint()
方法重新绘制所有内容)。一般来说,这种做法是有问题的(这是鲍勃·鲍威尔的解释)。
graphics
顺便说一句和 和有什么不一样scaledGraphics
?
如果您能解释一下您到底想通过此方法实现什么目标,也许我们可以找到更好(更快)的方法来实现此目的。