я использую AcquireNextFrame от API дублирования рабочего стола захватить экран. Частота обновления экрана составляет 120 Гц. При запуске игры со скоростью 120 кадров в секунду снимок экрана может захватывать кадры со скоростью 120 кадров в секунду. Но при увеличении частоты кадров в игре до 240 кадров в секунду снимок экрана фактически падает примерно до 70 кадров в секунду. Я предполагаю, что накапливаются дополнительные кадры, что добавляет накладные расходы, но я не уверен. Есть ли способ избежать падения производительности?
Desktop Duplication API по своему дизайну накапливает обновления монитора («выходные данные» в терминах DXGI), пока вы не запросите их через AcquireNextFrame
, API не предназначен для захвата каждого обновления в первую очередь. Кроме того, вы не указываете, делаете ли вы что-либо еще в AcquireNextFrame
Цикл или вы просто измеряете производительность (язык вопроса предлагает последнее, хотя).
То есть вполне ожидаемо, что при действительно интенсивном интерфейсе API дублирования выходных данных приложение пропускает обновления. Там тоже нет особой гибкости. Возможно, самый важный совет, доступный MSDN упоминает в ReleaseFrame
Раздел замечаний:
По соображениям производительности мы рекомендуем освободить кадр непосредственно перед вызовом
IDXGIOutputDuplication::AcquireNextFrame
способ получить следующий кадр. Когда клиент не владеет фреймом, операционная система копирует все обновления рабочего стола на поверхность. Это может привести к потерянным циклам графического процессора, если операционная система обновляет один и тот же регион для каждого кадра. Когда клиент получает кадр, клиент знает только об окончательном обновлении этого региона; поэтому любые перекрывающиеся обновления в предыдущих кадрах теряются. Когда клиент приобретает кадр, клиент владеет поверхностью; следовательно, операционная система может отслеживать только обновленные области и не может копировать обновления рабочего стола на поверхность. Из-за этого поведения мы рекомендуем минимизировать время между вызовом для освобождения текущего кадра и вызовом для получения следующего кадра.
То есть зовет ReleaseFrame
рано или поздно влияет на внутреннее поведение API. Он либо накапливает обновления в целом, либо также продолжает реплицировать фактические данные полезной нагрузки в дублированные ресурсы кадра.
Других решений пока нет …