[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