Подключено два дисплея: телевизор 1920x1080@59 и монитор 1680x1050@75. Изначально рабочий стол расширен только на монитор.
Запускаю тестовое видео в окне на мониторе. Расширяю рабочий стол на два дисплея. Перевожу окно на телевизор. При разворачивании окна или переходе на полный экран получаю некорректное положение кадра и некорректную информацию в статистике
(http://s020.radikal.ru/i700/1509/33/6b218129c93at.jpg) (http://s020.radikal.ru/i700/1509/33/6b218129c93a.jpg)
(http://s017.radikal.ru/i442/1509/23/146168fa9c44t.jpg) (http://s017.radikal.ru/i442/1509/23/146168fa9c44.jpg)
А галка "Реинициализация при смене монитора" выставлена ?? Если нет - то оно и понятно.
"Реинициализация при смене монитора" включена.
Если расширить рабочий стол на оба дисплея до запуска плеера, то проблемы нет.
Ну ты глянь в отладчике - почему не вызывается реинициализация. Делов то :)
Ситуация немного прояснилась.
Проверял немного на другой конфигурации. Основной монитор на дискретке и подключаемый во время воспроизведения телевизор на встройке.
В такой конфигурации проблема возникает из-за того, что pD3D->GetAdapterCount() всегда выдает 1.
Возможно надо как-то отлавливать расширение рабочего стола и производить m_pD3D->CreateDevice, все равно экран мигает.
[merge_posts_bbcode]Добавлено: 2016-01-06 20:56:13[/merge_posts_bbcode]
Еще заметил, что мы постоянно дергаем функцию GetAdapter(). Хотя по идее это надо делать по событию, например при смене монитора.
Как раз вызов GetAdapter() делается для проверки на смену монитора :)
Вообще-то рендерер должен принять WM_DISPLAYCHANGE и затем отдать EC_DISPLAY_CHANGED.
Дергать каждый раз GetAdapter(), который к тому же не всегда срабатывает, ненужно.
[merge_posts_bbcode]Добавлено: 2016-01-07 08:54:53[/merge_posts_bbcode]
Собственно в CBaseRenderer::OnDisplayChange() это и происходит. Только вот наши видеорендереры его не используют.
1 - OnDisplayChange() у нас обрабатывается в CMainFrame и затем отдается команда рендереру. Но - это не то событие. Можешь сам в отладчике либо с помощью Spy++ - будет ли посылаться событие WM_DISPLAYCHANGE в случае перемещения окна с одного экрана на другой.
WM_DISPLAYCHANGE посылается приложению когда меняется разрешение/ориентация экрана.
А вот отследить перемещение между экранами можно только таким способом, по таймеру проверять текущий адаптер, либо текущий монитор.
Вот что происходит при расширении с одного монитора на два.
(http://s017.radikal.ru/i430/1601/b9/aa479a60285at.jpg) (http://s017.radikal.ru/i430/1601/b9/aa479a60285a.png)
Тут два вызова WM_DISPLAYCHANGE, но мы их игнорируем. Возможно поэтому плеер определяет неверное количество адаптеров.
Цитата: Aleksoid1978А вот отследить перемещение между экранами можно только таким способом, по таймеру проверять текущий адаптер, либо текущий монитор.
Есть как минимум WM_MOVE и WM_WINDOWPOSCHANGED, которые по-любому будут вызваны при перемещении плеера с одного монитора на другой. Смысла проверять перед прорисовкой каждого кадра не вижу.
А при чем здесь 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(), т.е. более плавно.
Цитата: 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
Обе сборки работают корректно. Разницы не увидел.
Значит отлично - тему закрываем, изменения заливаю.