我正在开发一个应用程序,它需要以网格的形式绘制大约 70k 个矩形(一个网格 40x250 和一个 250x250)。当时并非所有矩形都在屏幕上可见。
阅读http://msdn.microsoft.com/en-us/magazine/dd483292.aspx后,我创建了简单的控件(从 FrameworkElement 继承,部分在下面列出),它使用 DrawingVisual descant 创建一列矩形。
// Removing items after collection change
private void RemoveItems(IList oldItems) {
foreach (var oldItem in oldItems) {
var visualChild = _visuals.FirstOrDefault(v => v.Data == oldItem);
if (visualChild != null) {
_visuals.Remove(visualChild);
RemoveVisualChild(visualChild);
}
_translateTransform.X -= 8;
}
}
// Adding items after collection change
private void AddItems(IList newItems) {
foreach (var newItem in newItems) {
var newArray = (byte[]) newItem;
var visual = CreateVisual(newArray);
_visuals.Add(visual);
AddVisualChild(visual);
_col++;
}
}
// Creating visual element
private StripeVisual CreateVisual(byte[] data) {
var result = new StripeVisual {
Data = data,
Transform = _translateTransform
};
using (var dc = result.RenderOpen()) {
for (int i = 0; i < data.Length; i++) {
dc.DrawRectangle(_brushes[data[i]], _strokePen, new Rect(_col * 8, i * 20, 8, 20));
}
}
return result;
}
所有画笔都被冻结(Brushes
类成员)并被_strokePen
冻结。每 200 毫秒将新的垂直条纹添加到集合中。
程序已在 3 台计算机上运行:
- 笔记本电脑:i7-2670QM、GeForce GT 540M/Intel HD Graphics 3000、4GB RAM、Win7 x64、DirectX11、
- PC:Core2Duo E7400、Radeon HD 4800、3GB RAM、Win7 x64、DirectX11、
- PC:i3 3,07GHz,Inter HD Graphics,3.3GB RAM,Win7 x86,DirectX11。
问题是,在我的第一台计算机上,程序运行平稳,对 CPU 没有太大影响(使用率在 1-10% 之间)。在第二台和第三台计算机上,程序的性能都是不可接受的:大约 30x100 的网格占用了 50% 的处理器,而且一切运行速度都很慢。即使只有一小部分网格可见,程序也会运行缓慢。
看起来程序正在使用软件渲染(渲染线程正在使用 50% 的处理器),但RenderCapability.Tier >> 16
返回 2,并RenderOption.ProcessRenderMode
设置为Default
. 也没有[HKCU/Software/Microsoft/Avalon.Graphics]
可以禁用硬件加速的键。
是否可以运行此应用程序顺利列出的计算机?我还能做些什么来最大限度地提高该程序的性能?
更新
设置DrawingVisual.CacheMode = new BitmapCache();
帮助很大。这是否意味着 CPU<=>GPU 通信是瓶颈?