本文介绍了如何检测WPF控件何时被重绘?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在使用D3DImage显示一个帧序列,这些帧一个接一个地渲染到同一Direct3D Surface上。我现在的逻辑是这样的:
- 显示上次渲染的帧(即D3DImage.Lock()/AddDirtyRect()/unlock())
- 开始渲染下一帧
- 等待下一帧准备就绪,是时候显示它了
- 显示上次渲染的帧
- .
这种方法的问题在于,当我们完成对D3DImage的unlock()调用时,实际上并没有复制图像,它只计划在下一次WPF渲染时复制。因此,我们有可能在WPF有机会显示新帧之前,在Direct3D表面上呈现一个新帧。最终结果是我们在显示器上看到丢失的帧。
现在,我正在试验使用单独的Direct3D纹理进行渲染,并在显示前执行到"显示纹理"的复制,这样可以获得更好的效果,但会产生大量开销。最好能够知道D3DImage何时完成刷新,并在刷新后立即开始渲染下一帧。这是可能的吗?如果是的话,是如何实现的?或者你有更好的主意吗?谢谢。
推荐答案
为了与UI并行呈现,执行此操作的干净方法似乎是呈现到单独的D3D图面中,并在调用Lock()和Unlock()之间将其复制到显示图面(即传递给SetBackBuffer的图面)。因此算法变成:
- 复制并显示最后渲染的帧,即
Lock()
- 从渲染复制到显示图面
SetBackBuffer(displaySurface)
AddDirtyRect()
Unlock()
- 计划对渲染图面进行新渲染
- 等待它完成并确定显示时间
- 转到%1
D3DImage文档explicitely states:
这里的痛点是拷贝,这可能很昂贵(即,如果硬件繁忙,则大于2ms)。为了在解锁D3DImage时使用显示图面(避免渲染时潜在的代价高昂的操作),用户将不得不求助于反汇编和反射来挂钩到D3DImage自己的渲染中.这篇关于如何检测WPF控件何时被重绘?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!