Module: wine Branch: master Commit: 91193b6eeccfe2c4d0eae9622338371b3ec35375 URL: http://source.winehq.org/git/wine.git/?a=commit;h=91193b6eeccfe2c4d0eae96223...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Fri Jul 30 10:15:23 2010 +0200
ddraw: Use a less offensive handle table implementation for stateblocks.
---
dlls/ddraw/ddraw_private.h | 2 +- dlls/ddraw/device.c | 122 ++++++++++++++++++++++++------------------- 2 files changed, 69 insertions(+), 55 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 49ec317..f41a695 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_StateBlock = 4 } DDrawHandleTypes;
struct HandleEntry @@ -342,6 +341,7 @@ enum ddraw_handle_type DDRAW_HANDLE_FREE, DDRAW_HANDLE_MATERIAL, DDRAW_HANDLE_MATRIX, + DDRAW_HANDLE_STATEBLOCK, };
struct ddraw_handle_entry diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 449ca4d..5814158 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -382,14 +382,6 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) } break;
- case DDrawHandle_StateBlock: - { - /* No fixme here because this might happen because of sloppy apps */ - WARN("Leftover stateblock handle %d, deleting\n", i + 1); - IDirect3DDevice7_DeleteStateBlock((IDirect3DDevice7 *)This, i + 1); - } - break; - default: FIXME("Unknown handle %d not unset properly\n", i + 1); } @@ -423,6 +415,14 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) break; }
+ case DDRAW_HANDLE_STATEBLOCK: + { + /* No FIXME here because this might happen because of sloppy applications. */ + WARN("Leftover stateblock handle %#x (%p), deleting.\n", i + 1, entry->object); + IDirect3DDevice7_DeleteStateBlock(iface, i + 1); + break; + } + default: FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); break; @@ -5604,7 +5604,10 @@ IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface, DWORD *BlockHandle) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; + IWineD3DStateBlock *wined3d_sb; HRESULT hr; + DWORD h; + TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
if(!BlockHandle) @@ -5614,17 +5617,29 @@ IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface, }
EnterCriticalSection(&ddraw_cs); - *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This); - if(!*BlockHandle) + + hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice, &wined3d_sb); + if (FAILED(hr)) + { + WARN("Failed to end stateblock, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + *BlockHandle = 0; + return hr_ddraw_from_wined3d(hr); + } + + h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK); + if (h == DDRAW_INVALID_HANDLE) { - ERR("Cannot get a handle number for the stateblock\n"); + ERR("Failed to allocate a stateblock handle.\n"); + IWineD3DStateBlock_Release(wined3d_sb); LeaveCriticalSection(&ddraw_cs); + *BlockHandle = 0; return DDERR_OUTOFMEMORY; } - This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock; - hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice, - (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr); + LeaveCriticalSection(&ddraw_cs); + *BlockHandle = h + 1; + return hr_ddraw_from_wined3d(hr); }
@@ -5723,25 +5738,23 @@ IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface, DWORD BlockHandle) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; + IWineD3DStateBlock *wined3d_sb; HRESULT hr; TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
EnterCriticalSection(&ddraw_cs); - if(!BlockHandle || BlockHandle > This->numHandles) - { - WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle); - LeaveCriticalSection(&ddraw_cs); - return D3DERR_INVALIDSTATEBLOCK; - } - if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock) + + wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK); + if (!wined3d_sb) { - WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle); + WARN("Invalid stateblock handle.\n"); LeaveCriticalSection(&ddraw_cs); return D3DERR_INVALIDSTATEBLOCK; }
- hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr); + hr = IWineD3DStateBlock_Apply(wined3d_sb); LeaveCriticalSection(&ddraw_cs); + return hr_ddraw_from_wined3d(hr); }
@@ -5787,24 +5800,21 @@ IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface, DWORD BlockHandle) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; + IWineD3DStateBlock *wined3d_sb; HRESULT hr; TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
EnterCriticalSection(&ddraw_cs); - if(BlockHandle == 0 || BlockHandle > This->numHandles) - { - WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle); - LeaveCriticalSection(&ddraw_cs); - return D3DERR_INVALIDSTATEBLOCK; - } - if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock) + + wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK); + if (!wined3d_sb) { - WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle); + WARN("Invalid stateblock handle.\n"); LeaveCriticalSection(&ddraw_cs); return D3DERR_INVALIDSTATEBLOCK; }
- hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr); + hr = IWineD3DStateBlock_Capture(wined3d_sb); LeaveCriticalSection(&ddraw_cs); return hr_ddraw_from_wined3d(hr); } @@ -5850,30 +5860,24 @@ IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface, DWORD BlockHandle) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; + IWineD3DStateBlock *wined3d_sb; ULONG ref; TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
EnterCriticalSection(&ddraw_cs); - if(BlockHandle == 0 || BlockHandle > This->numHandles) - { - WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle); - LeaveCriticalSection(&ddraw_cs); - return D3DERR_INVALIDSTATEBLOCK; - } - if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock) + + wined3d_sb = ddraw_free_handle(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK); + if (!wined3d_sb) { - WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle); + WARN("Invalid stateblock handle.\n"); LeaveCriticalSection(&ddraw_cs); return D3DERR_INVALIDSTATEBLOCK; }
- ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr); - if(ref) + if ((ref = IWineD3DStateBlock_Release(wined3d_sb))) { - ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref); + ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb, ref); } - This->Handles[BlockHandle - 1].ptr = NULL; - This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
LeaveCriticalSection(&ddraw_cs); return D3D_OK; @@ -5922,7 +5926,10 @@ IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface, DWORD *BlockHandle) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; + IWineD3DStateBlock *wined3d_sb; HRESULT hr; + DWORD h; + TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
if(!BlockHandle) @@ -5937,21 +5944,28 @@ IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface, }
EnterCriticalSection(&ddraw_cs); - *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This); - if(!*BlockHandle) + + /* The D3DSTATEBLOCKTYPE enum is fine here. */ + hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice, Type, &wined3d_sb, NULL); + if (FAILED(hr)) { - ERR("Cannot get a handle number for the stateblock\n"); + WARN("Failed to create stateblock, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return hr_ddraw_from_wined3d(hr); + } + + h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK); + if (h == DDRAW_INVALID_HANDLE) + { + ERR("Failed to allocate stateblock handle.\n"); + IWineD3DStateBlock_Release(wined3d_sb); LeaveCriticalSection(&ddraw_cs); return DDERR_OUTOFMEMORY; } - This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
- /* The D3DSTATEBLOCKTYPE enum is fine here */ - hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice, - Type, - (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr, - NULL /* Parent, hope that works */); + *BlockHandle = h + 1; LeaveCriticalSection(&ddraw_cs); + return hr_ddraw_from_wined3d(hr); }