[6/9] DDraw: Make IDirect3DMaterialImpl thread safe
Stefan Dösinger
stefandoesinger at gmx.at
Sat Aug 19 16:52:25 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:31:52 2006 +0200
Subject: [PATCH] DDraw: Make IDirectDrawMaterialImpl thread safe
---
dlls/ddraw/ddraw_private.h | 4 ++++
dlls/ddraw/device.c | 2 ++
dlls/ddraw/direct3d.c | 6 ++++++
dlls/ddraw/material.c | 17 ++++++++++++++++-
dlls/ddraw/viewport.c | 4 +++-
5 files changed, 31 insertions(+), 2 deletions(-)
951d528053a55f4e53dae70a62dc8f19ba789f94
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 36f2c63..b610df2 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -490,6 +490,10 @@ struct IDirect3DMaterialImpl
DWORD Handle;
void (*activate)(IDirect3DMaterialImpl* this);
+
+ /* Thread synchronisation */
+ CRITICAL_SECTION crit;
+ BOOL hasCrit;
};
/* VTables in various versions */
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 7c4a303..07cf330 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -345,7 +345,9 @@ IDirect3DDeviceImpl_7_Release(IDirect3DD
{
IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) This->Handles[i].ptr;
FIXME("Material handle %ld not unset properly\n", i + 1);
+ DDOBJ_LOCK(mat);
mat->Handle = 0;
+ DDOBJ_UNLOCK(mat);
}
break;
diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c
index c02d04c..c72b50a 100644
--- a/dlls/ddraw/direct3d.c
+++ b/dlls/ddraw/direct3d.c
@@ -500,6 +500,12 @@ IDirect3DImpl_3_CreateMaterial(IDirect3D
object->ddraw = This;
object->activate = material_activate;
+ if(This->hasCrit)
+ {
+ InitializeCriticalSection(&object->crit);
+ object->hasCrit = TRUE;
+ }
+
*Material = ICOM_INTERFACE(object, IDirect3DMaterial3);
TRACE("(%p) creating implementation at %p.\n", This, object);
diff --git a/dlls/ddraw/material.c b/dlls/ddraw/material.c
index 7b7839c..16596a9 100644
--- a/dlls/ddraw/material.c
+++ b/dlls/ddraw/material.c
@@ -149,12 +149,19 @@ IDirect3DMaterialImpl_Release(IDirect3DM
if (!ref)
{
+ DDOBJ_LOCK(This);
if(This->Handle)
{
This->ddraw->d3ddevice->Handles[This->Handle - 1].ptr = NULL;
This->ddraw->d3ddevice->Handles[This->Handle - 1].type = DDrawHandle_Unknown;
}
+ DDOBJ_UNLOCK(This);
+ if(This->hasCrit)
+ {
+ DeleteCriticalSection(&This->crit);
+ This->hasCrit = FALSE;
+ }
HeapFree(GetProcessHeap(), 0, This);
return 0;
}
@@ -248,9 +255,11 @@ IDirect3DMaterialImpl_SetMaterial(IDirec
dump_material(lpMat);
/* Stores the material */
+ DDOBJ_LOCK(This);
memset(&This->mat, 0, sizeof(This->mat));
memcpy(&This->mat, lpMat, lpMat->dwSize);
-
+ DDOBJ_UNLOCK(This);
+
return DD_OK;
}
@@ -281,8 +290,10 @@ IDirect3DMaterialImpl_GetMaterial(IDirec
/* Copies the material structure */
dwSize = lpMat->dwSize;
+ DDOBJ_LOCK(This);
memset(lpMat, 0, dwSize);
memcpy(lpMat, &This->mat, dwSize);
+ DDOBJ_UNLOCK(This);
return DD_OK;
}
@@ -311,6 +322,7 @@ IDirect3DMaterialImpl_GetHandle(IDirect3
IDirect3DDeviceImpl *device = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, lpDirect3DDevice3);
TRACE("(%p/%p)->(%p,%p)\n", This, iface, device, lpHandle);
+ DDOBJ_LOCK(This);
This->active_device = device;
if(!This->Handle)
{
@@ -326,6 +338,7 @@ IDirect3DMaterialImpl_GetHandle(IDirect3
DDOBJ_UNLOCK(device);
}
*lpHandle = This->Handle;
+ DDOBJ_UNLOCK(This);
TRACE(" returning handle %08lx.\n", *lpHandle);
return D3D_OK;
@@ -454,11 +467,13 @@ void material_activate(IDirect3DMaterial
D3DMATERIAL7 d3d7mat;
TRACE("Activating material %p\n", This);
+ DDOBJ_LOCK(This);
d3d7mat.u.diffuse = This->mat.u.diffuse;
d3d7mat.u1.ambient = This->mat.u1.ambient;
d3d7mat.u2.specular = This->mat.u2.specular;
d3d7mat.u3.emissive = This->mat.u3.emissive;
d3d7mat.u4.power = This->mat.u4.power;
+ DDOBJ_UNLOCK(This);
IDirect3DDevice7_SetMaterial(ICOM_INTERFACE(This->active_device, IDirect3DDevice7),
&d3d7mat);
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c
index 71c426b..154c81e 100644
--- a/dlls/ddraw/viewport.c
+++ b/dlls/ddraw/viewport.c
@@ -535,12 +535,14 @@ IDirect3DViewportImpl_Clear(IDirect3DVie
if (This->background == NULL) {
ERR(" Trying to clear the color buffer without background material !\n");
} else {
+ DDOBJ_LOCK(This->background);
color =
((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
((int) ((This->background->mat.u.diffuse.u2.g) * 255) << 8) |
((int) ((This->background->mat.u.diffuse.u3.b) * 255) << 0) |
((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
- }
+ DDOBJ_UNLOCK(This->background);
+ }
}
return IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7),
--
1.2.4
More information about the wine-patches
mailing list