From: Brendan McGrath bmcgrath@codeweavers.com
Ensures the Direct 2D lock is held before attempting to access Direct 2D exclusive resources.
This fixes periodic crashes in PowerPoint 365 --- dlls/d2d1/device.c | 8 ++++++++ dlls/d2d1/tests/d2d1.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index e5548878ee9..677968a980c 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -121,6 +121,8 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en { struct d2d_shape_resources *shape_resources = &render_target->shape_resources[shape_type]; ID3DDeviceContextState *prev_state; + ID2D1Factory *factory = render_target->factory; + ID2D1Multithread *multithread; ID3D11Device1 *device = render_target->d3d_device; ID3D11DeviceContext1 *context; ID3D11Buffer *vs_cb = render_target->vs_cb, *ps_cb = render_target->ps_cb; @@ -135,6 +137,9 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f;
+ ID2D1Factory_QueryInterface(factory, &IID_ID2D1Multithread, (void **)&multithread); + ID2D1Multithread_Enter(multithread); + ID3D11Device1_GetImmediateContext1(device, &context); ID3D11DeviceContext1_SwapDeviceContextState(context, render_target->d3d_state, &prev_state);
@@ -188,6 +193,9 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en ID3D11DeviceContext1_SwapDeviceContextState(context, prev_state, NULL); ID3D11DeviceContext1_Release(context); ID3DDeviceContextState_Release(prev_state); + + ID2D1Multithread_Leave(multithread); + ID2D1Multithread_Release(multithread); }
static void d2d_device_context_set_error(struct d2d_device_context *context, HRESULT code) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index f0e6f1ffb38..3b7b59ef49f 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10778,7 +10778,7 @@ static void test_mt_factory(BOOL d3d11) thread = CreateThread(NULL, 0, mt_factory_test_thread_draw_func, ctx.rt, 0, NULL); ok(!!thread, "Failed to create a thread.\n"); ret = WaitForSingleObject(thread, 1000); - todo_wine ok(ret == WAIT_TIMEOUT, "Expected timeout.\n"); + ok(ret == WAIT_TIMEOUT, "Expected timeout.\n"); ID2D1Multithread_Leave(multithread); WaitForSingleObject(thread, INFINITE); CloseHandle(thread);