diff options
author | Jøger Hansegård <joger.hansegard@qt.io> | 2023-05-24 13:59:28 +0200 |
---|---|---|
committer | Jøger Hansegård <joger.hansegard@qt.io> | 2023-05-30 14:06:42 +0200 |
commit | cfc5b97daee9ac38b6fa8ec52be292e0790220ce (patch) | |
tree | 3459e3fe7228b9abca5565c0b71a8e20337d9f98 /src | |
parent | 9b38bc514c658117a4ee0cb3bfbe6010ff864914 (diff) |
Release DXGI duplication frame as late as possible to favor performance
According to Microsoft documentation for the
IDXGIOutputDuplication::ReleaseFrame: "For performance reasons, we
recommend that you release the frame just before you call the
IDXGIOutputDuplication::AcquireNextFrame method to acquire the next
frame."
This has no measurable impact on GPU usage or performance of the screen
capture, but because this design simplifies error handling/cleanup, we
can just as well follow the guidelines.
Task-number: QTBUG-113460
Pick-to: 6.5
Change-Id: I0f95c5792b29942a957f57971081520501a1e0a5
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpegscreencapture_dxgi.cpp | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegscreencapture_dxgi.cpp b/src/plugins/multimedia/ffmpeg/qffmpegscreencapture_dxgi.cpp index 057fa700f..7799f1a49 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegscreencapture_dxgi.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegscreencapture_dxgi.cpp @@ -134,6 +134,8 @@ public: ~Grabber() { stop(); + if (m_releaseFrame) + m_duplication->ReleaseFrame(); } void run() override @@ -179,19 +181,27 @@ public: private: QMaybe<QComPtr<ID3D11Texture2D>> getNextFrame() { + if (m_releaseFrame) { + HRESULT hr = m_duplication->ReleaseFrame(); + if (FAILED(hr)) + return "Failed to release duplication frame. " + ::errorString(hr); + + m_releaseFrame = false; + } + QComPtr<IDXGIResource> frame; DXGI_OUTDUPL_FRAME_INFO info; HRESULT hr = m_duplication->AcquireNextFrame(0, &info, frame.address()); if (FAILED(hr)) return hr == DXGI_ERROR_WAIT_TIMEOUT ? QString{} - : "Failed to grab the screen content" + ::errorString(hr); + : "Failed to grab the screen content" + ::errorString(hr); + + m_releaseFrame = true; QComPtr<ID3D11Texture2D> tex; hr = frame->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(tex.address())); - if (FAILED(hr)) { - m_duplication->ReleaseFrame(); + if (FAILED(hr)) return "Failed to obtain D3D11 texture" + ::errorString(hr); - } D3D11_TEXTURE2D_DESC texDesc = {}; tex->GetDesc(&texDesc); @@ -199,17 +209,13 @@ private: texDesc.BindFlags = 0; QComPtr<ID3D11Texture2D> texCopy; hr = m_device->CreateTexture2D(&texDesc, nullptr, texCopy.address()); - if (FAILED(hr)) { - m_duplication->ReleaseFrame(); + if (FAILED(hr)) return "Failed to create texture with CPU access" + ::errorString(hr); - } QComPtr<ID3D11DeviceContext> ctx; m_device->GetImmediateContext(ctx.address()); ctx->CopyResource(texCopy.get(), tex.get()); - m_duplication->ReleaseFrame(); - return texCopy; } @@ -220,6 +226,7 @@ private: QMutex m_formatMutex; std::shared_ptr<QMutex> m_ctxMutex; QSize m_frameSize; + bool m_releaseFrame = false; }; static QMaybe<QComPtr<IDXGIOutputDuplication>> duplicateOutput(ID3D11Device* device, IDXGIOutput *output) |