Получение полного скриншота рабочего стола из графического процессора

Я использую функцию Windows API BitBlt для выполнения захвата экрана.

Однако есть много недостатков:

  • DWM и Aero вызывают значительное замедление (3 мс → 35 мс только для вызова BitBlt) - для работы вокруг этого потребуется отключить Aero, которого я просто не делал. Экран мерцает и все меняется.
  • Данные должны быть перенесены на GPU для загрузки данных в виде текстуры
  • Слоистые окна не могут быть захвачены без флага CAPTUREBLT. Когда включено, курсор мыши мигает при захвате. Это может показаться второстепенной проблемой, но это чрезвычайно раздражает, когда приложение в противном случае не содержит ошибок. В качестве обходного пути я намереваюсь отображать многоуровневое окно в качестве дополнительного курсора.

Я уже использую OpenGL для отображения и обработки захваченных данных экрана. BitBlt дает мне пиксельные данные, и относительно легко загрузить их в текстуру. Однако это немного абсурдно, потому что я вручную пересылаю данные обратно на GPU, когда он должен быть доступен на графическом процессоре для начала. Данные, безусловно, есть, но попытка получить доступ к нему - это другое дело.

Я предполагаю, что эта функция невелика в списке дел (или, вероятно, в любом списке для этого) для поставщиков, но я хотел бы попросить тех, кто знает, существуют ли какие-либо положения, предоставленные AMD ( ATI) или NVidia в своих драйверах для чтения экранного буфера (например, в контексте OpenGL). Я просто не знаю достаточно о современной архитектуре графического процессора, чтобы знать, с чего начать копать ответы.

Ответ 1

OpenGL может читать только фреймбуфер контекста (окно) и любые фреймбуферы или pbuffers, которые вы создали. OpenGL не может касаться рабочего стола или любого другого окна.

Ответ 2

Это интересный вопрос. К сожалению, я не думаю, что это действительно поддерживается. Я нашел сообщения о некотором уровне успеха с созданием полноэкранного невидимого окна и чтением данных пикселя с помощью glReadPixels:

http://www.virtualdub.org/blog/pivot/entry.php?id=142

http://www.opentk.com/node/2430

Однако, я считаю, что поведение при этом undefined и будет работать только в определенных конфигурациях оборудования/ОС.