Вопрос

I'm using D3DImage as part of my WPF user control. Very rarely, when rendering, the D3DImage.TryLock fails.

So far, I haven't been able to find any documentation as to why D3D.TryLock would fail. Does anyone know why this might be happening?

Это было полезно?

Решение

Look at this in the Remarks section. It states:

Occasionally, the front buffer becomes unavailable. This lack of availability can be caused by screen locking, full-screen exclusive Direct3D applications, user-switching, or other system activities. When this occurs, your WPF application is notified by handling the IsFrontBufferAvailableChanged event.

It says this in relationship to the Unlock method, which pushes the backbuffer contents to the frontbuffer. But I imagine that if you acquire a lock and call Unlock, at which point it fails because it cannot write to the frontbuffer for whatever reason, the lock may be retained until it is successfully unlocked, at which time a call to TryLock would fail. I imagine something like this:

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.

I have seen this issue occur in some native DirectX development when using BeginDraw and EndDraw improperly, so it could be your solution. That's about all I have. Hope it helps!

As is stated in that block comment, you can check to see if this is the case by adding an event to the IsFrontBufferAvailableChanged event. If it is not, you can handle the issue appropriately by not calling the TryLock/Unlock combo, essentially skipping a render when the front buffer is unavailable. More information on this event handler can be found here. And the remarks on this page have further information on how you can better handle when this event is raised. It states:

The SetBackBuffer method has an overload that takes a parameter that specifies whether WPF falls back to software rendering.

Другие советы

Please note that even when TryLock fails, you must call Unlock. The MSDN documentation isn't mentioning this explicitly. See the source code D3DImage.TryLock, it calls LockImpl, and that method always increments the internal reference count...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top