Сбой D3DImage TryLock
Я использую D3DImage как часть моего пользовательского элемента управления WPF. Очень редко при рендеринге происходит сбой D3DImage.TryLock.
До сих пор я не смог найти никакой документации о том, почему D3D.TryLock потерпит неудачу. Кто-нибудь знает, почему это может происходить?
2 ответа
Посмотрите на это в разделе "Замечания". Говорится:
Иногда передний буфер становится недоступным. Это отсутствие доступности может быть вызвано блокировкой экрана, полноэкранными эксклюзивными приложениями Direct3D, переключением пользователей или другими действиями системы. Когда это происходит, приложение WPF уведомляется путем обработки события IsFrontBufferAvailableChanged.
Это говорит об этом по отношению к 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.
Я видел, что эта проблема возникает в какой-то разработке DirectX при использовании BeginDraw
а также EndDraw
неправильно, так что это может быть вашим решением. Это обо всем, что у меня есть. Надеюсь, поможет!
Как указано в этом комментарии к блоку, вы можете проверить, так ли это, добавив событие в IsFrontBufferAvailableChanged
событие. Если это не так, вы можете решить проблему соответствующим образом, не вызывая TryLock
/Unlock
combo, пропускающий рендер, когда передний буфер недоступен. Более подробную информацию об этом обработчике событий можно найти здесь. И замечания на этой странице содержат дополнительную информацию о том, как вы можете лучше справиться с этим событием. Говорится:
У метода SetBackBuffer есть перегрузка, которая принимает параметр, который указывает, возвращается ли WPF к программному отображению.
Обратите внимание, что даже когда TryLock
не удается, вы должны позвонить Unlock
, Документация MSDN не упоминает об этом явно. Посмотрите исходный код D3DImage.TryLock, он вызывает LockImpl
и этот метод всегда увеличивает внутренний счетчик ссылок...