[PATCH 2/4] ddraw: Use a less offensive handle table implementation for matrices.

Henri Verbeet hverbeet at codeweavers.com
Wed Jul 28 06:41:48 CDT 2010


---
 dlls/ddraw/ddraw_private.h |    2 +-
 dlls/ddraw/device.c        |   95 +++++++++++++++++++------------------------
 dlls/ddraw/executebuffer.c |   72 +++++++++++++++++----------------
 3 files changed, 80 insertions(+), 89 deletions(-)

diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index e5e6ff4..49ec317 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -326,7 +326,6 @@ typedef enum
 {
     DDrawHandle_Unknown       = 0,
     DDrawHandle_Texture       = 1,
-    DDrawHandle_Matrix        = 3,
     DDrawHandle_StateBlock    = 4
 } DDrawHandleTypes;
 
@@ -342,6 +341,7 @@ enum ddraw_handle_type
 {
     DDRAW_HANDLE_FREE,
     DDRAW_HANDLE_MATERIAL,
+    DDRAW_HANDLE_MATRIX,
 };
 
 struct ddraw_handle_entry
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index fee434e..449ca4d 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -382,14 +382,6 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
                     }
                     break;
 
-                    case DDrawHandle_Matrix:
-                    {
-                        /* No fixme here because this might happen because of sloppy apps */
-                        WARN("Leftover matrix handle %d, deleting\n", i + 1);
-                        IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
-                    }
-                    break;
-
                     case DDrawHandle_StateBlock:
                     {
                         /* No fixme here because this might happen because of sloppy apps */
@@ -423,6 +415,14 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
                     break;
                 }
 
+                case DDRAW_HANDLE_MATRIX:
+                {
+                    /* No FIXME here because this might happen because of sloppy applications. */
+                    WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object);
+                    IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
+                    break;
+                }
+
                 default:
                     FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
                     break;
@@ -1426,6 +1426,8 @@ IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DM
 {
     IDirect3DDeviceImpl *This = device_from_device1(iface);
     D3DMATRIX *Matrix;
+    DWORD h;
+
     TRACE("(%p)->(%p)\n", This, D3DMatHandle);
 
     if(!D3DMatHandle)
@@ -1439,16 +1441,18 @@ IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DM
     }
 
     EnterCriticalSection(&ddraw_cs);
-    *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
-    if(!(*D3DMatHandle))
+
+    h = ddraw_allocate_handle(&This->handle_table, Matrix, DDRAW_HANDLE_MATRIX);
+    if (h == DDRAW_INVALID_HANDLE)
     {
-        ERR("Failed to create a matrix handle\n");
+        ERR("Failed to allocate a matrix handle.\n");
         HeapFree(GetProcessHeap(), 0, Matrix);
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_OUTOFMEMORY;
     }
-    This->Handles[*D3DMatHandle - 1].ptr = Matrix;
-    This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
+
+    *D3DMatHandle = h + 1;
+
     TRACE(" returning matrix handle %d\n", *D3DMatHandle);
 
     LeaveCriticalSection(&ddraw_cs);
@@ -1479,21 +1483,18 @@ IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
                                 D3DMATRIX *D3DMatrix)
 {
     IDirect3DDeviceImpl *This = device_from_device1(iface);
+    D3DMATRIX *m;
+
     TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
 
-    if( (!D3DMatHandle) || (!D3DMatrix) )
-        return DDERR_INVALIDPARAMS;
+    if (!D3DMatrix) return DDERR_INVALIDPARAMS;
 
     EnterCriticalSection(&ddraw_cs);
-    if(D3DMatHandle > This->numHandles)
-    {
-        ERR("Handle %d out of range\n", D3DMatHandle);
-        LeaveCriticalSection(&ddraw_cs);
-        return DDERR_INVALIDPARAMS;
-    }
-    else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
+
+    m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
+    if (!m)
     {
-        ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
+        WARN("Invalid matrix handle.\n");
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
     }
@@ -1501,7 +1502,7 @@ IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
     if (TRACE_ON(d3d7))
         dump_D3DMATRIX(D3DMatrix);
 
-    *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
+    *m = *D3DMatrix;
 
     if(This->world == D3DMatHandle)
     {
@@ -1548,29 +1549,23 @@ IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
                                 D3DMATRIX *D3DMatrix)
 {
     IDirect3DDeviceImpl *This = device_from_device1(iface);
+    D3DMATRIX *m;
+
     TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
 
-    if(!D3DMatrix)
-        return DDERR_INVALIDPARAMS;
-    if(!D3DMatHandle)
-        return DDERR_INVALIDPARAMS;
+    if (!D3DMatrix) return DDERR_INVALIDPARAMS;
 
     EnterCriticalSection(&ddraw_cs);
-    if(D3DMatHandle > This->numHandles)
-    {
-        ERR("Handle %d out of range\n", D3DMatHandle);
-        LeaveCriticalSection(&ddraw_cs);
-        return DDERR_INVALIDPARAMS;
-    }
-    else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
+
+    m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
+    if (!m)
     {
-        ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
+        WARN("Invalid matrix handle.\n");
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
     }
 
-    /* The handle is simply a pointer to a D3DMATRIX structure */
-    *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
+    *D3DMatrix = *m;
 
     LeaveCriticalSection(&ddraw_cs);
     return D3D_OK;
@@ -1596,30 +1591,24 @@ IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
                                    D3DMATRIXHANDLE D3DMatHandle)
 {
     IDirect3DDeviceImpl *This = device_from_device1(iface);
-    TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
+    D3DMATRIX *m;
 
-    if(!D3DMatHandle)
-        return DDERR_INVALIDPARAMS;
+    TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
 
     EnterCriticalSection(&ddraw_cs);
-    if(D3DMatHandle > This->numHandles)
-    {
-        ERR("Handle %d out of range\n", D3DMatHandle);
-        LeaveCriticalSection(&ddraw_cs);
-        return DDERR_INVALIDPARAMS;
-    }
-    else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
+
+    m = ddraw_free_handle(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
+    if (!m)
     {
-        ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
+        WARN("Invalid matrix handle.\n");
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
     }
 
-    HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
-    This->Handles[D3DMatHandle - 1].ptr = NULL;
-    This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
-
     LeaveCriticalSection(&ddraw_cs);
+
+    HeapFree(GetProcessHeap(), 0, m);
+
     return D3D_OK;
 }
 
diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c
index 40b586f..59481b1 100644
--- a/dlls/ddraw/executebuffer.c
+++ b/dlls/ddraw/executebuffer.c
@@ -188,25 +188,24 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
 	        int i;
 		TRACE("MATRIXMULTIPLY   (%d)\n", count);
 		
-		for (i = 0; i < count; i++) {
-		    LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr;
-                    LPD3DMATRIX a, b, c;
-
-                    if(!ci->hDestMatrix || ci->hDestMatrix > lpDevice->numHandles ||
-                       !ci->hSrcMatrix1 || ci->hSrcMatrix1 > lpDevice->numHandles ||
-                       !ci->hSrcMatrix2 || ci->hSrcMatrix2 > lpDevice->numHandles) {
-                        ERR("Handles out of bounds\n");
-                    } else if (lpDevice->Handles[ci->hDestMatrix - 1].type != DDrawHandle_Matrix ||
-                               lpDevice->Handles[ci->hSrcMatrix1 - 1].type != DDrawHandle_Matrix ||
-                               lpDevice->Handles[ci->hSrcMatrix2 - 1].type != DDrawHandle_Matrix) {
-                        ERR("Handle types invalid\n");
-                    } else {
-                        a = (LPD3DMATRIX) lpDevice->Handles[ci->hDestMatrix - 1].ptr;
-                        b = (LPD3DMATRIX) lpDevice->Handles[ci->hSrcMatrix1 - 1].ptr;
-                        c = (LPD3DMATRIX) lpDevice->Handles[ci->hSrcMatrix2 - 1].ptr;
-                        TRACE("  Dest : %p  Src1 : %p  Src2 : %p\n",
-                            a, b, c);
-                        multiply_matrix(a,c,b);
+                for (i = 0; i < count; ++i)
+                {
+                    D3DMATRIXMULTIPLY *ci = (D3DMATRIXMULTIPLY *)instr;
+                    D3DMATRIX *a, *b, *c;
+
+                    a = ddraw_get_object(&lpDevice->handle_table, ci->hDestMatrix - 1, DDRAW_HANDLE_MATRIX);
+                    b = ddraw_get_object(&lpDevice->handle_table, ci->hSrcMatrix1 - 1, DDRAW_HANDLE_MATRIX);
+                    c = ddraw_get_object(&lpDevice->handle_table, ci->hSrcMatrix2 - 1, DDRAW_HANDLE_MATRIX);
+
+                    if (!a || !b || !c)
+                    {
+                        ERR("Invalid matrix handle (a %#x -> %p, b %#x -> %p, c %#x -> %p).\n",
+                                ci->hDestMatrix, a, ci->hSrcMatrix1, b, ci->hSrcMatrix2, c);
+                    }
+                    else
+                    {
+                        TRACE("dst %p, src1 %p, src2 %p.\n", a, b, c);
+                        multiply_matrix(a, c, b);
                     }
 
                     instr += size;
@@ -217,27 +216,30 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
 	        int i;
 		TRACE("STATETRANSFORM   (%d)\n", count);
 		
-		for (i = 0; i < count; i++) {
-		    LPD3DSTATE ci = (LPD3DSTATE) instr;
+                for (i = 0; i < count; ++i)
+                {
+                    D3DSTATE *ci = (D3DSTATE *)instr;
+                    D3DMATRIX *m;
 
-                    if(!ci->u2.dwArg[0]) {
-                        ERR("Setting a NULL matrix handle, what should I do?\n");
-                    } else if(ci->u2.dwArg[0] > lpDevice->numHandles) {
-                        ERR("Handle %d is out of bounds\n", ci->u2.dwArg[0]);
-                    } else if(lpDevice->Handles[ci->u2.dwArg[0] - 1].type != DDrawHandle_Matrix) {
-                        ERR("Handle %d is not a matrix handle\n", ci->u2.dwArg[0]);
-                    } else {
-                        if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_WORLD)
+                    m = ddraw_get_object(&lpDevice->handle_table, ci->u2.dwArg[0] - 1, DDRAW_HANDLE_MATRIX);
+                    if (!m)
+                    {
+                        ERR("Invalid matrix handle %#x.\n", ci->u2.dwArg[0]);
+                    }
+                    else
+                    {
+                        if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_WORLD)
                             lpDevice->world = ci->u2.dwArg[0];
-                        if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_VIEW)
+                        if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_VIEW)
                             lpDevice->view = ci->u2.dwArg[0];
-                        if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION)
+                        if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION)
                             lpDevice->proj = ci->u2.dwArg[0];
                         IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)lpDevice,
-                                ci->u1.dtstTransformStateType, (LPD3DMATRIX)lpDevice->Handles[ci->u2.dwArg[0] - 1].ptr);
+                                ci->u1.dtstTransformStateType, m);
                     }
-		    instr += size;
-		}
+
+                    instr += size;
+                }
 	    } break;
 
 	    case D3DOP_STATELIGHT: {
-- 
1.7.1




More information about the wine-patches mailing list