summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorSeungha Yang <seungha@centricular.com>2021-03-17 23:53:04 +0900
committerSeungha Yang <seungha@centricular.com>2021-03-18 16:37:37 +0000
commit872b7f503c49442e559f6a381416c6a84b76a3c6 (patch)
tree46ec1b601004f672eef73d729475eabe24803b80 /gst-libs
parent0d36dcab4e773a797f0d8c1e841b98044647690c (diff)
downloadgstreamer-plugins-bad-872b7f503c49442e559f6a381416c6a84b76a3c6.tar.gz
d3d11: Enable native multi-thread protection layer and make use of it
... instead of our own GRecMutex locking. In this way, any other Direct3D11 client (MediaFoundation for example) can safely call any Direct3D11 API even when we are sharing our Direct3D11 device with others. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2092>
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/d3d11/gstd3d11device.c28
-rw-r--r--gst-libs/gst/d3d11/gstd3d11memory.c11
-rw-r--r--gst-libs/gst/d3d11/meson.build2
3 files changed, 24 insertions, 17 deletions
diff --git a/gst-libs/gst/d3d11/gstd3d11device.c b/gst-libs/gst/d3d11/gstd3d11device.c
index fd40ead5e..337bc19ce 100644
--- a/gst-libs/gst/d3d11/gstd3d11device.c
+++ b/gst-libs/gst/d3d11/gstd3d11device.c
@@ -30,6 +30,7 @@
#include <windows.h>
#include <versionhelpers.h>
+#include <d3d10.h>
/**
* SECTION:gstd3d11device
@@ -105,11 +106,11 @@ struct _GstD3D11DevicePrivate
ID3D11VideoDevice *video_device;
ID3D11VideoContext *video_context;
+ ID3D10Multithread *multi_thread;
IDXGIFactory1 *factory;
GstD3D11Format format_table[GST_D3D11_N_FORMATS];
- GRecMutex extern_lock;
GMutex resource_lock;
#if HAVE_D3D11SDKLAYERS_H
@@ -412,7 +413,6 @@ gst_d3d11_device_init (GstD3D11Device * self)
priv = gst_d3d11_device_get_instance_private (self);
priv->adapter = DEFAULT_ADAPTER;
- g_rec_mutex_init (&priv->extern_lock);
g_mutex_init (&priv->resource_lock);
self->priv = priv;
@@ -784,6 +784,20 @@ gst_d3d11_device_constructed (GObject * object)
goto error;
}
+ hr = ID3D11Device_QueryInterface (priv->device, &IID_ID3D10Multithread,
+ (void **) &priv->multi_thread);
+ if (!gst_d3d11_result (hr, NULL)) {
+ GST_ERROR_OBJECT (self, "ID3D10Multithread interface is not available");
+ ID3D11Device_Release (priv->device);
+ priv->device = NULL;
+
+ ID3D11DeviceContext_Release (priv->device_context);
+ priv->device_context = NULL;
+ goto error;
+ }
+
+ ID3D10Multithread_SetMultithreadProtected (priv->multi_thread, TRUE);
+
priv->factory = factory;
#if HAVE_D3D11SDKLAYERS_H
@@ -899,6 +913,11 @@ gst_d3d11_device_dispose (GObject * object)
GST_LOG_OBJECT (self, "dispose");
+ if (priv->multi_thread) {
+ ID3D10Multithread_Release (priv->multi_thread);
+ priv->multi_thread = NULL;
+ }
+
if (priv->video_device) {
ID3D11VideoDevice_Release (priv->video_device);
priv->video_device = NULL;
@@ -966,7 +985,6 @@ gst_d3d11_device_finalize (GObject * object)
GST_LOG_OBJECT (self, "finalize");
- g_rec_mutex_clear (&priv->extern_lock);
g_mutex_clear (&priv->resource_lock);
g_free (priv->description);
@@ -1148,7 +1166,7 @@ gst_d3d11_device_lock (GstD3D11Device * device)
priv = device->priv;
GST_TRACE_OBJECT (device, "device locking");
- g_rec_mutex_lock (&priv->extern_lock);
+ ID3D10Multithread_Enter (priv->multi_thread);
GST_TRACE_OBJECT (device, "device locked");
}
@@ -1169,8 +1187,8 @@ gst_d3d11_device_unlock (GstD3D11Device * device)
g_return_if_fail (GST_IS_D3D11_DEVICE (device));
priv = device->priv;
+ ID3D10Multithread_Leave (priv->multi_thread);
- g_rec_mutex_unlock (&priv->extern_lock);
GST_TRACE_OBJECT (device, "device unlocked");
}
diff --git a/gst-libs/gst/d3d11/gstd3d11memory.c b/gst-libs/gst/d3d11/gstd3d11memory.c
index 0c96d7f31..da32c9e07 100644
--- a/gst-libs/gst/d3d11/gstd3d11memory.c
+++ b/gst-libs/gst/d3d11/gstd3d11memory.c
@@ -347,7 +347,6 @@ map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type)
ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (dmem->device);
- gst_d3d11_device_lock (dmem->device);
if (GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD)) {
ID3D11DeviceContext_CopySubresourceRegion (device_context,
staging, 0, 0, 0, 0, texture, priv->subresource_index, NULL);
@@ -362,8 +361,6 @@ map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type)
ret = FALSE;
}
- gst_d3d11_device_unlock (dmem->device);
-
return ret;
}
@@ -383,7 +380,6 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
map_type = gst_map_flags_to_d3d11 (flags);
- gst_d3d11_device_lock (dmem->device);
hr = ID3D11DeviceContext_Map (device_context,
(ID3D11Resource *) priv->texture, 0, map_type, 0, &priv->map);
if (!gst_d3d11_result (hr, dmem->device)) {
@@ -391,7 +387,6 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
"Failed to map staging texture (0x%x)", (guint) hr);
ret = FALSE;
}
- gst_d3d11_device_unlock (dmem->device);
if (!ret) {
GST_D3D11_MEMORY_UNLOCK (dmem);
@@ -425,11 +420,9 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (dmem->device);
- gst_d3d11_device_lock (dmem->device);
ID3D11DeviceContext_CopySubresourceRegion (device_context,
(ID3D11Resource *) priv->texture, priv->subresource_index, 0, 0, 0,
(ID3D11Resource *) priv->staging, 0, NULL);
- gst_d3d11_device_unlock (dmem->device);
}
GST_MEMORY_FLAG_UNSET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD);
@@ -492,9 +485,7 @@ unmap_cpu_access_data (GstD3D11Memory * dmem)
if (priv->type == GST_D3D11_MEMORY_TYPE_STAGING)
staging = (ID3D11Resource *) priv->texture;
- gst_d3d11_device_lock (dmem->device);
ID3D11DeviceContext_Unmap (device_context, staging, 0);
- gst_d3d11_device_unlock (dmem->device);
}
static void
@@ -693,7 +684,6 @@ calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture,
ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (device);
- gst_d3d11_device_lock (device);
hr = ID3D11DeviceContext_Map (device_context,
(ID3D11Resource *) texture, 0, map_type, 0, &map);
@@ -707,7 +697,6 @@ calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture,
desc->Width, desc->Height, map.RowPitch, offset, stride, size);
ID3D11DeviceContext_Unmap (device_context, (ID3D11Resource *) texture, 0);
- gst_d3d11_device_unlock (device);
return ret;
}
diff --git a/gst-libs/gst/d3d11/meson.build b/gst-libs/gst/d3d11/meson.build
index b699082d5..b0b2ae9cf 100644
--- a/gst-libs/gst/d3d11/meson.build
+++ b/gst-libs/gst/d3d11/meson.build
@@ -72,7 +72,7 @@ foreach d3d11_h: d3d11_headers
endif
endforeach
-have_d3d11 = d3d11_lib.found() and dxgi_lib.found() and have_d3d11_header and have_dxgi_header
+have_d3d11 = d3d11_lib.found() and dxgi_lib.found() and have_d3d11_header and have_dxgi_header and cc.has_header('d3d10.h')
if not have_d3d11
if d3d11_option.enabled()
error('The d3d11 was enabled explicitly, but required dependencies were not found.')