DrawingVisual与Canvas.OnRender的性能,适用于许多不断变化的形状

Rom*_*kov 13 wpf performance

我正在开发一款类似游戏的应用程序,它有多达千种形状(椭圆和线条),不断变换为60fps.阅读了一篇关于渲染许多移动形状优秀文章后,我使用自定义Canvas后代实现了这一点,该后代覆盖OnRender了通过a进行绘制DrawingContext.虽然CPU使用率很高,但性能非常合理.

然而,文章表明,不断移动形状的最有效方法是使用大量DrawingVisual实例而不是OnRender.不幸的是,虽然它没有解释为什么在这种情况下应该更快.

以这种方式改变实现并不是一件小事,所以我想在决定进行切换之前了解原因以及它们是否适用于我.为什么这种DrawingVisual方法会导致CPU使用率低OnRender于此方案中的方法?

Cha*_*lie 15

来自C#2008中的Pro WPF:

这些应用程序带来的问题不是艺术的复杂性,而是单个图形元素的绝对数量.即使用较轻的Geometry对象替换Path元素,开销仍然会妨碍应用程序的性能.针对这种情况的WPF解决方案是使用较低级别的可视层模型.基本思想是将每个图形元素定义为Visual对象,这是一个非常轻量级的成分,其开销比Geometry对象或Path对象少.

它归结为是你创造的那些椭圆和线条中的每一个都是独立的FrameworkElement; 这意味着它不仅支持命中测试,还支持布局,输入,焦点,事件,样式,数据绑定,资源和动画.对于你想要做的事情来说,这是一个非常重量级的对象!该Visual对象跳过所有这些并直接从中继承DependencyObject.它仍然支持命中测试,坐标转换和边界框计算,但没有形状支持的其他东西.它的重量更轻,可能会极大地提高您的性能.

编辑:

好的,我第一次误读了你的问题.

在您使用的情况下OnRender,它实际上取决于您如何创建视觉效果并显示它们.如果您正在使用a DrawingContext并将所有视觉效果添加到单个元素,则这与使用该DrawingVisual方法没有什么不同.如果您为每个Visual创建的元素创建一个单独的元素,那么这将是一个问题.在我看来,你正在以正确的方式做事.

  • 编辑也是错误的,当使用 DrawingContext 渲染时,您不会创建任何 Visual,您只需绘制形状而不保留任何参考。 (2认同)

use*_*587 9

答案中的每个人都错了.问题是在绘图上下文中直接渲染形状是否比创建DrawingVisual更快.答案显然是'是'.DrawLine,DrawEllipse,DrawRectangle等函数不会创建任何UI元素.DrawingVisual要慢得多,因为它确实创建了一个UI元素,尽管它是一个轻量级元素.答案中的混淆是因为人们只是复制/粘贴DrawingVisual比MSDN中的不同UIElement形状语句表现更好.

  • 我不完全确定答案是否明显.在大多数形状不移动的情况下,绘图上下文*不是更慢*?它重绘了一切,而DrawingVisual方法允许框架缓存和重用之前绘制的东西.或者这不是这样吗? (4认同)
  • DrawingContext不会重绘所有内容,因为WPF具有保留的绘图模型.DrawingVisual包含控制是否应该重绘Visual的逻辑.您可以在OnRender()方法中实现相同的逻辑,并仅在必要时绘制.WPF不会以60 fps使绘图无效,只有在调用InvalidateVisual()或WPF需要使绘图无效时才会调用OnRender(). (3认同)

Ran*_*e42 8

我认为Petzold在这一段中解释过;

ScatterPlotVisual类的工作原理是为每个DataPoint创建一个DrawingVisual对象.当DataPoint对象的属性发生更改时,该类只需要更改与该DataPoint关联的DrawingVisual.

这建立在早先的解释之上;

只要ItemsSource属性发生更改,或者集合发生更改,或者集合中DataPoint对象的属性发生更改,ScatterPlotRender就会调用InvalidateVisual.这将生成对OnRender的调用,该调用绘制 整个散点图.

这是你的要求吗?

顺便说一句,是一个相当新的高性能WPF教程,该绘图中有数万个点,它也是3D渲染和动画(甚至使用鼠标输入来驱动一些变换).

  • 是的,似乎我感到困惑的是没有意识到`DrawingVisual`方法只被认为是这种特殊场景的"最佳"方法 - 许多点改变了,但不是全部.当一切都在移动时(我的情况就是这样),"OnRender"听起来就像是最好的方法.不错的链接 - 谢谢. (2认同)