WPF使用BitmapSource渲染性能

Dan*_*olf 7 wpf performance rendering bitmap

我已经创建了一个WPF控件(继承自FrameworkElement),它显示了可以平移的平铺图形.每块瓷砖在24bpp时为256x256像素.我已经超越了OnRender.在那里,我加载任何新的tile(如BitmapFrame),然后使用drawingContext.DrawImage绘制所有可见的tile.

现在,每当渲染周期中有少量新的图块时,帧速率从60fps下降到零大约一秒钟.这不是由加载图像(以毫秒为单位)引起的,也不是由DrawImage(它根本不花时间,因为它只填充一些中间渲染数据结构)引起的.

我的猜测是每当渲染线程获得大量(~20)新的BitmapSource实例(即它尚未缓存的实例)时,它就会扼流圈.要么花费大量时间将它们转换为某种内部DirectX兼容格式,要么它可能是一个缓存问题.它不能用完视频RAM; 穿孔器显示低于60MB的峰值,我有256MB.此外,Perforator说所有渲染目标都是硬件加速的,所以也不可能.

任何见解将不胜感激!

提前致谢

丹尼尔

@RandomEngy:
BitmapScalingMode.LowQuality减少了一点问题,但没有摆脱它.我已经按照预期的分辨率加载了瓷砖.它不能是图形驱动程序,它是最新的(Nvidia).
得知缩放需要花费很多时间,我有点惊讶.我理解它的方式,位图(无论其大小)只是作为Direct3D纹理加载,然后硬件缩放.事实上,一旦第一次渲染位图,我可以改变其旋转和缩放而不会进一步冻结.

Ran*_*ngy 3

这不仅仅是大量的图像。只需一张大图像就足以在加载之前阻止渲染,当图像尺寸开始增加到数千时,这一点可能会非常明显。

我同意你的观点,这可能是渲染线程的问题:我做了一个测试,UI 线程仍然愉快地调度消息,而渲染延迟是由于尝试显示完全预缓存的 BitmapImage 而发生的。

它一定是在对图像进行某种转换或准备,就像您推测的那样。我试图在我的应用程序中通过“渲染”但隐藏图像来缓解这种情况,然后在需要显示时显示它。然而,这并不理想,因为渲染冻结无论如何都会发生。

(编辑)

一些后续工作:在对 MS WPF 别名进行讨论后,我发现了导致延迟的原因。在我的 Server 2008 计算机上,它是不支持新 WDDM 驱动程序模型的旧视频驱动程序和调整图像大小的延迟的组合。

如果源图像大小与显示大小不同,则会在图像显示之前延迟渲染线程。默认情况下,图像设置为最高质量,但您可以通过调用更改渲染的缩放选项RenderOptions.SetBitmapScalingMode(uiImage, BitmapScalingMode.LowQuality);。一旦我这样做了,显示图像之前的神秘冻结就消失了。如果您不喜欢缩放时的质量下降,另一种方法是加载 BitmapImage,其 DecodePixelWidth/Height 等于其显示的大小。然后,如果您在后台线程上加载 BitmapImage,则显示它应该没有延迟。