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