本文介绍了如何检测WPF控件何时被重绘?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用D3DImage显示一个帧序列,这些帧一个接一个地渲染到同一Direct3D Surface上。我现在的逻辑是这样的:

  • 显示上次渲染的帧(即D3DImage.Lock()/AddDirtyRect()/unlock())
  • 开始渲染下一帧
  • 等待下一帧准备就绪,是时候显示它了
  • 显示上次渲染的帧
  • .

这种方法的问题在于,当我们完成对D3DImage的unlock()调用时,实际上并没有复制图像,它只计划在下一次WPF渲染时复制。因此,我们有可能在WPF有机会显示新帧之前,在Direct3D表面上呈现一个新帧。最终结果是我们在显示器上看到丢失的帧。

现在,我正在试验使用单独的Direct3D纹理进行渲染,并在显示前执行到"显示纹理"的复制,这样可以获得更好的效果,但会产生大量开销。最好能够知道D3DImage何时完成刷新,并在刷新后立即开始渲染下一帧。这是可能的吗?如果是的话,是如何实现的?或者你有更好的主意吗?

谢谢。

推荐答案

为了与UI并行呈现,执行此操作的干净方法似乎是呈现到单独的D3D图面中,并在调用Lock()和Unlock()之间将其复制到显示图面(即传递给SetBackBuffer的图面)。因此算法变成:

  1. 复制并显示最后渲染的帧,即
    • Lock()
    • 从渲染复制到显示图面
    • SetBackBuffer(displaySurface)
    • AddDirtyRect()
    • Unlock()
  2. 计划对渲染图面进行新渲染
  3. 等待它完成并确定显示时间
  4. 转到%1

D3DImage文档explicitely states

这里的痛点是拷贝,这可能很昂贵(即,如果硬件繁忙,则大于2ms)。为了在解锁D3DImage时使用显示图面(避免渲染时潜在的代价高昂的操作),用户将不得不求助于反汇编和反射来挂钩到D3DImage自己的渲染中.

这篇关于如何检测WPF控件何时被重绘?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-16 08:55