WPF渲染性能的BitmapSource [英] WPF render performance with BitmapSource

查看:923
本文介绍了WPF渲染性能的BitmapSource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've created a WPF control (inheriting from FrameworkElement) that displays a tiled graphic that can be panned. Each tile is 256x256 pixels at 24bpp. I've overridden OnRender. There, I load any new tiles (as BitmapFrame), then draw all visible tiles using drawingContext.DrawImage.

现在,每当有每个渲染周期超过了一把新瓦片,帧率60fps的从零降至约1秒钟。这不是由加载图像(其发生在毫秒的数量级)引起的,也没有通过的DrawImage(这需要任何时间在所有的,因为它仅仅是填充一些中间呈现数据结构)。

Now, whenever there are more than a handful new tiles per render cycle, the framerate drops from 60fps to zero for about a second. This is not caused by loading the images (which takes in the order of milliseconds), nor by DrawImage (which takes no time at all, as it merely fills some intermediate render data structure).

我的猜测是,渲染线程本身扼流圈一旦进入新的BitmapSource实例的大量(约20)(即那些它尚未缓存)。它要么花费大量的时间把它们转换成一些内部DirectX兼容的格式,或者它可能是一个缓存的问题。它不能运行的视频RAM;射孔显示峰低于6​​0MB,我有256MB。此外,穿孔说,所有的渲染目标是硬件加速,所以不可能是它,无论是。

My guess is that the render thread itself chokes whenever it gets a large number (~20) of new BitmapSource instances (that is, ones it had not already cached). Either it spends a lot of time converting them to some internal DirectX-compatible format or it might be a caching issue. It cannot be running out of video RAM; Perforator shows peaks at below 60MB, I have 256MB. Also, Perforator says all render targets are hardware-accelerated, so that can't be it, either.

任何见解将是AP preciated!

Any insights would be appreciated!

在此先感谢

丹尼尔

@RandomEngy:结果
BitmapScalingMode.LowQuality减少问题了一点,但并没有摆脱它。我已经加载在预期的分辨率瓷砖。它不能是图形驱动程序,这是先进的日期(Nvidia的)。结果,
我有点惊讶地得知,缩放花费那​​么多的时间。我的理解是这样的,一个位图(无论大小)只是加载一个Direct3D的纹理,然后硬件缩放。作为事实上,一旦位图被渲染为第一次,我可以改变它的旋转和比例不经任何进一步冻结。

@RandomEngy:
BitmapScalingMode.LowQuality reduced the problem a little, but did not get rid of it. I am already loading tiles at the intended resolution. And it can't be the graphics driver, which is up-to-date (Nvidia).
I'm a little surprised to learn that scaling takes that much time. The way I understood it, a bitmap (regardless of its size) is just loaded as a Direct3D texture and then hardware-scaled. As a matter of fact, once the bitmap has been rendered for the first time, I can change its rotation and scale without any further freezes.

推荐答案

这不只是有大量图像。只是一个大的图像,就足以撑起渲染,直到它被加载,并且可以当你的图像尺寸开始在千元起来相当noticable。

It's not just with a large number of images. Just one large image is enough to hold up rendering until it has been loaded in, and that can be quite noticable when your image dimensions start getting up in the thousands.

我不同意你的看法,它是可能的渲染线程:我做了一个测试,并在UI线程仍然兴高采烈地调度信息,同时此呈现延迟从试图显示完全pre-缓存的BitmapImage发生

I do agree with you that it's probably the render thread: I did a test and the UI thread was still happily dispatching messages while this render delay was taking place from trying to display a fully pre-cached BitmapImage.

必须做在图像上某种转换或preparation,像你猜测。我试图通过渲染,但隐藏的图像,然后露出它的时候,我需要表现出来,以减轻这在我的应用程序。然而,这是不太理想的,因为渲染冻结仍会发生。

It must be doing some sort of conversion or preparation on the image, like you were speculating. I've tried to mitigate this in my app by "rendering" but hiding the image, then revealing it when I need to show it. However this is less than ideal because the rendering freezes happen anyway.

(编辑)

一些后续:在MS WPF别名,我发现是什么原因导致的延误讨论之后。在我的Server 2008的机器是不支持新的WDDM驱动程序模型和调整图像的延迟旧的视频驱动程序的组合。

Some followup: After a discussion on the MS WPF alias I found what was causing the delays. On my Server 2008 machine it was a combination of old video drivers that don't support the new WDDM driver model and a delay for resizing the image.

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

If the source image size is different from the display size, that will delay the render thread before the image shows up. By default an image is set to the highest quality, but you can change the scaling options for rendering by calling RenderOptions.SetBitmapScalingMode(uiImage, BitmapScalingMode.LowQuality); . Once I did that, the mysterious freeze before displaying an image went away. An alternative, if you don't like the quality drop in scaling, is to load the BitmapImage with DecodePixelWidth/Height equal to the size it will be displayed at. Then if you load the BitmapImage on a background thread, you should have no delay in displaying it.

这篇关于WPF渲染性能的BitmapSource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆