[vlc-devel] [PATCH 1/4] [RFC] direct3d11: add a way to (re)store the device in the global context

Steve Lhomme robux4 at videolabs.io
Mon Nov 20 09:54:37 CET 2017


--
replaces https://patches.videolan.org/patch/18701/
- if there was already a value set it's now used, before it would just
  assert or overwrite the old value

It's not fully thread safe, if 2 threads call var_CreateGetAddress at the
same time they will both return NULL even though one of them created the
variable. They will both write their own value. We could live with that
for 3.0 as it's an edge case for an edge case.
---
 modules/codec/avcodec/d3d11va.c         |  2 +-
 modules/video_chroma/d3d11_fmt.c        | 28 +++++++++++++++++++++++++++-
 modules/video_chroma/d3d11_fmt.h        |  6 +++++-
 modules/video_output/win32/direct3d11.c |  2 +-
 4 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index 608016aa7b..b1957539db 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -439,7 +439,7 @@ static void D3dDestroyDevice(vlc_va_t *va)
     vlc_va_sys_t *sys = va->sys;
     if (sys->d3dvidctx)
         ID3D11VideoContext_Release(sys->d3dvidctx);
-    D3D11_ReleaseDevice( &sys->d3d_dev );
+    D3D11_ReleaseDevice( va, &sys->d3d_dev );
 }
 /**
  * It describes our Direct3D object
diff --git a/modules/video_chroma/d3d11_fmt.c b/modules/video_chroma/d3d11_fmt.c
index 8caeade34a..9d000db604 100644
--- a/modules/video_chroma/d3d11_fmt.c
+++ b/modules/video_chroma/d3d11_fmt.c
@@ -39,6 +39,8 @@
 
 #include "../codec/avcodec/va_surface.h"
 
+#define D3D11_GLOBAL_CONTEXT_NAME  "_d3d11-device"
+
 picture_sys_t *ActivePictureSys(picture_t *p_pic)
 {
     struct va_pic_context *pic_ctx = (struct va_pic_context*)p_pic->context;
@@ -134,7 +136,8 @@ int AllocateShaderView(vlc_object_t *obj, ID3D11Device *d3ddevice,
     return VLC_SUCCESS;
 }
 
-void D3D11_ReleaseDevice(d3d11_device_t *d3d_dev)
+#undef D3D11_ReleaseDevice
+void D3D11_ReleaseDevice(vlc_object_t *o, d3d11_device_t *d3d_dev)
 {
     if (d3d_dev->d3dcontext)
     {
@@ -147,6 +150,8 @@ void D3D11_ReleaseDevice(d3d11_device_t *d3d_dev)
         ID3D11Device_Release(d3d_dev->d3ddevice);
         d3d_dev->d3ddevice = NULL;
     }
+    if (d3d_dev->owner)
+        var_Destroy(o->obj.libvlc, D3D11_GLOBAL_CONTEXT_NAME);
 }
 
 #undef D3D11_CreateDevice
@@ -222,11 +227,32 @@ HRESULT D3D11_CreateDevice(vlc_object_t *obj, d3d11_handle_t *hd3d,
     if (SUCCEEDED(hr))
     {
         out->owner = true;
+        void *old = var_CreateGetAddress(obj->obj.libvlc, D3D11_GLOBAL_CONTEXT_NAME);
+        if (likely(old == NULL))
+            var_SetAddress(obj->obj.libvlc, D3D11_GLOBAL_CONTEXT_NAME, out->d3dcontext);
+        else
+        {
+            /* there was already one, use this one */
+            /* var_Create increases the internal usage counter so we will need a
+             * var_Destroy too */
+            ID3D11DeviceContext_Release(out->d3dcontext);
+            ID3D11Device_Release(out->d3ddevice);
+
+            out->d3dcontext = old;
+            ID3D11Device_AddRef( out->d3dcontext );
+            ID3D11DeviceContext_GetDevice( out->d3dcontext, &out->d3ddevice );
+        }
     }
 
     return hr;
 }
 
+#undef D3D11_GetDevice
+ID3D11DeviceContext *D3D11_GetDevice(vlc_object_t *obj)
+{
+    return var_InheritAddress(obj, D3D11_GLOBAL_CONTEXT_NAME);
+}
+
 IDXGIAdapter *D3D11DeviceAdapter(ID3D11Device *d3ddev)
 {
     IDXGIDevice *pDXGIDevice = NULL;
diff --git a/modules/video_chroma/d3d11_fmt.h b/modules/video_chroma/d3d11_fmt.h
index 9ed889edf9..fe09e93426 100644
--- a/modules/video_chroma/d3d11_fmt.h
+++ b/modules/video_chroma/d3d11_fmt.h
@@ -90,7 +90,11 @@ HRESULT D3D11_CreateDevice(vlc_object_t *obj, d3d11_handle_t *,
                            bool hw_decoding, d3d11_device_t *out);
 #define D3D11_CreateDevice(a,b,c,d)  D3D11_CreateDevice( VLC_OBJECT(a), b, c, d )
 
-void D3D11_ReleaseDevice(d3d11_device_t *);
+void D3D11_ReleaseDevice(vlc_object_t *, d3d11_device_t *);
+#define D3D11_ReleaseDevice(a,b) D3D11_ReleaseDevice( VLC_OBJECT(a), b )
+
+ID3D11DeviceContext *D3D11_GetDevice(vlc_object_t *);
+#define D3D11_GetDevice(a) D3D11_GetDevice( VLC_OBJECT(a) )
 
 int D3D11_Create(vlc_object_t *, d3d11_handle_t *);
 #define D3D11_Create(a,b) D3D11_Create( VLC_OBJECT(a), b )
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 85eeb643fe..49d80bacb1 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -1593,7 +1593,7 @@ static void Direct3D11Close(vout_display_t *vd)
         sys->dxgiswapChain = NULL;
     }
 
-    D3D11_ReleaseDevice( &sys->d3d_dev );
+    D3D11_ReleaseDevice( vd, &sys->d3d_dev );
 
     msg_Dbg(vd, "Direct3D11 device adapter closed");
 }
-- 
2.14.2



More information about the vlc-devel mailing list