我正在使用D3DImage作为我的WPF用户控件的一部分。很少,在渲染时,D3DImage.TryLock失败。
到目前为止,我还没有找到任何关于为什么D3D.TryLock会失败的文档。 有谁知道为什么会发生这种情况?
答案 0 :(得分:2)
Look at this。它声明:
有时,前端缓冲区变得不可用。这种缺乏可用性可能是由屏幕锁定,全屏独有的Direct3D应用程序,用户切换或其他系统活动引起的。发生这种情况时,将通过处理IsFrontBufferAvailableChanged事件来通知您的WPF应用程序。
它与Unlock
方法有关,它将后备缓冲内容推送到前缓冲区。但是我想如果你获得一个锁并调用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.
我发现在使用BeginDraw
和EndDraw
时,在某些本机DirectX开发中会出现此问题,因此它可能是您的解决方案。这就是我所拥有的一切。希望它有所帮助!
正如该块注释中所述,您可以通过向IsFrontBufferAvailableChanged
事件添加事件来检查是否是这种情况。如果不是,您可以通过不调用TryLock
/ Unlock
组合来适当地处理问题,实质上是在前端缓冲区不可用时跳过渲染。有关此事件处理程序的更多信息,请参见here。而且this page上的评论还提供了有关如何在发生此事件时更好地处理的更多信息。它声明:
SetBackBuffer方法有一个重载,它带有一个参数,指定WPF是否回退到软件渲染。
答案 1 :(得分:0)
请注意,即使TryLock
失败,也必须呼叫Unlock
。 MSDN文档没有明确提及这一点。参见源代码D3DImage.TryLock,它调用LockImpl
,并且该方法总是增加内部引用计数...