Direct3D 桌面复制:如何从更改的屏幕分辨率中恢复?

Aar*_*Ong 3 c++ desktop duplication direct3d11

我正在开发一个桌面应用程序,它使用 IDXGIOutputDuplication 接口每秒多次拍摄屏幕图片。每当我调用其 AcquireNextFrame 方法时,我都会检查返回的 HRESULT 是否为 DXGI_ERROR_ACCESS_LOST,以查看是否有某些事件使复制接口无效。我还有一个 IDXGIFactory1,我使用 isCurrent() 来查看图形设置中是否有任何更改,例如安装了新的 GPU(出于某种原因)、连接了新的显示器或更改了桌面的分辨率。

当 isCurrent() 返回 false 时,我的方法是使用 IDXGIFactory1 重建所有 IDXGI 和 ID3D11 接口。这意味着所有适配器、所有输出和所有复制接口。根据 cout 日志,每个监视器的接口似乎都已正确重建。

我对这种方法的问题是,根据我的观察,即使构造了新接口,其 OutputDuplication 接口返回 DXGI_ERROR_ACCESS_LOST 代码的监视器也永远不会恢复。因此,如果监视器 A 产生错误,然后我从监视器 B 捕获,它会为我提供屏幕截图。但如果我继续从监视器 A 捕获,我什么也得不到,也许只是 DXGI_ERROR_ACCESS_LOST 错误代码。

我知道这听起来有点奇怪,并且在某些部分可能不清楚,但到目前为止,这是我能解释的最好方法。我也尝试过在网上搜索,但没有任何帮助。有任何想法吗?

(另外,如果有帮助的话,我正在使用 JNI,以便应用程序的 Java 代码可以访问 C++ 的 Direct3D 接口。这是我在工作中正在做的一个项目,但那里没有人知道解决方案。)

Aar*_*Ong 6

好吧,所以我又摆弄了一些,然后找到了解决方案。

重构所有ID3D11接口后,桌面复制接口(IDXGIOutputDuplication)仍然无效。也许是因为它是在屏幕分辨率仍在更新时检索的。

我所要做的就是当下次调用 AcquireNextFrame() 返回 DXGI_ERROR_ACCESS_LOST 代码时再次调用 IDXGIOutput1 的 DuplicateOutput() 方法。

将其放在这里以防有人遇到同样的问题。