Module: wine Branch: master Commit: d08585e6ecaffa956ad937718191d6bb27c6f5dc URL: http://source.winehq.org/git/wine.git/?a=commit;h=d08585e6ecaffa956ad9377181...
Author: Stefan Dösinger stefan@codeweavers.com Date: Mon May 7 20:46:24 2007 +0200
wined3d: Manage private data in a wine linked list.
---
dlls/wined3d/device.c | 1 + dlls/wined3d/resource.c | 96 +++++++++++++++++++++------------------- dlls/wined3d/wined3d_private.h | 7 +-- 3 files changed, 55 insertions(+), 49 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 9a419f0..16df8a5 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -109,6 +109,7 @@ static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3 object->resource.format = Format; \ object->resource.usage = Usage; \ object->resource.size = _size; \ + list_init(&object->resource.privateData); \ /* Check that we have enough video ram left */ \ if (Pool == WINED3DPOOL_DEFAULT) { \ if (IWineD3DDevice_GetAvailableTextureMem(iface) <= _size) { \ diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index a463d82..d99adb2 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -88,58 +88,66 @@ HRESULT WINAPI IWineD3DResourceImpl_GetDevice(IWineD3DResource *iface, IWineD3DD return WINED3D_OK; }
-static PrivateData** IWineD3DResourceImpl_FindPrivateData(IWineD3DResourceImpl *This, +static PrivateData* IWineD3DResourceImpl_FindPrivateData(IWineD3DResourceImpl *This, REFGUID tag) { - PrivateData** data; - for (data = &This->resource.privateData; *data != NULL; data = &(*data)->next) + PrivateData *data; + struct list *entry; + + TRACE("Searching for private data %s\n", debugstr_guid(tag)); + LIST_FOR_EACH(entry, &This->resource.privateData) { - if (IsEqualGUID(&(*data)->tag, tag)) break; + data = LIST_ENTRY(entry, PrivateData, entry); + if (IsEqualGUID(&data->tag, tag)) { + TRACE("Found %p\n", data); + return data; + } } - return data; + TRACE("Not found\n"); + return NULL; }
HRESULT WINAPI IWineD3DResourceImpl_SetPrivateData(IWineD3DResource *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface; - PrivateData **data; + PrivateData *data;
- TRACE("(%p) : %p %p %d %d\n", This, refguid, pData, SizeOfData, Flags); + TRACE("(%p) : %s %p %d %d\n", This, debugstr_guid(refguid), pData, SizeOfData, Flags); data = IWineD3DResourceImpl_FindPrivateData(This, refguid); - if (*data == NULL) + if (data == NULL) { - *data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**data)); - if (NULL == *data) return E_OUTOFMEMORY; + data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)); + if (NULL == data) return E_OUTOFMEMORY;
- (*data)->tag = *refguid; - (*data)->flags = Flags; + data->tag = *refguid; + data->flags = Flags; #if 0 (*data)->uniquenessValue = This->uniquenessValue; #endif if (Flags & WINED3DSPD_IUNKNOWN) { - (*data)->ptr.object = (LPUNKNOWN)pData; - (*data)->size = sizeof(LPUNKNOWN); - IUnknown_AddRef((*data)->ptr.object); + data->ptr.object = (LPUNKNOWN)pData; + data->size = sizeof(LPUNKNOWN); + IUnknown_AddRef(data->ptr.object); } else { - (*data)->ptr.data = HeapAlloc(GetProcessHeap(), 0, SizeOfData); - if (NULL == (*data)->ptr.data) { - HeapFree(GetProcessHeap(), 0, *data); + data->ptr.data = HeapAlloc(GetProcessHeap(), 0, SizeOfData); + if (NULL == data->ptr.data) { + HeapFree(GetProcessHeap(), 0, data); return E_OUTOFMEMORY; } - (*data)->size = SizeOfData; - memcpy((*data)->ptr.data, pData, SizeOfData); + data->size = SizeOfData; + memcpy(data->ptr.data, pData, SizeOfData); } - /* link it in */ - (*data)->next = This->resource.privateData; - This->resource.privateData = *data; + list_add_tail(&This->resource.privateData, &data->entry); return WINED3D_OK;
} else { /* I don't actually know how windows handles this case. The only - * reason I don't just call FreePrivateData is because I want to - * guarantee SetPrivateData working when using LPUNKNOWN or data - * that is no larger than the old data. */ + * reason I don't just call FreePrivateData is because I want to + * guarantee SetPrivateData working when using LPUNKNOWN or data + * that is no larger than the old data. + */ + FIXME("Handle overwriting private data in SetPrivateData\n"); return E_FAIL;
} @@ -149,11 +157,11 @@ HRESULT WINAPI IWineD3DResourceImpl_SetPrivateData(IWineD3DResource *iface, REFG
HRESULT WINAPI IWineD3DResourceImpl_GetPrivateData(IWineD3DResource *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface; - PrivateData **data; + PrivateData *data;
TRACE("(%p) : %p %p %p\n", This, refguid, pData, pSizeOfData); data = IWineD3DResourceImpl_FindPrivateData(This, refguid); - if (*data == NULL) return WINED3DERR_NOTFOUND; + if (data == NULL) return WINED3DERR_NOTFOUND;
#if 0 /* This may not be right. */ @@ -161,41 +169,39 @@ HRESULT WINAPI IWineD3DResourceImpl_GetPrivateData(IWineD3DResource *iface, REFG && (*data)->uniquenessValue != This->uniquenessValue) return DDERR_EXPIRED; #endif - if (*pSizeOfData < (*data)->size) { - *pSizeOfData = (*data)->size; + if (*pSizeOfData < data->size) { + *pSizeOfData = data->size; return WINED3DERR_MOREDATA; }
- if ((*data)->flags & WINED3DSPD_IUNKNOWN) { - *(LPUNKNOWN *)pData = (*data)->ptr.object; - IUnknown_AddRef((*data)->ptr.object); + if (data->flags & WINED3DSPD_IUNKNOWN) { + *(LPUNKNOWN *)pData = data->ptr.object; + IUnknown_AddRef(data->ptr.object); } else { - memcpy(pData, (*data)->ptr.data, (*data)->size); + memcpy(pData, data->ptr.data, data->size); }
return WINED3D_OK; } HRESULT WINAPI IWineD3DResourceImpl_FreePrivateData(IWineD3DResource *iface, REFGUID refguid) { IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface; - PrivateData **data; + PrivateData *data;
- TRACE("(%p) : %p\n", This, refguid); - /* TODO: move this code off into a linked list class */ + TRACE("(%p) : %s\n", This, debugstr_guid(refguid)); data = IWineD3DResourceImpl_FindPrivateData(This, refguid); - if (*data == NULL) return WINED3DERR_NOTFOUND; - - *data = (*data)->next; + if (data == NULL) return WINED3DERR_NOTFOUND;
- if ((*data)->flags & WINED3DSPD_IUNKNOWN) + if (data->flags & WINED3DSPD_IUNKNOWN) { - if ((*data)->ptr.object != NULL) - IUnknown_Release((*data)->ptr.object); + if (data->ptr.object != NULL) + IUnknown_Release(data->ptr.object); } else { - HeapFree(GetProcessHeap(), 0, (*data)->ptr.data); + HeapFree(GetProcessHeap(), 0, data->ptr.data); } + list_remove(&data->entry);
- HeapFree(GetProcessHeap(), 0, *data); + HeapFree(GetProcessHeap(), 0, data);
return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ce2dae3..c7a9744 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -741,11 +741,10 @@ static inline BOOL isStateDirty(WineD3DContext *context, DWORD state) { return context->isStateDirty[idx] & (1 << shift); }
-/* Support for IWineD3DResource ::Set/Get/FreePrivateData. I don't think - * anybody uses it for much so a good implementation is optional. */ +/* Support for IWineD3DResource ::Set/Get/FreePrivateData. */ typedef struct PrivateData { - struct PrivateData* next; + struct list entry;
GUID tag; DWORD flags; /* DDSPD_* */ @@ -777,7 +776,7 @@ typedef struct IWineD3DResourceClass DWORD usage; WINED3DFORMAT format; BYTE *allocatedMemory; - PrivateData *privateData; + struct list privateData;
} IWineD3DResourceClass;