From: Brendan McGrath bmcgrath@codeweavers.com
Place the CRITICAL_SECTION pointer in the d2d_device_context struct so we don't have to QueryInterface(), Release(), and go through function pointers everytime we draw --- dlls/d2d1/d2d1_private.h | 2 ++ dlls/d2d1/device.c | 25 +++++++++++++++++++------ dlls/d2d1/factory.c | 5 +++++ 3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 1dd5cdb0a39..4ad22a8a223 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -171,6 +171,7 @@ struct d2d_device_context const struct d2d_device_context_ops *ops;
ID2D1Factory *factory; + CRITICAL_SECTION *cs; struct d2d_device *device; ID3D11Device1 *d3d_device; ID3DDeviceContextState *d3d_state; @@ -684,6 +685,7 @@ struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory const GUID *effect_id); void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect); +CRITICAL_SECTION* d2d_factory_mt_get_cs(ID2D1Multithread *iface);
struct d2d_transform_graph { diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 677968a980c..4127ea8f633 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -115,14 +115,20 @@ static void d2d_clip_stack_pop(struct d2d_clip_stack *stack) --stack->count; }
+static inline void d2d_device_context_enter_cs(struct d2d_device_context *context) { + if (context->cs) EnterCriticalSection(context->cs); +} + +static inline void d2d_device_context_leave_cs(struct d2d_device_context *context) { + if (context->cs) LeaveCriticalSection(context->cs); +} + static void d2d_device_context_draw(struct d2d_device_context *render_target, enum d2d_shape_type shape_type, ID3D11Buffer *ib, unsigned int index_count, ID3D11Buffer *vb, unsigned int vb_stride, struct d2d_brush *brush, struct d2d_brush *opacity_brush) { 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; @@ -137,8 +143,7 @@ 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); + d2d_device_context_enter_cs(render_target);
ID3D11Device1_GetImmediateContext1(device, &context); ID3D11DeviceContext1_SwapDeviceContextState(context, render_target->d3d_state, &prev_state); @@ -194,8 +199,7 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en ID3D11DeviceContext1_Release(context); ID3DDeviceContextState_Release(prev_state);
- ID2D1Multithread_Leave(multithread); - ID2D1Multithread_Release(multithread); + d2d_device_context_leave_cs(render_target); }
static void d2d_device_context_set_error(struct d2d_device_context *context, HRESULT code) @@ -3204,6 +3208,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, IDWriteFactory *dwrite_factory; D3D11_RASTERIZER_DESC rs_desc; D3D11_BUFFER_DESC buffer_desc; + ID2D1Multithread *multithread; unsigned int i; HRESULT hr;
@@ -4264,6 +4269,14 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, render_target->device = device; ID2D1Device1_AddRef(&render_target->device->ID2D1Device1_iface);
+ ID2D1Factory_QueryInterface(render_target->factory, &IID_ID2D1Multithread, (void **)&multithread); + if (ID2D1Multithread_GetMultithreadProtected(multithread)) { + render_target->cs = d2d_factory_mt_get_cs(multithread); + } else { + render_target->cs = NULL; + } + ID2D1Multithread_Release(multithread); + render_target->outer_unknown = outer_unknown ? outer_unknown : &render_target->IUnknown_iface; render_target->ops = ops;
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 3b2b1f5e4ec..063fa6a8543 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -1155,6 +1155,11 @@ static BOOL STDMETHODCALLTYPE d2d_factory_mt_GetMultithreadProtected(ID2D1Multit return TRUE; }
+CRITICAL_SECTION* d2d_factory_mt_get_cs(ID2D1Multithread *iface) { + struct d2d_factory *factory = impl_from_ID2D1Multithread(iface); + return &factory->cs; +} + static void STDMETHODCALLTYPE d2d_factory_mt_Enter(ID2D1Multithread *iface) { struct d2d_factory *factory = impl_from_ID2D1Multithread(iface);