Commit 599f018c authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

d3d8: The "forwardReference" field in struct d3d8_surface is always a texture, if set.

parent c5e8115e
...@@ -228,16 +228,12 @@ struct d3d8_surface ...@@ -228,16 +228,12 @@ struct d3d8_surface
struct d3d8_resource resource; struct d3d8_resource resource;
struct wined3d_surface *wined3d_surface; struct wined3d_surface *wined3d_surface;
IDirect3DDevice8 *parent_device; IDirect3DDevice8 *parent_device;
IUnknown *container;
/* The surface container */ struct d3d8_texture *texture;
IUnknown *container;
/* If set forward refcounting to this object */
IUnknown *forwardReference;
}; };
void surface_init(struct d3d8_surface *surface, struct wined3d_surface *wined3d_surface, void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
struct d3d8_device *device, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN; struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN;
struct d3d8_vertexbuffer struct d3d8_vertexbuffer
......
...@@ -918,7 +918,6 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width ...@@ -918,7 +918,6 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width
sub_resource = wined3d_texture_get_sub_resource(texture, 0); sub_resource = wined3d_texture_get_sub_resource(texture, 0);
surface_impl = wined3d_resource_get_parent(sub_resource); surface_impl = wined3d_resource_get_parent(sub_resource);
surface_impl->forwardReference = NULL;
surface_impl->parent_device = &device->IDirect3DDevice8_iface; surface_impl->parent_device = &device->IDirect3DDevice8_iface;
*surface = &surface_impl->IDirect3DSurface8_iface; *surface = &surface_impl->IDirect3DSurface8_iface;
IDirect3DSurface8_AddRef(*surface); IDirect3DSurface8_AddRef(*surface);
...@@ -2940,7 +2939,6 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent ...@@ -2940,7 +2939,6 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
void *container_parent, struct wined3d_surface *surface, void **parent, void *container_parent, struct wined3d_surface *surface, void **parent,
const struct wined3d_parent_ops **parent_ops) const struct wined3d_parent_ops **parent_ops)
{ {
struct d3d8_device *device = device_from_device_parent(device_parent);
struct d3d8_surface *d3d_surface; struct d3d8_surface *d3d_surface;
TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n", TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
...@@ -2949,17 +2947,10 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent ...@@ -2949,17 +2947,10 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface)))) if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
surface_init(d3d_surface, surface, device, parent_ops); surface_init(d3d_surface, container_parent, surface, parent_ops);
*parent = d3d_surface; *parent = d3d_surface;
TRACE("Created surface %p.\n", d3d_surface); TRACE("Created surface %p.\n", d3d_surface);
d3d_surface->container = container_parent;
IDirect3DDevice8_Release(d3d_surface->parent_device);
d3d_surface->parent_device = NULL;
IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface);
d3d_surface->forwardReference = container_parent;
return D3D_OK; return D3D_OK;
} }
...@@ -3008,7 +2999,6 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic ...@@ -3008,7 +2999,6 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
wined3d_texture_decref(texture); wined3d_texture_decref(texture);
d3d_surface = wined3d_surface_get_parent(*surface); d3d_surface = wined3d_surface_get_parent(*surface);
d3d_surface->forwardReference = NULL;
d3d_surface->parent_device = &device->IDirect3DDevice8_iface; d3d_surface->parent_device = &device->IDirect3DDevice8_iface;
return hr; return hr;
......
...@@ -50,69 +50,60 @@ static HRESULT WINAPI d3d8_surface_QueryInterface(IDirect3DSurface8 *iface, REFI ...@@ -50,69 +50,60 @@ static HRESULT WINAPI d3d8_surface_QueryInterface(IDirect3DSurface8 *iface, REFI
static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface) static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
{ {
struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface); struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
ULONG refcount;
TRACE("iface %p.\n", iface); TRACE("iface %p.\n", iface);
if (surface->forwardReference) if (surface->texture)
{ {
/* Forward refcounting */ TRACE("Forwarding to %p.\n", surface->texture);
TRACE("Forwarding to %p.\n", surface->forwardReference); return IDirect3DBaseTexture8_AddRef(&surface->texture->IDirect3DBaseTexture8_iface);
return IUnknown_AddRef(surface->forwardReference);
} }
else
{
/* No container, handle our own refcounting */
ULONG ref = InterlockedIncrement(&surface->resource.refcount);
TRACE("%p increasing refcount to %u.\n", iface, ref); refcount = InterlockedIncrement(&surface->resource.refcount);
TRACE("%p increasing refcount to %u.\n", iface, refcount);
if (ref == 1) if (refcount == 1)
{ {
if (surface->parent_device) if (surface->parent_device)
IDirect3DDevice8_AddRef(surface->parent_device); IDirect3DDevice8_AddRef(surface->parent_device);
wined3d_mutex_lock(); wined3d_mutex_lock();
wined3d_surface_incref(surface->wined3d_surface); wined3d_surface_incref(surface->wined3d_surface);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
}
return ref;
} }
return refcount;
} }
static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface) static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
{ {
struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface); struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
ULONG refcount;
TRACE("iface %p.\n", iface); TRACE("iface %p.\n", iface);
if (surface->forwardReference) if (surface->texture)
{ {
/* Forward refcounting */ TRACE("Forwarding to %p.\n", surface->texture);
TRACE("Forwarding to %p.\n", surface->forwardReference); return IDirect3DBaseTexture8_Release(&surface->texture->IDirect3DBaseTexture8_iface);
return IUnknown_Release(surface->forwardReference);
} }
else
{
/* No container, handle our own refcounting */
ULONG ref = InterlockedDecrement(&surface->resource.refcount);
TRACE("%p decreasing refcount to %u.\n", iface, ref); refcount = InterlockedDecrement(&surface->resource.refcount);
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!ref) if (!refcount)
{ {
IDirect3DDevice8 *parent_device = surface->parent_device; IDirect3DDevice8 *parent_device = surface->parent_device;
/* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */ wined3d_mutex_lock();
wined3d_mutex_lock(); wined3d_surface_decref(surface->wined3d_surface);
wined3d_surface_decref(surface->wined3d_surface); wined3d_mutex_unlock();
wined3d_mutex_unlock();
if (parent_device) if (parent_device)
IDirect3DDevice8_Release(parent_device); IDirect3DDevice8_Release(parent_device);
}
return ref;
} }
return refcount;
} }
static HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3DDevice8 **device) static HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3DDevice8 **device)
...@@ -121,22 +112,8 @@ static HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3D ...@@ -121,22 +112,8 @@ static HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3D
TRACE("iface %p, device %p.\n", iface, device); TRACE("iface %p, device %p.\n", iface, device);
if (surface->forwardReference) if (surface->texture)
{ return IDirect3DBaseTexture8_GetDevice(&surface->texture->IDirect3DBaseTexture8_iface, device);
IDirect3DResource8 *resource;
HRESULT hr;
hr = IUnknown_QueryInterface(surface->forwardReference, &IID_IDirect3DResource8, (void **)&resource);
if (SUCCEEDED(hr))
{
hr = IDirect3DResource8_GetDevice(resource, device);
IDirect3DResource8_Release(resource);
TRACE("Returning device %p.\n", *device);
}
return hr;
}
*device = surface->parent_device; *device = surface->parent_device;
IDirect3DDevice8_AddRef(*device); IDirect3DDevice8_AddRef(*device);
...@@ -311,15 +288,23 @@ static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops = ...@@ -311,15 +288,23 @@ static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
surface_wined3d_object_destroyed, surface_wined3d_object_destroyed,
}; };
void surface_init(struct d3d8_surface *surface, struct wined3d_surface *wined3d_surface, void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
struct d3d8_device *device, const struct wined3d_parent_ops **parent_ops) struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
{ {
IDirect3DBaseTexture8 *texture;
surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl; surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl;
d3d8_resource_init(&surface->resource); d3d8_resource_init(&surface->resource);
wined3d_surface_incref(wined3d_surface); surface->resource.refcount = 0;
surface->wined3d_surface = wined3d_surface; surface->wined3d_surface = wined3d_surface;
surface->parent_device = &device->IDirect3DDevice8_iface; surface->container = container_parent;
IDirect3DDevice8_AddRef(surface->parent_device);
if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
&IID_IDirect3DBaseTexture8, (void **)&texture)))
{
surface->texture = unsafe_impl_from_IDirect3DBaseTexture8(texture);
IDirect3DBaseTexture8_Release(texture);
}
*parent_ops = &d3d8_surface_wined3d_parent_ops; *parent_ops = &d3d8_surface_wined3d_parent_ops;
} }
......
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