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

Direct3D Desktop Duplication: How to Recover From Changing Screen Resolution?

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

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

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

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

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

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

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

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

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