用于自定义声波控制的WPF性能渲染

时间:2014-01-06 15:15:18

标签: wpf performance custom-controls

我目前正在为WPF编写声波可视化控件。实际上它可以渲染任何类型的线图数据;它不一定是声波。只要数据是一组离散的样本,它就会呈现它。

我有它的工作;但是性能并不理想。我已经做了很多代码优化,以使OnRender方法快速工作。我用一个分析器对它进行了测试,它显示它运行在110毫秒左右,这应该没问题。

然而,我看到应用程序停滞不前,而分析器没有显示原因。

在我的测试中,我注意到它可能与填充率有关。我的意思是绘制的像素数。我的测试数据由一个sin波组成,在40000秒时为41000hz。这样可以生成812000个样本。现在,我的控件根据用户正在查看波形的缩放比例优化此数据。整个波浪将使用大约6000线绘制。

如果我向波浪缩放很长时间,那么我只渲染两个完整的正弦波,我仍然可以进行大约6000次线条绘制。 CPU时间大约相同,为110毫秒,但应用程序是平滑的,并没有停止,这一开始看起来很奇怪。

然而,当看到它时,全波画几乎触及每个像素。图表绘制一条绿线,当缩小时会覆盖图形控件的整个背景。仅在少量缩放时,背景就会透支。

我是一名游戏程序员,所以我发现这个问题可能是由填充率限制引起的。如果线条绘制触摸每个像素,则无论线条绘制的数量如何,绘制都会变慢。但是我不希望出现这种情况,因为图表在屏幕上不是那么大。如果我改变窗口的大小,那么它会变得更慢,这再次通过猜测填充率问题来加强。现代显卡应该能够处理这个,所以控件可能正在使用软件渲染。我不确定如何证明这一点!!

因此,就逻辑而言,我的OnRender方法已经过优化。在上述两种情况下,在CPU上绘制所花费的时间并没有太大变化。然而,在某些情况下,如果触摸了大量像素,则存在大约一秒钟的可怕延迟。

有谁知道如何改善这个?

我考虑过的一种方法是在另一个线程上渲染屏幕外纹理并且一旦完成,然后在纹理更新后调用InvalidateVisual。我也可以经常进行失效,因此图形渲染会随着时间的推移而更新,而不是突然出现。

任何人都有这方面的经验,我如何实际剖析WPF的内部?

有没有人知道一个能够告诉我实际造成这种情况的分析器,但正如我所说的,我认为这可能取决于实际的硬件渲染和填充率问题。

请注意,我的图形控件继承自Canvas,线条绘制是使用StreamGeometryContext完成的。我还冻结了几何图形和所有画笔和笔。

由于

1 个答案:

答案 0 :(得分:3)

我编写的软件需要非常快速地绘制大量频率sprectrum数据。 WPF保留的图形系统不适合绘制(绘制)经常变化的大量数据。我们使用D3D9绘制图表。 WPF提供了一种通过D3DImage类将其转换为渲染系统的方法,它可以成为ImageBrush。因此,它以一点点性能为代价避免了与空域限制有关的问题,但仍然比使用WPF对象渲染要快得多。

我还看到了两个非常好的图形库,它们有不同的优点/缺点。

  1. SciChart实际上是一个基于软件的WPF渲染图表工具,但性能很好。
  2. Lightning Chart使用DirectX(通过SlimDX库,它是一个托管的.NET包装器),并且非常注重性能。
  3. 关于有关软件渲染的问题... WPF Performance Suite具有分析工具和叠加层,可以显示应用程序的哪些部分正在进行软件渲染。您可能希望从Microsoft下载并试一试。

    根据我的阅读,WPF的渲染系统几乎不是最优的(A Critical Deep Dive into the WPF Rendering System)。对于WPF的设计,它很棒,但它也有其局限性。

    我的建议是,如果你有游戏开发和DirectX的经验,并且你需要一种方法来快速绘制大量数据,通过WPF中的D3DImage类来查看与D3D的互操作。