From 6a34d4b40fea64713728365c2326f70df952229f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Fri, 14 Mar 2014 14:50:33 +0100 Subject: [PATCH] wined3d: Decouple private data from the resource structure. --- dlls/wined3d/resource.c | 98 +++++----------------------------- dlls/wined3d/wined3d_private.h | 2 +- include/wine/wined3d.h | 94 ++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 85 deletions(-) diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 6c3fd7a6814..782cc9fb9fc 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -27,20 +27,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -struct private_data -{ - struct list entry; - - GUID tag; - DWORD flags; /* DDSPD_* */ - DWORD size; - union - { - BYTE data[1]; - IUnknown *object; - } ptr; -}; - static DWORD resource_access_from_pool(enum wined3d_pool pool) { switch (pool) @@ -114,7 +100,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * resource->parent = parent; resource->parent_ops = parent_ops; resource->resource_ops = resource_ops; - list_init(&resource->privateData); + wined3d_private_store_init(&resource->private_store); if (size) { @@ -149,9 +135,6 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * void resource_cleanup(struct wined3d_resource *resource) { const struct wined3d *d3d = resource->device->wined3d; - struct private_data *data; - struct list *e1, *e2; - HRESULT hr; TRACE("Cleaning up resource %p.\n", resource); @@ -161,13 +144,7 @@ void resource_cleanup(struct wined3d_resource *resource) adapter_adjust_memory(resource->device->adapter, 0 - resource->size); } - LIST_FOR_EACH_SAFE(e1, e2, &resource->privateData) - { - data = LIST_ENTRY(e1, struct private_data, entry); - hr = wined3d_resource_free_private_data(resource, &data->tag); - if (FAILED(hr)) - ERR("Failed to free private data when destroying resource %p, hr = %#x.\n", resource, hr); - } + wined3d_private_store_cleanup(&resource->private_store); wined3d_resource_free_sysmem(resource); @@ -183,69 +160,25 @@ void resource_unload(struct wined3d_resource *resource) resource, resource->type); } -static struct private_data *resource_find_private_data(const struct wined3d_resource *resource, REFGUID tag) -{ - struct private_data *data; - struct list *entry; - - TRACE("Searching for private data %s\n", debugstr_guid(tag)); - LIST_FOR_EACH(entry, &resource->privateData) - { - data = LIST_ENTRY(entry, struct private_data, entry); - if (IsEqualGUID(&data->tag, tag)) { - TRACE("Found %p\n", data); - return data; - } - } - TRACE("Not found\n"); - return NULL; -} - HRESULT CDECL wined3d_resource_set_private_data(struct wined3d_resource *resource, REFGUID guid, const void *data, DWORD data_size, DWORD flags) { - struct private_data *d; - const void *ptr = data; - TRACE("resource %p, riid %s, data %p, data_size %u, flags %#x.\n", resource, debugstr_guid(guid), data, data_size, flags); - if (flags & WINED3DSPD_IUNKNOWN) - { - if (data_size != sizeof(IUnknown *)) - { - WARN("IUnknown data with size %u, returning WINED3DERR_INVALIDCALL.\n", data_size); - return WINED3DERR_INVALIDCALL; - } - ptr = &data; - } - - if (!(d = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(struct private_data, ptr.data[data_size])))) - return E_OUTOFMEMORY; - wined3d_resource_free_private_data(resource, guid); - - d->tag = *guid; - d->flags = flags; - d->size = data_size; - - memcpy(d->ptr.data, ptr, data_size); - if (flags & WINED3DSPD_IUNKNOWN) - IUnknown_AddRef(d->ptr.object); - list_add_tail(&resource->privateData, &d->entry); - - return WINED3D_OK; + return wined3d_private_store_set_private_data(&resource->private_store, guid, data, data_size, flags); } HRESULT CDECL wined3d_resource_get_private_data(const struct wined3d_resource *resource, REFGUID guid, void *data, DWORD *data_size) { - const struct private_data *d; + const struct wined3d_private_data *d; DWORD size_in; TRACE("resource %p, guid %s, data %p, data_size %p.\n", resource, debugstr_guid(guid), data, data_size); - d = resource_find_private_data(resource, guid); + d = wined3d_private_store_get_private_data(&resource->private_store, guid); if (!d) return WINED3DERR_NOTFOUND; @@ -258,35 +191,32 @@ HRESULT CDECL wined3d_resource_get_private_data(const struct wined3d_resource *r if (d->flags & WINED3DSPD_IUNKNOWN) { - *(IUnknown **)data = d->ptr.object; + *(IUnknown **)data = d->content.object; if (resource->device->wined3d->dxVersion != 7) { /* D3D8 and D3D9 addref the private data, DDraw does not. This * can't be handled in ddraw because it doesn't know if the * pointer returned is an IUnknown * or just a blob. */ - IUnknown_AddRef(d->ptr.object); + IUnknown_AddRef(d->content.object); } } else { - memcpy(data, d->ptr.data, d->size); + memcpy(data, d->content.data, d->size); } return WINED3D_OK; } + HRESULT CDECL wined3d_resource_free_private_data(struct wined3d_resource *resource, REFGUID guid) { - struct private_data *data; - + struct wined3d_private_data *entry; TRACE("resource %p, guid %s.\n", resource, debugstr_guid(guid)); - data = resource_find_private_data(resource, guid); - if (!data) return WINED3DERR_NOTFOUND; - - if (data->flags & WINED3DSPD_IUNKNOWN) - IUnknown_Release(data->ptr.object); - list_remove(&data->entry); - HeapFree(GetProcessHeap(), 0, data); + entry = wined3d_private_store_get_private_data(&resource->private_store, guid); + if (!entry) + return WINED3DERR_NOTFOUND; + wined3d_private_store_free_private_data(&resource->private_store, entry); return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 60088e816e0..ff31ebcbec1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2006,8 +2006,8 @@ struct wined3d_resource UINT size; DWORD priority; void *heap_memory; - struct list privateData; struct list resource_list_entry; + struct wined3d_private_store private_store; void *parent; const struct wined3d_parent_ops *parent_ops; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 3496c5d0c67..74ff3d1b926 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -26,6 +26,8 @@ #ifndef __WINE_WINED3D_H #define __WINE_WINED3D_H +#include "wine/list.h" + #define WINED3D_OK S_OK #define _FACWINED3D 0x876 @@ -1983,6 +1985,25 @@ struct wined3d_device_parent_ops struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain); }; +struct wined3d_private_store +{ + struct list content; +}; + +struct wined3d_private_data +{ + struct list entry; + + GUID tag; + DWORD flags; /* DDSPD_* */ + DWORD size; + union + { + BYTE data[1]; + IUnknown *object; + } content; +}; + typedef HRESULT (CDECL *wined3d_device_reset_cb)(struct wined3d_resource *resource); void __stdcall wined3d_mutex_lock(void); @@ -2245,6 +2266,79 @@ enum wined3d_query_type __cdecl wined3d_query_get_type(const struct wined3d_quer ULONG __cdecl wined3d_query_incref(struct wined3d_query *query); HRESULT __cdecl wined3d_query_issue(struct wined3d_query *query, DWORD flags); +static inline void wined3d_private_store_init(struct wined3d_private_store *store) +{ + list_init(&store->content); +} + +static inline struct wined3d_private_data *wined3d_private_store_get_private_data( + const struct wined3d_private_store *store, const GUID *tag) +{ + struct wined3d_private_data *data; + struct list *entry; + + LIST_FOR_EACH(entry, &store->content) + { + data = LIST_ENTRY(entry, struct wined3d_private_data, entry); + if (IsEqualGUID(&data->tag, tag)) + return data; + } + return NULL; +} + +static inline void wined3d_private_store_free_private_data(struct wined3d_private_store *store, + struct wined3d_private_data *entry) +{ + if (entry->flags & WINED3DSPD_IUNKNOWN) + IUnknown_Release(entry->content.object); + list_remove(&entry->entry); + HeapFree(GetProcessHeap(), 0, entry); +} + +static inline void wined3d_private_store_cleanup(struct wined3d_private_store *store) +{ + struct wined3d_private_data *data; + struct list *e1, *e2; + + LIST_FOR_EACH_SAFE(e1, e2, &store->content) + { + data = LIST_ENTRY(e1, struct wined3d_private_data, entry); + wined3d_private_store_free_private_data(store, data); + } +} + +static inline HRESULT wined3d_private_store_set_private_data(struct wined3d_private_store *store, + const GUID *guid, const void *data, DWORD data_size, DWORD flags) +{ + struct wined3d_private_data *d, *old; + const void *ptr = data; + + if (flags & WINED3DSPD_IUNKNOWN) + { + if (data_size != sizeof(IUnknown *)) + return WINED3DERR_INVALIDCALL; + ptr = &data; + } + + if (!(d = HeapAlloc(GetProcessHeap(), 0, + FIELD_OFFSET(struct wined3d_private_data, content.data[data_size])))) + return E_OUTOFMEMORY; + old = wined3d_private_store_get_private_data(store, guid); + if (old) + wined3d_private_store_free_private_data(store, old); + + d->tag = *guid; + d->flags = flags; + d->size = data_size; + + memcpy(d->content.data, ptr, data_size); + if (flags & WINED3DSPD_IUNKNOWN) + IUnknown_AddRef(d->content.object); + list_add_tail(&store->content, &d->entry); + + return WINED3D_OK; +} + HRESULT __cdecl wined3d_resource_free_private_data(struct wined3d_resource *resource, REFGUID guid); void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc);