我使用 D3DImage 作为我的 WPF 用户控件的一部分。很少,在渲染时, D3DImage.TryLock 失败。
到目前为止,我还没有找到任何关于 D3D.TryLock 为什么会失败的文档。有谁知道为什么会发生这种情况?
在备注部分查看此内容。它指出:
有时,前端缓冲区变得不可用。这种可用性不足的原因可能是屏幕锁定、全屏独占 Direct3D 应用程序、用户切换或其他系统活动。发生这种情况时,您的 WPF 应用程序会通过处理 IsFrontBufferAvailableChanged 事件得到通知。
它与Unlock
将后缓冲区内容推送到前缓冲区的方法有关。但是我想,如果您获取 lock 并调用Unlock
,此时它会失败,因为它由于某种原因无法写入前端缓冲区,锁可能会一直保留到它被成功解锁,此时调用TryLock
会失败。我想象这样的事情:
image.TryLock
// image gets written to
image.Unlock // fails for one of the listed reasons, lock is retained
// loop
image.TryLock // fails because lock is already acquired
image.Unlock // succeeds because the previously successful lock is still in
// place and the issue that caused the previous failure of Unlock
// has since subsided.
我在一些原生 DirectX 开发中看到这个问题在使用BeginDraw
和EndDraw
不正确的时候出现,所以它可能是你的解决方案。这就是我所拥有的一切。希望能帮助到你!
如该块注释中所述,您可以通过向事件添加事件来检查是否是这种情况IsFrontBufferAvailableChanged
。如果不是,您可以通过不调用TryLock
/Unlock
组合来适当地处理该问题,实质上是在前端缓冲区不可用时跳过渲染。可以在此处找到有关此事件处理程序的更多信息。并且此页面上的注释提供了有关如何更好地处理此事件时的更多信息。它指出:
SetBackBuffer 方法有一个重载,它采用一个参数,该参数指定 WPF 是否回退到软件呈现。
请注意,即使TryLock
失败,您也必须调用Unlock
. MSDN 文档没有明确提到这一点。请参阅源代码 D3DImage.TryLock,它调用LockImpl
,并且该方法始终增加内部引用计数...