WPF使用BitmapSource渲染性能

时间:2009-04-30 09:24:10

标签: wpf performance bitmap rendering

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

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

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

任何见解都将不胜感激!

提前致谢

丹尼尔

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

2 个答案:

答案 0 :(得分:3)

这不仅仅是大量的图像。只有一个大图像足以阻止渲染,直到它被加载为止,当图像尺寸开始增加数千时,这可能非常明显。

我同意你的意见,它可能是渲染线程:我做了一个测试,UI线程仍然很乐意调度消息,而这个渲染延迟是在尝试显示一个完全预先缓存的BitmapImage时发生的。

它必须在图像上进行某种转换或准备,就像你在猜测一样。我试图在我的应用程序中通过“渲染”来缓解这个问题,但隐藏了图像,然后在我需要显示它时显示它。然而,这并不理想,因为无论如何都会发生渲染冻结。

(编辑)

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

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

答案 1 :(得分:0)

也试试这些;

/* ivis is declared in XAML <Image x:Name="iVis" UseLayoutRounding="True" SnapsToDevicePixels="True" /> */

iVis.Stretch = Stretch.None;
RenderOptions.SetBitmapScalingMode(iVis, BitmapScalingMode.NearestNeighbor);
RenderOptions.SetEdgeMode(iVis, EdgeMode.Aliased);
VisualBitmapScalingMode = BitmapScalingMode.NearestNeighbor;
iVis.Source = **** your bitmap source ****

在使用大量的“A”频道颜色时,我遇到了一些性能问题,等到图像渲染到规模后,它对我来说效果更好。

另外,正如你所说的使用平铺图形?

您通常会使用TileBrush在FrameworkElement上设置为Brush。如果您动画它们或动态添加新动画,您可以生成画笔,然后在手动移动时将它们应用到您的对象,如果可以,请务必冻结它们。此外,VisualBitmapScalingMode是任何Visual。

的属性