Commit 6a34d4b4 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Decouple private data from the resource structure.

parent 05b3d7b6
......@@ -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;
}
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment