【问题标题】:Forcing hardware acceleration强制硬件加速
【发布时间】:2016-07-28 21:19:39
【问题描述】:

我刚刚做了一个基准测试,在其中我继续向画布添加多边形,并让调度程序计时器在每次通过时随机更新每个多边形的位置。我一直这样做,直到我测量到 fps 低于 30fps。我注意到一些事情,基准测试似乎没有使用 GPU。我有渲染能力 2,但在使用 avalon.graphics 注册表打开硬件加速时得到相同的结果。在我看来,即使我有渲染能力 2 和良好的 GPU,wpf 仍然为带有画布容器的 ItemsControl 和带有 Polygons 的 observablecollection 选择软件渲染。 (在低于 30fps 之前,我添加了大约 3500 个多边形)。这里有什么我不明白的吗?我是否必须使用其他形状或渲染循环来使用图形硬件?

【问题讨论】:

    标签: .net wpf graphics


    【解决方案1】:

    您应该使用分析器进行检查以确定,但我怀疑您的大部分开销是填充矢量图形缓冲区的代码,而不是实际的光栅化(硬件帮助的部分)。您可能会得到更好的如果您不尝试移动多边形,而只是不断添加新多边形,则可以了解光栅化开销。

    也就是说,您在使用 ItemsControl 时可能会遇到另一个问题。即使容器是 Canvas,Polygon 对象也不会直接添加到 Canvas。 ItemsControl 而是创建一个容器对象来承载每个 Polygon 并将该容器对象添加到 Canvas。这意味着您有另一层对象参与测量/排列/渲染通道。

    此外,Polygon 类实际上是一个 UIControl,它是一个相对“重”的类。特别是,它允许 UI 交互性,其中涉及大量用于鼠标事件、焦点的基础设施,当然还有整个通用的 DependencyObject 基础设施。这不是执行大量元素渲染的好选择。

    如果您想这样做,最好创建您自己的 UIElement/FrameworkElement 衍生物并在 OnRender 覆盖中执行所有多边形的渲染。这允许您直接绘制到 DrawingContext,绕过上面描述的所有重型机械。您仍然可以使用 View/ViewModel 模式,但您最终将在代码中而不是 XAML 中实现您的 View 类。

    【讨论】:

    • 啊,我明白了!非常感谢,我会进一步调查。你是否知道有一个 itemscollection 并跳过为每个元素添加的额外容器?我只想添加多边形本身。或者也许是一些更明确的方式来添加它们而不使用 wpf-controls
    • 这确实是一个改进,现在我的原始对象渲染得更快了。 WPF 渲染管道的另一个问题是,当我同时添加大量对象时,我使用 AddRange 到我的 ObservableCollection,但是在添加它们时仍然存在很大的冻结延迟,并且在我删除/添加时连续单品,你有过这种经历吗?我所有的对象也不是多边形,而是由线条、多边形、文本等组成的更复杂的对象。
    • 默认的 ObservableCollection 不能很好地处理 AddRange; VS SDK 中有一个BulkObservableCollection,但它不是标准 BCL 的一部分。最简单的选择可能是替换整个集合并提高集合属性上更改的属性,而不是使用 ObservableCollection。 ObservableCollection 最适合用于相对较小的集合。
    • 好吧,每次都替换整个 Collection 并提高 notifypropertychanged 似乎太费劲了。它可以包含从 20 到 400 个需要渲染的对象的所有内容。我在 observablecollection 中看到的问题是同时添加 20-30 个对象时。这似乎锁定了我的 ui 线程。多边形的东西确实有助于清理事情,以及尝试修剪视觉树
    猜你喜欢
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2013-09-29
    • 2019-04-16
    • 2011-03-10
    相关资源
    最近更新 更多