From 95ca40c4ab0e3316767815d41df14040a226d7df Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 2 Mar 2023 02:51:21 +0900 Subject: [PATCH] d3d11screencapturesrc: Use keyed mutex instead of fence D3D11 runtime might not support ID3D11Fence, and if so GstD3D11Fence abstraction will use ID3D11Query instead. However, since the ID3D11Query requires busy waiting, keyed mutex is better approach. Part-of: --- .../sys/d3d11/gstd3d11dxgicapture.cpp | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11dxgicapture.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11dxgicapture.cpp index fbdf8f6651..1622a98d42 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11dxgicapture.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11dxgicapture.cpp @@ -231,7 +231,6 @@ class D3D11DesktopDupObject public: D3D11DesktopDupObject () : device_(nullptr) - , fence_(nullptr) , metadata_buffer_(nullptr) , metadata_buffer_size_(0) , vertex_buffer_(nullptr) @@ -247,7 +246,11 @@ public: if (vertex_buffer_) delete[] vertex_buffer_; - gst_clear_d3d11_fence (&fence_); + if (keyed_mutex_) { + keyed_mutex_->ReleaseSync (0); + keyed_mutex_ = nullptr; + } + gst_clear_object (&device_); } @@ -282,7 +285,7 @@ public: D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; texture_desc.CPUAccessFlags = 0; /* source element may hold different d3d11 device object */ - texture_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; + texture_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; hr = device_handle->CreateTexture2D (&texture_desc, nullptr, &shared_texture_); @@ -291,6 +294,21 @@ public: return GST_FLOW_ERROR; } + hr = shared_texture_.As (&keyed_mutex_); + if (!gst_d3d11_result (hr, device)) { + GST_ERROR_OBJECT (device, "Couldn't get keyed mutex interface"); + shared_texture_ = nullptr; + return GST_FLOW_ERROR; + } + + hr = keyed_mutex_->AcquireSync (0, INFINITE); + if (hr != S_OK) { + GST_ERROR_OBJECT (device, "Couldn't acquire sync"); + keyed_mutex_ = nullptr; + shared_texture_ = nullptr; + return GST_FLOW_ERROR; + } + device_ = (GstD3D11Device *) gst_object_ref (device); return GST_FLOW_OK; @@ -547,8 +565,8 @@ public: { ID3D11DeviceContext *context_handle = nullptr; ComPtr tex; + ComPtr < IDXGIKeyedMutex > other_keyed_mutex; HRESULT hr; - gboolean is_shared = FALSE; context_handle = gst_d3d11_device_get_device_context_handle (device); @@ -574,24 +592,21 @@ public: if (!gst_d3d11_result (hr, device)) return GST_FLOW_ERROR; - if (fence_ && fence_->device != device) - gst_clear_d3d11_fence (&fence_); - - if (!fence_) - fence_ = gst_d3d11_device_create_fence (device); - - if (!fence_) + hr = tex.As (&other_keyed_mutex); + if (!gst_d3d11_result (hr, device)) return GST_FLOW_ERROR; - is_shared = TRUE; + /* release sync from our device, and acquire for other device */ + keyed_mutex_->ReleaseSync (0); + other_keyed_mutex->AcquireSync (0, INFINITE); } context_handle->CopySubresourceRegion (texture, 0, 0, 0, 0, tex.Get(), 0, cropBox); - if (is_shared) { - if (!gst_d3d11_fence_signal (fence_) || !gst_d3d11_fence_wait (fence_)) - return GST_FLOW_ERROR; + if (other_keyed_mutex) { + other_keyed_mutex->ReleaseSync (0); + keyed_mutex_->AcquireSync (0, INFINITE); } return GST_FLOW_OK; @@ -1472,9 +1487,9 @@ private: PTR_INFO ptr_info_; DXGI_OUTDUPL_DESC output_desc_; GstD3D11Device * device_; - GstD3D11Fence * fence_; ComPtr shared_texture_; + ComPtr keyed_mutex_; ComPtr rtv_; ComPtr move_texture_; ComPtr vs_;