Программно определить, есть ли в системе переключаемая графика
Мы сталкиваемся со следующей проблемой на ноутбуках с переключаемой графикой (AMD Radeon 7670M + Intel 4000) в нашем приложении WPF:
D3DImage, который мы используем для отображения некоторого видео, показывает только черную рамку. Это происходит только тогда, когда для приложения активна дискретная графика (AMD) (режим установлен на высокую производительность). При активной графике Intel (режим энергосбережения) все работает. Похоже, мы не одиноки с этим вопросом. Поиск в Google показал следующие сообщения на форумах AMD:
- СРОЧНО: переключаемая графика и совместное использование ресурсов
- D3DImage не отображаются при настройке переключаемой графики на адаптер Radeon
Я нашел обходной путь, используя D3DImage.CopyBackBuffer - похоже, что буферный буфер действительно содержит правильный кадр - поэтому я попытаюсь отобразить это вместо этого.
Но для того, чтобы применить этот обходной путь только тогда, когда это необходимо, я подхожу к теме этого вопроса: как я узнаю, действительно ли система имеет переключаемую графику?
Я полагаю, что могут быть какие-то способы использования WMI или просмотра реестра, но я был бы очень рад, если бы кто-то указал мне верное направление или даже мог бы привести пример, как это сделать.
Обновить:
Я пробовал EnumDisplayDevices и System.Management.ManagementObjectSearcher. Первый не возвращает все устройства, а последний возвращает. Но, возможно, есть еще лучший способ?
3 ответа
Комбинируя этот вопрос и этот, решением было бы использовать System.Management следующим образом:
internal class Program
{
private static void Main(string[] args)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController");
var mos = searcher.Get();
foreach (ManagementObject mo in mos)
{
foreach (PropertyData property in mo.Properties)
{
if (property.Name == "Description")
{
Console.WriteLine(property.Value);
}
}
}
Console.ReadKey();
}
}
Мое оборудование:
И результат:
Поскольку у меня есть не совсем аппаратное устройство под названием "DameWare Development Mirror", вы также можете посмотреть свойство VideoProcessor. Для NVidea и Intel они будут иметь свое значение, для несуществующих устройств - NULL.
if (property.Name == "Description")
Console.WriteLine(property.Value);
if (property.Name == "VideoProcessor")
Console.WriteLine(property.Value);
А для определения активной видеокарты вы можете проверить, имеет ли свойство CurrentBitsPerPixel значение
Может быть, поиск имени водителя другой ответ. Но это не совсем правильно. Потому что возможно обновление драйвера. Поэтому я предпочитаю использовать System.Management.ManagementObjectSearcher.
Если повезет, вы можете использовать запросы WMI, чтобы получить эту информацию с System.Management.ManagementObjectSearcher
, но это может быть очень тесно связано с версиями Windows и драйверов.
Я думаю, что ваша настоящая проблема в том, что вы пропускаете ключевое событие, когда аппаратное устройство теряется и аппаратные ресурсы (поверхности и выделенная память VRAM) сбрасываются. Попробуйте подписаться на подобные события https://msdn.microsoft.com/en-us/library/system.windows.interop.d3dimage.isfrontbufferavailablechanged.aspx, чтобы отследить переключение и перестроить аппаратные поверхности в новый графический контекст.