我正在使用桌面复制 API中的AcquireNextFrame来捕获屏幕。屏幕的刷新率为120Hz。当以120FPS运行游戏时,屏幕捕获可以捕获120FPS的帧数。但是当将游戏的帧率增加到240FPS时,屏幕捕获实际上会下降到大约70FPS。我的猜测是额外的帧被累积了,这增加了开销,但我不确定。有没有办法避免这种性能下降?
我正在使用桌面复制 API中的AcquireNextFrame来捕获屏幕。屏幕的刷新率为120Hz。当以120FPS运行游戏时,屏幕捕获可以捕获120FPS的帧数。但是当将游戏的帧率增加到240FPS时,屏幕捕获实际上会下降到大约70FPS。我的猜测是额外的帧被累积了,这增加了开销,但我不确定。有没有办法避免这种性能下降?
桌面复制 API 的设计是累积显示器(在 DXGI 中称为“输出”)更新,直到您通过 AcquireNextFrame
请求它们。该 API 并非旨在首先捕获每个更新。此外,您没有指定在 AcquireNextFrame
循环中是否还进行其他操作,或者只是测量性能(问题的语言表明后者)。
也就是说,对于非常密集的前端应用程序,输出复制 API 会错过更新,这是可以预料的。在那里也没有太多的灵活性。也许 MSDN 提供的最重要的提示在ReleaseFrame
Remarks 部分中提到:
出于性能原因,我们建议您在调用
IDXGIOutputDuplication::AcquireNextFrame
方法获取下一帧之前释放帧。当客户端不拥有该帧时,操作系统会将所有桌面更新复制到表面上。如果操作系统更新每个帧的同一区域,则可能会导致 GPU 循环浪费。当客户端获取帧时,客户端仅知道此区域的最终更新;因此,在先前帧期间发生的任何重叠更新都是浪费的。当客户端获取帧时,客户端拥有表面;因此,操作系统只能跟踪更新的区域,并且不能将桌面更新复制到表面。由于这种行为,我们建议您尽量缩短释放当前帧和获取下一帧之间的时间。
也就是说,早或晚调用 ReleaseFrame
会影响 API 的内部行为。它要么总体上累积更新,要么还会将实际负载数据复制到复制的帧资源中。