You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows平台C++实现144Hz高帧率屏幕捕获优化方案咨询

屏幕捕获帧率优化方案

我正在开发将屏幕画面捕获并复制到应用程序中的功能,现有代码如下:

static bool first = false;
static IDirect3DSurface9* pSurface;
static IDirect3DSurface9* pBackbuffer;

HRESULT hr;
if (first == false)
{
    hr = m_pD3DDevice9Ex->CreateOffscreenPlainSurface(1920, 1080,
        D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pSurface, NULL);
    hr = m_pD3DDevice9Ex->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackbuffer);
    first = true;
}

if (pSurface != NULL)
{
    hr = m_pD3DDevice9Ex->GetFrontBufferData(0, pSurface);
    hr = m_pD3DDevice9Ex->UpdateSurface(pSurface, NULL, pBackbuffer, NULL);
}

该代码可正常运行,但帧率极低(1920×1080分辨率下仅60-80fps)。我需要实现至少144Hz的屏幕捕获,以下是可行的优化方案:

  • 替换低效的GetFrontBufferData:GetFrontBufferData是同步操作,且强制将GPU显存数据拷贝到系统内存,这是帧率瓶颈的核心原因。改用IDirect3DDevice9Ex::CreateRenderTarget创建GPU显存池(D3DPOOL_DEFAULT)内的渲染目标,配合StretchRect直接在显存内完成拷贝,避免跨内存池的数据传输。
  • 调整内存池类型:将CreateOffscreenPlainSurface的D3DPOOL_SYSTEMMEM改为D3DPOOL_DEFAULT,让捕获表面留在GPU显存中,彻底消除显存到系统内存的拷贝开销——这一步能大幅提升捕获效率。
  • 移除冗余的两次拷贝:当前代码先把前缓冲区数据拷到pSurface,再拷到pBackbuffer,属于重复操作。直接调用StretchRect将前缓冲区数据复制到应用的pBackbuffer,省去中间表面的中转步骤。
  • 改用DXGI的屏幕捕获API:Direct3D9的API设计并非针对高刷新率捕获,而DXGI的IDXGIOutputDuplication是专门为桌面捕获优化的接口,能直接获取桌面的帧数据,支持硬件加速,轻松达到144Hz甚至更高帧率。核心步骤为:初始化DXGI设备、获取目标显示器的输出复制接口、循环调用AcquireNextFrame获取帧、处理后调用ReleaseFrame释放资源。
  • 引入异步处理机制:利用Direct3D的异步查询(IDirect3DQuery9)检测捕获操作是否完成,避免CPU等待GPU,同时维护一个帧队列,让捕获、处理、渲染三个环节并行执行,充分利用CPU和GPU资源。
  • 完善错误处理:当前代码未检查HRESULT的返回值,若资源创建失败会导致后续操作无效。添加SUCCEEDED(hr)或FAILED(hr)的判断,确保资源初始化成功后再执行捕获逻辑。

内容的提问来源于stack exchange,提问作者medq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 06:27:25