Nikolay Sivov : mfplat: Implement shared device manager API.

Alexandre Julliard julliard at winehq.org
Mon May 3 16:37:06 CDT 2021


Module: wine
Branch: master
Commit: def07b3f69bd82357419f31449a7de875944a041
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=def07b3f69bd82357419f31449a7de875944a041

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon May  3 20:02:44 2021 +0300

mfplat: Implement shared device manager API.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mfplat/main.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/mfplat/mfplat.spec    |  2 ++
 dlls/mfplat/tests/mfplat.c | 39 ++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index dad4039fa16..f1d0aaad94d 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -8553,6 +8553,16 @@ HRESULT WINAPI CreatePropertyStore(IPropertyStore **store)
     return S_OK;
 }
 
+struct shared_dxgi_manager
+{
+    IMFDXGIDeviceManager *manager;
+    unsigned int token;
+    unsigned int locks;
+};
+
+static struct shared_dxgi_manager shared_dm;
+static CRITICAL_SECTION shared_dm_cs = { NULL, -1, 0, 0, 0, 0 };
+
 enum dxgi_device_handle_flags
 {
     DXGI_DEVICE_HANDLE_FLAG_OPEN = 0x1,
@@ -8904,6 +8914,9 @@ static const IMFDXGIDeviceManagerVtbl dxgi_device_manager_vtbl =
     dxgi_device_manager_UnlockDevice,
 };
 
+/***********************************************************************
+ *      MFCreateDXGIDeviceManager (mfplat.@)
+ */
 HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **manager)
 {
     struct dxgi_device_manager *object;
@@ -8930,6 +8943,58 @@ HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **man
     return S_OK;
 }
 
+/***********************************************************************
+ *      MFLockDXGIDeviceManager (mfplat.@)
+ */
+HRESULT WINAPI MFLockDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **manager)
+{
+    HRESULT hr = S_OK;
+
+    TRACE("%p, %p.\n", token, manager);
+
+    EnterCriticalSection(&shared_dm_cs);
+
+    if (!shared_dm.manager)
+        hr = MFCreateDXGIDeviceManager(&shared_dm.token, &shared_dm.manager);
+
+    if (SUCCEEDED(hr))
+    {
+        *manager = shared_dm.manager;
+        IMFDXGIDeviceManager_AddRef(*manager);
+        shared_dm.locks++;
+
+        if (token) *token = shared_dm.token;
+    }
+
+    LeaveCriticalSection(&shared_dm_cs);
+
+    return hr;
+}
+
+/***********************************************************************
+ *      MFUnlockDXGIDeviceManager (mfplat.@)
+ */
+HRESULT WINAPI MFUnlockDXGIDeviceManager(void)
+{
+    TRACE("\n");
+
+    EnterCriticalSection(&shared_dm_cs);
+
+    if (shared_dm.manager)
+    {
+        IMFDXGIDeviceManager_Release(shared_dm.manager);
+        if (!--shared_dm.locks)
+        {
+            shared_dm.manager = NULL;
+            shared_dm.token = 0;
+        }
+    }
+
+    LeaveCriticalSection(&shared_dm_cs);
+
+    return S_OK;
+}
+
 
 /*
  * MFllMulDiv implementation is derived from gstreamer utility functions code (gstutils.c),
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index d8558cee0cb..e8dc01c200c 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -131,6 +131,7 @@
 @ stdcall MFInvokeCallback(ptr)
 @ stub MFJoinIoPort
 @ stdcall MFJoinWorkQueue(long long ptr) rtworkq.RtwqJoinWorkQueue
+@ stdcall MFLockDXGIDeviceManager(ptr ptr)
 @ stdcall MFLockPlatform() rtworkq.RtwqLockPlatform
 @ stdcall MFLockSharedWorkQueue(wstr long ptr ptr) rtworkq.RtwqLockSharedWorkQueue
 @ stdcall MFLockWorkQueue(long) rtworkq.RtwqLockWorkQueue
@@ -171,6 +172,7 @@
 @ stub MFTraceFuncEnter
 @ stub MFUnblockThread
 @ stdcall MFUnjoinWorkQueue(long long) rtworkq.RtwqUnjoinWorkQueue
+@ stdcall MFUnlockDXGIDeviceManager()
 @ stdcall MFUnlockPlatform() rtworkq.RtwqUnlockPlatform
 @ stdcall MFUnlockWorkQueue(long) rtworkq.RtwqUnlockWorkQueue
 @ stdcall MFUnwrapMediaType(ptr ptr)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index b0c7298c28d..65ab72bd57b 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -262,6 +262,8 @@ static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surfa
         IMFMediaBuffer **buffer);
 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
 static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
+static HRESULT (WINAPI *pMFLockDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
+static HRESULT (WINAPI *pMFUnlockDXGIDeviceManager)(void);
 
 static HWND create_window(void)
 {
@@ -935,6 +937,7 @@ static void init_functions(void)
     X(MFCreateVideoSampleAllocatorEx);
     X(MFGetPlaneSize);
     X(MFGetStrideForBitmapInfoHeader);
+    X(MFLockDXGIDeviceManager);
     X(MFLockSharedWorkQueue);
     X(MFMapDX9FormatToDXGIFormat);
     X(MFMapDXGIFormatToDX9Format);
@@ -947,6 +950,7 @@ static void init_functions(void)
     X(MFTRegisterLocalByCLSID);
     X(MFTUnregisterLocal);
     X(MFTUnregisterLocalByCLSID);
+    X(MFUnlockDXGIDeviceManager);
 
     if ((mod = LoadLibraryA("d3d11.dll")))
     {
@@ -7168,6 +7172,40 @@ static void test_MFllMulDiv(void)
     }
 }
 
+static void test_shared_dxgi_device_manager(void)
+{
+    IMFDXGIDeviceManager *manager;
+    HRESULT hr;
+    UINT token;
+
+    if (!pMFLockDXGIDeviceManager)
+    {
+        win_skip("Shared DXGI device manager is not supported.\n");
+        return;
+    }
+
+    hr = pMFUnlockDXGIDeviceManager();
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    manager = NULL;
+    hr = pMFLockDXGIDeviceManager(NULL, &manager);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!!manager, "Unexpected instance.\n");
+
+    hr = pMFLockDXGIDeviceManager(&token, &manager);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    EXPECT_REF(manager, 3);
+
+    hr = pMFUnlockDXGIDeviceManager();
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    EXPECT_REF(manager, 2);
+
+    hr = pMFUnlockDXGIDeviceManager();
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+}
+
 START_TEST(mfplat)
 {
     char **argv;
@@ -7233,6 +7271,7 @@ START_TEST(mfplat)
     test_sample_allocator();
     test_MFMapDX9FormatToDXGIFormat();
     test_MFllMulDiv();
+    test_shared_dxgi_device_manager();
 
     CoUninitialize();
 }




More information about the wine-cvs mailing list