[8/9] Make IDirectDrawViewportImpl thread safe
Stefan Dösinger
stefandoesinger at gmx.at
Sat Aug 19 16:53:43 CDT 2006
-------------- next part --------------
From nobody Mon Sep 17 00:00:00 2001
From: Stefan Dösinger <stefan at codeweavers.com>
Date: Sat Aug 19 09:38:49 2006 +0200
Subject: [PATCH] DDraw: Make IDirectDrawViewportImpl thread safe
---
dlls/ddraw/ddraw_private.h | 4 ++++
dlls/ddraw/device.c | 15 +++++++++++++
dlls/ddraw/direct3d.c | 6 ++++-
dlls/ddraw/viewport.c | 49 +++++++++++++++++++++++++++++++++++++-------
4 files changed, 64 insertions(+), 10 deletions(-)
09778f76d56cf5fc9db43a0310c4271545efc53d
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index b610df2..e0cbbb9 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -540,6 +540,10 @@ struct IDirect3DViewportImpl
/* Background material */
IDirect3DMaterialImpl *background;
+
+ /* Thread synchronisation */
+ CRITICAL_SECTION crit;
+ BOOL hasCrit;
};
/* Vtable */
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 07cf330..57045ea 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -767,7 +767,9 @@ IDirect3DDeviceImpl_1_Execute(IDirect3DD
/* Execute... */
DDOBJ_LOCK(This);
+ DDOBJ_LOCK(Direct3DViewportImpl);
IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
+ DDOBJ_UNLOCK(Direct3DViewportImpl);
DDOBJ_UNLOCK(This);
return D3D_OK;
@@ -804,8 +806,10 @@ IDirect3DDeviceImpl_3_AddViewport(IDirec
return DDERR_INVALIDPARAMS;
DDOBJ_LOCK(This);
+ DDOBJ_LOCK(vp);
vp->next = This->viewport_list;
This->viewport_list = vp;
+ DDOBJ_UNLOCK(vp);
DDOBJ_UNLOCK(This);
return D3D_OK;
@@ -860,7 +864,9 @@ IDirect3DDeviceImpl_3_DeleteViewport(IDi
TRACE("(%p)->(%p)\n", This, vp);
DDOBJ_LOCK(This);
+ DDOBJ_LOCK(vp);
cur_viewport = This->viewport_list;
+ DDOBJ_LOCK(cur_viewport);
while (cur_viewport != NULL)
{
if (cur_viewport == vp)
@@ -869,13 +875,18 @@ IDirect3DDeviceImpl_3_DeleteViewport(IDi
else prev_viewport->next = cur_viewport->next;
/* TODO : add desactivate of the viewport and all associated lights... */
{
+ DDOBJ_UNLOCK(cur_viewport);
+ DDOBJ_UNLOCK(vp);
DDOBJ_UNLOCK(This);
return D3D_OK;
}
}
prev_viewport = cur_viewport;
+ DDOBJ_UNLOCK(cur_viewport);
cur_viewport = cur_viewport->next;
+ DDOBJ_LOCK(cur_viewport);
}
+ DDOBJ_UNLOCK(vp);
DDOBJ_UNLOCK(This);
return DDERR_INVALIDPARAMS;
@@ -935,8 +946,8 @@ IDirect3DDeviceImpl_3_NextViewport(IDire
if(!vp)
{
- return DDERR_INVALIDPARAMS;
*lplpDirect3DViewport3 = NULL;
+ return DDERR_INVALIDPARAMS;
}
DDOBJ_LOCK(This);
@@ -944,7 +955,9 @@ IDirect3DDeviceImpl_3_NextViewport(IDire
{
case D3DNEXT_NEXT:
{
+ DDOBJ_LOCK(vp);
res = vp->next;
+ DDOBJ_UNLOCK(vp);
}
break;
case D3DNEXT_HEAD:
diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c
index 6ef8e39..3d8418a 100644
--- a/dlls/ddraw/direct3d.c
+++ b/dlls/ddraw/direct3d.c
@@ -599,7 +599,11 @@ IDirect3DImpl_3_CreateViewport(IDirect3D
object->lights = NULL;
object->num_lights = 0;
object->map_lights = 0;
-
+ if(This->hasCrit)
+ {
+ InitializeCriticalSection(&object->crit);
+ object->hasCrit = TRUE;
+ }
*Viewport = ICOM_INTERFACE(object, IDirect3DViewport3);
TRACE("(%p) creating implementation at %p.\n",This, object);
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c
index 154c81e..0e26fc0 100644
--- a/dlls/ddraw/viewport.c
+++ b/dlls/ddraw/viewport.c
@@ -59,7 +59,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
void viewport_activate(IDirect3DViewportImpl* This) {
IDirect3DLightImpl* light;
D3DVIEWPORT7 vp;
-
+ DDOBJ_LOCK(This);
+
/* Activate all the lights associated with this context */
light = This->lights;
@@ -84,7 +85,8 @@ void viewport_activate(IDirect3DViewport
vp.dvMinZ = This->viewports.vp1.dvMinZ;
vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
}
-
+ DDOBJ_UNLOCK(This);
+
/* And also set the viewport */
IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
}
@@ -254,7 +256,10 @@ IDirect3DViewportImpl_GetViewport(IDirec
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
DWORD dwSize;
TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
+
+ DDOBJ_LOCK(This);
if (This->use_vp2 != 0) {
+ DDOBJ_UNLOCK(This);
ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
return DDERR_INVALIDPARAMS;
}
@@ -266,7 +271,8 @@ IDirect3DViewportImpl_GetViewport(IDirec
TRACE(" returning D3DVIEWPORT :\n");
_dump_D3DVIEWPORT(lpData);
}
-
+ DDOBJ_UNLOCK(This);
+
return DD_OK;
}
@@ -291,6 +297,7 @@ IDirect3DViewportImpl_SetViewport(IDirec
LPDIRECT3DVIEWPORT3 current_viewport;
TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
+ DDOBJ_LOCK(This);
if (TRACE_ON(d3d7)) {
TRACE(" getting D3DVIEWPORT :\n");
_dump_D3DVIEWPORT(lpData);
@@ -312,6 +319,7 @@ IDirect3DViewportImpl_SetViewport(IDirec
This->activate(This);
if(current_viewport) IDirect3DViewport3_Release(current_viewport);
}
+ DDOBJ_UNLOCK(This);
return DD_OK;
}
@@ -386,17 +394,21 @@ IDirect3DViewportImpl_SetBackground(IDir
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
TRACE("(%p)->(%ld)\n", This, (DWORD) hMat);
+ DDOBJ_LOCK(This->ddraw->d3ddevice);
if(hMat && hMat > This->ddraw->d3ddevice->numHandles)
{
+ DDOBJ_UNLOCK(This->ddraw->d3ddevice);
WARN("Specified Handle %ld out of range\n", hMat);
return DDERR_INVALIDPARAMS;
}
else if(hMat && This->ddraw->d3ddevice->Handles[hMat - 1].type != DDrawHandle_Material)
{
+ DDOBJ_UNLOCK(This->ddraw->d3ddevice);
WARN("Handle %ld is not a material handle\n", hMat);
return DDERR_INVALIDPARAMS;
}
+ DDOBJ_LOCK(This);
if(hMat)
{
This->background = (IDirect3DMaterialImpl *) This->ddraw->d3ddevice->Handles[hMat - 1].ptr;
@@ -411,6 +423,8 @@ IDirect3DViewportImpl_SetBackground(IDir
This->background = NULL;
TRACE("Setting background to NULL\n");
}
+ DDOBJ_UNLOCK(This);
+ DDOBJ_UNLOCK(This->ddraw->d3ddevice);
return D3D_OK;
}
@@ -436,6 +450,7 @@ IDirect3DViewportImpl_GetBackground(IDir
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
TRACE("(%p)->(%p,%p)\n", This, lphMat, lpValid);
+ DDOBJ_LOCK(This);
if(lpValid)
{
*lpValid = This->background != NULL;
@@ -444,13 +459,16 @@ IDirect3DViewportImpl_GetBackground(IDir
{
if(This->background)
{
+ DDOBJ_LOCK(This->background);
*lphMat = This->background->Handle;
+ DDOBJ_UNLOCK(This->background);
}
else
{
*lphMat = 0;
}
}
+ DDOBJ_UNLOCK(This);
return D3D_OK;
}
@@ -525,8 +543,9 @@ IDirect3DViewportImpl_Clear(IDirect3DVie
{
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
DWORD color = 0x00000000;
-
+
TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
+
if (This->active_device == NULL) {
ERR(" Trying to clear a viewport not attached to a device !\n");
return D3DERR_VIEWPORTHASNODEVICE;
@@ -535,6 +554,7 @@ IDirect3DViewportImpl_Clear(IDirect3DVie
if (This->background == NULL) {
ERR(" Trying to clear the color buffer without background material !\n");
} else {
+ DDOBJ_LOCK(This);
DDOBJ_LOCK(This->background);
color =
((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
@@ -542,6 +562,7 @@ IDirect3DViewportImpl_Clear(IDirect3DVie
((int) ((This->background->mat.u.diffuse.u3.b) * 255) << 0) |
((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
DDOBJ_UNLOCK(This->background);
+ DDOBJ_UNLOCK(This);
}
}
@@ -575,14 +596,16 @@ IDirect3DViewportImpl_AddLight(IDirect3D
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
DWORD i = 0;
- DWORD map = This->map_lights;
+ DWORD map;
TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
if (This->num_lights >= 8)
return DDERR_INVALIDPARAMS;
+ DDOBJ_LOCK(This);
/* Find a light number and update both light and viewports objects accordingly */
+ map = This->map_lights;
while(map&1) {
map>>=1;
i++;
@@ -602,7 +625,8 @@ IDirect3DViewportImpl_AddLight(IDirect3D
if (This->active_device != NULL) {
lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
}
-
+ DDOBJ_UNLOCK(This);
+
return D3D_OK;
}
@@ -628,6 +652,7 @@ IDirect3DViewportImpl_DeleteLight(IDirec
IDirect3DLightImpl *cur_light, *prev_light = NULL;
TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
+ DDOBJ_LOCK(This);
cur_light = This->lights;
while (cur_light != NULL) {
if (cur_light == lpDirect3DLightImpl) {
@@ -638,11 +663,13 @@ IDirect3DViewportImpl_DeleteLight(IDirec
cur_light->active_viewport = NULL;
This->num_lights--;
This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
- return D3D_OK;
+ DDOBJ_UNLOCK(This);
+ return D3D_OK;
}
prev_light = cur_light;
cur_light = cur_light->next;
}
+ DDOBJ_UNLOCK(This);
return DDERR_INVALIDPARAMS;
}
@@ -697,7 +724,10 @@ IDirect3DViewportImpl_GetViewport2(IDire
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
DWORD dwSize;
TRACE("(%p)->(%p)\n", This, lpData);
+
+ DDOBJ_LOCK(This);
if (This->use_vp2 != 1) {
+ DDOBJ_UNLOCK(This);
ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
return DDERR_INVALIDPARAMS;
}
@@ -709,7 +739,8 @@ IDirect3DViewportImpl_GetViewport2(IDire
TRACE(" returning D3DVIEWPORT2 :\n");
_dump_D3DVIEWPORT2(lpData);
}
-
+ DDOBJ_UNLOCK(This);
+
return D3D_OK;
}
@@ -738,6 +769,7 @@ IDirect3DViewportImpl_SetViewport2(IDire
_dump_D3DVIEWPORT2(lpData);
}
+ DDOBJ_LOCK(This);
This->use_vp2 = 1;
memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
@@ -748,6 +780,7 @@ IDirect3DViewportImpl_SetViewport2(IDire
This->activate(This);
IDirect3DViewport3_Release(current_viewport);
}
+ DDOBJ_UNLOCK(This);
return D3D_OK;
}
--
1.2.4
More information about the wine-patches
mailing list