图像控件,D3DImage和脏矩形 [英] The Image control, D3DImage and dirty rects

查看:95
本文介绍了图像控件,D3DImage和脏矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在等待对WriteableBitmap控件的承诺修复,正如MSDN论坛上众多文章所证明的那样,该控件过去曾遇到严重的性能问题.我最近用WriteableBitmap和D3DImage做了一些测试 看看脏的rect现在是否可以正常工作,甚至在更新位图的一小部分时也不会导致我的应用程序占用CPU.

在我的测试应用程序中,D3DImage的Source属性设置为D3DImage实例,并且我(成功)验证了如果我调用D3DImage的AddDirtyRect(),则只有修改后的像素将从后缓冲区复制到前缓冲区.

然而,根据Perforator,图像控件(或至少在渲染路径中的某物")仍然认为整个位图已经被更新,这导致整个位图被重新渲染.对于分层窗口,这尤其成问题 如果位图占用了窗口的整个大小,因为它涉及将窗口的所有像素从视频内存复制到系统内存,然后又向下又回到视频内存.

要验证Perforator不是在脏矩形上说谎,我在UpdateLayeredWindowIndirect()上设置了一个断点,并得到了以下脏矩形[9,134,1291,781],它与窗口中Image控件的大小相对应

那么,话虽如此,有人可以告诉我是什么导致WPF认为整个Image脏了吗?由于此原因,我看到的主要性能下降是因为我使用的位图非常大,甚至更新其中的一小部分也会导致 整个位图都将被重新渲染.

解决方案

Soren,

Wmm,D3DImage仅从缓冲区更新修改后的矩形.但是WriteableBitmap不会,它会更新整个位图.您是否已在WPF中就此建议提交了反馈? Microsoft Connect网站?如果没有,我想我们可以提交一个,谢谢.

WriteableBitmap 类调用"wpfgfx_v0400.dll"的方法 MILSwDoubleBufferedBitmapAddDirtyRect( AddDirthRect) (或版本0300),并且此dll用于提供图形功能.从WPF 3.5开始,一个 博客对其进行了介绍:媒体集成层(MIL),并用于与DX通信,

(wpfgfx_vxxx.dll在WPF之后替换了milcore 3.5)

,它也是WriteableBitmap的双缓冲模式.我们知道,在Vista之前的Windows操作系统中,系统使用双缓冲图形来防止在窗口更改期间出现闪烁和撕裂.双缓冲区以及不重绘未更改的区域, 因此我们将在此处找到代表更改区域的参数(Int32RectdirtyRect).因此,您应该尝试检查调用堆栈(通过windbg或其他调试工具),以查找在哪里/哪个代码调用了 WriteableBitmap.AddDirtyRect 方法.

此致


I've been eagerly awaiting the promised fixes to the WriteableBitmap control, which, as evidenced by the numerous posts here on the MSDN forums, has had significant performance issues in the past. I recently did a few tests with WriteableBitmap and D3DImage to see if dirty rects are now working properly and wouldn't cause my application to hog the CPU when updating even a small part of the bitmap.

In my test application, the Source property of D3DImage is set to the D3DImage instance and I (successfully) verified that if I called D3DImage's AddDirtyRect(), only the modified pixels would be copied from the back buffer to the front buffer.

However, according to Perforator, the Image control (or "something" in the rendering path, at least) still considers the entire bitmap to have been updated, which causes the entire bitmap to be re-rendered. This is especially problematic for layered windows if the bitmap takes up the entire size of the window since it involves copying all the window's pixels from video memory to system memory and then back down to video memory again.

To verify that Perforator wasn't lying about the dirty rects, I set a breakpoint on UpdateLayeredWindowIndirect() and got the following dirty rect [9,134,1291,781], which corresponds with the size of the Image control in the window.

So, with all that said, can anybody tell me what's causing the entire Image to be considered dirty by WPF? I'm seeing major performance degradation due to this because the bitmaps I'm using are quite large, and even updating a small part of it causes the entire bitmap to be re-rendered.

解决方案

Hi Soren,

Wmm, D3DImage only updates the modified retangle from buffer. But WriteableBitmap does not, it updates the entire bitmap. Do you have submit a feedback for this suggestion in WPF on the Microsoft Connect site? If not, I think we could submit one, and thanks.

WriteableBitmap class invoke the method MILSwDoubleBufferedBitmapAddDirtyRect (AddDirthRect) of the "wpfgfx_v0400.dll" (or version 0300), and this dll is used to provide the graphics functions. Start from WPF 3.5, one blog introduces it: http://blogs.msdn.com/b/jgoldb/archive/2008/05/15/what-s-new-for-performance-in-wpf-in-net-3-5-sp1.aspx it is also used by DWM. From the enter point name, we know it is one part of Media Integration Layer (MIL), and used to communicate with DX,

(wpfgfx_vxxx.dll has replaced the milcore after WPF 3.5)

and also it is a double buffer mode for the WriteableBitmap. We know, in pre-Vista Windows OSs, system uses double-buffered graphics to prevent flickering and tearing during window changes. The double buffer as well as not redrawing areas that haven't changed, so we will find the parameter (Int32Rect dirtyRect) here which represents the area that changed. So you should try to check the call stack (by windbg or other debug tool) to find where/which code invoke the WriteableBitmap.AddDirtyRect method.

Sincerely,


这篇关于图像控件,D3DImage和脏矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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