Некорректная работа в мультимониторной конфигурации [Исправлено]

Автор V0lt, 25 сентября 2015, 19:05:23

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

V0lt

Подключено два дисплея: телевизор 1920x1080@59 и монитор 1680x1050@75. Изначально рабочий стол расширен только на монитор.
Запускаю тестовое видео в окне на мониторе. Расширяю рабочий стол на два дисплея. Перевожу окно на телевизор. При разворачивании окна или переходе на полный экран получаю некорректное положение кадра и некорректную информацию в статистике



Aleksoid1978

А галка "Реинициализация при смене монитора" выставлена ?? Если нет - то оно и понятно.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

"Реинициализация при смене монитора" включена.
Если расширить рабочий стол на оба дисплея до запуска плеера, то проблемы нет.

Aleksoid1978

Ну ты глянь в отладчике - почему не вызывается реинициализация. Делов то :)
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Ситуация немного прояснилась.
Проверял немного на другой конфигурации. Основной монитор на дискретке и подключаемый во время воспроизведения телевизор на встройке.
В такой конфигурации проблема возникает из-за того, что pD3D->GetAdapterCount() всегда выдает 1.

Возможно надо как-то отлавливать расширение рабочего стола и производить m_pD3D->CreateDevice, все равно экран мигает.
[merge_posts_bbcode]Добавлено: 2016-01-06 20:56:13[/merge_posts_bbcode]

Еще заметил, что мы постоянно дергаем функцию GetAdapter(). Хотя по идее это надо делать по событию, например при смене монитора.

Aleksoid1978

Как раз вызов GetAdapter() делается для проверки на смену монитора :)
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Вообще-то рендерер должен принять WM_DISPLAYCHANGE и затем отдать EC_DISPLAY_CHANGED.
Дергать каждый раз GetAdapter(), который к тому же не всегда срабатывает, ненужно.
[merge_posts_bbcode]Добавлено: 2016-01-07 08:54:53[/merge_posts_bbcode]

Собственно в CBaseRenderer::OnDisplayChange() это и происходит. Только вот наши видеорендереры его не используют.

Aleksoid1978

1 - OnDisplayChange() у нас обрабатывается в CMainFrame и затем отдается команда рендереру. Но - это не то событие. Можешь сам в отладчике либо с помощью Spy++ - будет ли посылаться событие WM_DISPLAYCHANGE в случае перемещения окна с одного экрана на другой.
WM_DISPLAYCHANGE посылается приложению когда меняется разрешение/ориентация экрана.

А вот отследить перемещение между экранами можно только таким способом, по таймеру проверять текущий адаптер, либо текущий монитор.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Вот что происходит при расширении с одного монитора на два.

Тут два вызова WM_DISPLAYCHANGE, но мы их игнорируем. Возможно поэтому плеер определяет неверное количество адаптеров.

Цитата: Aleksoid1978А вот отследить перемещение между экранами можно только таким способом, по таймеру проверять текущий адаптер, либо текущий монитор.
Есть как минимум WM_MOVE и WM_WINDOWPOSCHANGED, которые по-любому будут вызваны при перемещении плеера с одного монитора на другой. Смысла проверять перед прорисовкой каждого кадра не вижу.

Aleksoid1978

А при чем здесь WM_DISPLAYCHANGE и кол-во адаптеров ??

А по поводу обработки сообщений WM_MOVE/WM_WINDOWPOSCHANGED или любых других - эти сообщения мы обрабатываем в основном окне, но ни как не силами видео-рендерера.

И проверка делается не перед прорисовкой каждого кадра - а по таймеру. madVR делает точно так же.
[merge_posts_bbcode]Добавлено: 2016-01-07 18:15:51[/merge_posts_bbcode]

И еще, самое главное - по событию WM_DISPLAYCHANGE нельзя отличить смену монитора от смены разрешения. Так же - событие WM_DISPLAYCHANGE не генерируется при условии одинакового разрешения на разных экранах(проверил у себя, монитор + TV, оба FullHD). Так что с помощью этого события нельзя отследить смену экрана.
[merge_posts_bbcode]Добавлено: 2016-01-07 19:25:40[/merge_posts_bbcode]

Кажется я понял почему если после открытия файла подключить второй монитор/расширить рабочий стол рендерер этого не видит. А потому что m_pD3D создается в конструкторе видео-рендерера и далее в ::GetAdapter() идет опрос на кол-во адаптеров.

Чтобы этого избежать - надо делать полную реинициализацию по какому-то событию.

Еще вот что - я заметил что у тебя на статистике(на первом скрине) отсутствует название адаптера, это как раз из-за того что функция ::GetAdapter() очищает названия текущего адаптера но и потом не заполняет, т.к. просто ничего не знает о его существовании.

[merge_posts_bbcode]Добавлено: 2016-01-07 20:08:11[/merge_posts_bbcode]

Вот пробуем тестовый билд - https://yadi.sk/d/_rE8jYPmmimmy
Теперь при включении/отключении мониторов или изменений работы в мультимониторной конфигурации(в случае если кол-во "адаптеров" изменилось) - будет срабатывать ResetDevice(). И после этого уже должно корректно обрабатываться перемещение между мониторами.

[merge_posts_bbcode]Добавлено: 2016-01-07 23:24:26[/merge_posts_bbcode]

А вот еще один билд https://yadi.sk/d/DHTe_D1fmj7iE - в нем, в отличии от предыдущего, по событию WM_DISPLAYCHANGE не происходит ResetDevice(), т.е. более плавно.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Цитата: Aleksoid1978А при чем здесь WM_DISPLAYCHANGE и кол-во адаптеров ??
Я написал, что расширение рабочего стола с одного монитора на два стола вызывает эти события. Можно и к другим привязаться, если легче. На скриншоте все показано.
[merge_posts_bbcode]Добавлено: 2016-01-07 18:41:46[/merge_posts_bbcode]

ЦитироватьВот пробуем тестовый билд - https://yadi.sk/d/_rE8jYPmmimmy
...
А вот еще один билд https://yadi.sk/d/DHTe_D1fmj7iE
Обе сборки работают корректно. Разницы не увидел.

Aleksoid1978

Значит отлично - тему закрываем, изменения заливаю.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215