1

我有一个控件,它使用 D3DImage 来托管 SharpDX DirectX9 表面,并允许用于平移、缩放和与世界对象交互,结果非常棒。性能实际上是惊人的一致 60fps,除非窗口被最小化并重新打开,或者用户锁定然后解锁屏幕。当窗口重新获得焦点时,fps 下降到大约 25-30fps。我可以通过将控件卸载并加载回其容器然后 BOOM,60fps 来“修复”该问题。

我使用设置为 10 毫秒的 DispatcherTimer 调用主渲染函数。之前,我使用的是 CompositionTarget.Rendering 事件,但性能不如使用 DispatcherTimer。我相当确定我正在正确处理丢失的资源。关于这些每秒丢失的帧有什么想法吗?

编辑: 我有同样的问题。不幸的是,进行自动设备重置并不能解决问题,但如果我有一个执行相同重置方法的按钮,那么我的 fps 会恢复正常。

4

2 回答 2

2

锁定/解锁屏幕会导致设备丢失。但你可能知道这一点。

无论如何,我也在 WPF 中使用 D3DImage 。当我打电话时,我的性能问题就结束了

D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero)

在每台丢失的设备上。我曾经在设备丢失后遇到响应问题,直到我意识到 WPF 仍然持有对纹理的引用。当然,当您有更新的纹理时,您应该稍后重新设置后台缓冲区。

虽然不清楚幕后究竟出了什么问题,但很明显 D3DImage 会为您的纹理保留一个引用计数,这可能会在设备丢失的情况下阻止成功恢复。就我而言,我们根本没有更新。

对于轶事的回答很抱歉...但是在真正的 D3DImage 专家进入房间之前,总比没有好。

PS 我正在使用 SlimDX,但我认为这并不重要……据我所知,SharpDX 是 SlimDX 的一个分支。

于 2012-11-13T22:05:29.803 回答
0

有一个重载SetBackBuffer需要一个额外的Boolean标志:

D3DImage.SetBackBuffer(D3DResourceType, IntPtr, Boolean)

当调用SetBackBuffer (D3DResourceType, IntPtr) 重载,或者调用 SetBackBuffer(D3DResourceType, IntPtr, Boolean) 重载且enableSoftwareFallback参数设置为 false 时,[WPF] 渲染系统在前缓冲区变为不可用且不显示任何内容。

我也不是专家,但我猜这就是正在发生的事情;因为您没有将该标志设置为“true”,所以 WPFRelease()在退出锁定后立即调用 D3D 表面的最后一个 COM 引用计数。这似乎需要您维护自己的额外引用计数。

一方面,我注意到,即使在从 WPF 锁定/解锁往返“返回”“使用”表面之后,您仍然需要在下一个表面取代它之前释放它(即成功调用d3dimg.SetBackBuffer)。否则,当 WPF 窗口在屏幕上拖动时会闪烁。鉴于这是我发现的用于检测 WPF 何时真正使用您的缓冲区的唯一可靠方法,因此 WPF 关注 AddRef'ing 或 Release'ing 它似乎毫无意义。

通常令人困惑的D3DImage是,IDirect3DDevice9正在运行的 WPF 并没有真正与IDirect3DDevice9生成你作为后台缓冲区的表面的那个相关联......对于 WPF。整个Lock/Unlock业务大概是为了 WPF 的利益,与你自己的(可能是可锁定的?)IDirect3DSurface9rendertarget 的生存无关。


谨防!
如果使用D3DImage.TryLock,请注意它,嗯......我们应该说,非常规语义:即使在返回falseUnlock的情况下也必须调用。有关更多信息,请参阅https://stackoverflow.com/a/39581727/147511TryLock

于 2016-09-19T19:19:11.003 回答