summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJøger Hansegård <joger.hansegard@qt.io>2023-05-24 13:59:28 +0200
committerJøger Hansegård <joger.hansegard@qt.io>2023-05-30 14:06:42 +0200
commitcfc5b97daee9ac38b6fa8ec52be292e0790220ce (patch)
tree3459e3fe7228b9abca5565c0b71a8e20337d9f98 /src
parent9b38bc514c658117a4ee0cb3bfbe6010ff864914 (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.cpp25
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)