rtworkq: Partially implement shared queues.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-03-25 19:06:19 +03:00 committed by Alexandre Julliard
parent bd9aca2cc8
commit d1d1e3f56f
4 changed files with 80 additions and 2 deletions

View file

@ -132,6 +132,7 @@
@ stub MFJoinIoPort
@ stdcall MFJoinWorkQueue(long long ptr) rtworkq.RtwqJoinWorkQueue
@ stdcall MFLockPlatform() rtworkq.RtwqLockPlatform
@ stdcall MFLockSharedWorkQueue(wstr long ptr ptr) rtworkq.RtwqLockSharedWorkQueue
@ stdcall MFLockWorkQueue(long) rtworkq.RtwqLockWorkQueue
@ stdcall MFMapDX9FormatToDXGIFormat(long)
@ stdcall MFMapDXGIFormatToDX9Format(long)

View file

@ -240,6 +240,7 @@ static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **all
static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
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 HWND create_window(void)
{
@ -907,6 +908,7 @@ static void init_functions(void)
X(MFCreateVideoSampleAllocatorEx);
X(MFGetPlaneSize);
X(MFGetStrideForBitmapInfoHeader);
X(MFLockSharedWorkQueue);
X(MFMapDX9FormatToDXGIFormat);
X(MFMapDXGIFormatToDX9Format);
X(MFPutWaitingWorkItem);
@ -7016,6 +7018,49 @@ done:
DestroyWindow(window);
}
static void test_MFLockSharedWorkQueue(void)
{
DWORD taskid, queue, queue2;
HRESULT hr;
if (!pMFLockSharedWorkQueue)
{
win_skip("MFLockSharedWorkQueue() is not available.\n");
return;
}
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
taskid = 0;
hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
queue = 0;
hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
queue2 = 0;
hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(queue == queue2, "Unexpected queue %#x.\n", queue2);
hr = MFUnlockWorkQueue(queue2);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = MFUnlockWorkQueue(queue);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = MFShutdown();
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
}
START_TEST(mfplat)
{
char **argv;
@ -7044,6 +7089,7 @@ START_TEST(mfplat)
test_source_resolver();
test_MFCreateAsyncResult();
test_allocate_queue();
test_MFLockSharedWorkQueue();
test_MFCopyImage();
test_MFCreateCollection();
test_MFHeapAlloc();

View file

@ -58,6 +58,7 @@ static struct queue_handle user_queues[MAX_USER_QUEUE_HANDLES];
static struct queue_handle *next_free_user_queue;
static struct queue_handle *next_unused_user_queue = user_queues;
static WORD queue_generation;
static DWORD shared_mt_queue;
static CRITICAL_SECTION queues_section;
static CRITICAL_SECTION_DEBUG queues_critsect_debug =
@ -217,6 +218,7 @@ static HRESULT unlock_user_queue(DWORD queue)
{
if (--entry->refcount == 0)
{
if (shared_mt_queue == queue) shared_mt_queue = 0;
shutdown_queue((struct queue *)entry->obj);
heap_free(entry->obj);
entry->obj = next_free_user_queue;
@ -1438,9 +1440,37 @@ HRESULT WINAPI RtwqSetLongRunning(DWORD queue_id, BOOL enable)
HRESULT WINAPI RtwqLockSharedWorkQueue(const WCHAR *usageclass, LONG priority, DWORD *taskid, DWORD *queue)
{
FIXME("%s, %d, %p, %p.\n", debugstr_w(usageclass), priority, taskid, queue);
struct queue_desc desc;
HRESULT hr;
return RtwqAllocateWorkQueue(RTWQ_STANDARD_WORKQUEUE, queue);
TRACE("%s, %d, %p, %p.\n", debugstr_w(usageclass), priority, taskid, queue);
if (!usageclass)
return E_POINTER;
if (!*usageclass && taskid)
return E_INVALIDARG;
if (*usageclass)
FIXME("Class name is ignored.\n");
EnterCriticalSection(&queues_section);
if (shared_mt_queue)
hr = lock_user_queue(shared_mt_queue);
else
{
desc.queue_type = RTWQ_MULTITHREADED_WORKQUEUE;
desc.ops = &pool_queue_ops;
desc.target_queue = 0;
hr = alloc_user_queue(&desc, &shared_mt_queue);
}
*queue = shared_mt_queue;
LeaveCriticalSection(&queues_section);
return hr;
}
HRESULT WINAPI RtwqSetDeadline(DWORD queue_id, LONGLONG deadline, HANDLE *request)

View file

@ -553,6 +553,7 @@ HRESULT WINAPI MFInitAttributesFromBlob(IMFAttributes *attributes, const UINT8 *
HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size);
HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result);
HRESULT WINAPI MFLockPlatform(void);
HRESULT WINAPI MFLockSharedWorkQueue(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
DXGI_FORMAT WINAPI MFMapDX9FormatToDXGIFormat(DWORD format);
DWORD WINAPI MFMapDXGIFormatToDX9Format(DXGI_FORMAT dxgi_format);
HRESULT WINAPI MFPutWaitingWorkItem(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);