Commit fadfdf21 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Forward surface refcounts to the container.

This will prevent textures from being released if one of its surfaces is still in use by the stateblock. We have similar constructions in d3d8 and d3d9, but those won't prevent the wined3d texture from being released.
parent a5983e0c
...@@ -1376,20 +1376,39 @@ HRESULT surface_load(IWineD3DSurfaceImpl *surface, BOOL srgb) ...@@ -1376,20 +1376,39 @@ HRESULT surface_load(IWineD3DSurfaceImpl *surface, BOOL srgb)
/* Do not call while under the GL lock. */ /* Do not call while under the GL lock. */
static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
{ {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
ULONG ref = InterlockedDecrement(&This->resource.ref); ULONG refcount;
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
TRACE("Surface %p, container %p of type %#x.\n",
surface, surface->container.u.base, surface->container.type);
switch (surface->container.type)
{
case WINED3D_CONTAINER_TEXTURE:
return wined3d_texture_decref(surface->container.u.texture);
case WINED3D_CONTAINER_SWAPCHAIN:
return wined3d_swapchain_decref(surface->container.u.swapchain);
default:
ERR("Unhandled container type %#x.\n", surface->container.type);
case WINED3D_CONTAINER_NONE:
break;
}
refcount = InterlockedDecrement(&surface->resource.ref);
TRACE("%p decreasing refcount to %u.\n", surface, refcount);
if (!ref) if (!refcount)
{ {
surface_cleanup(This); surface_cleanup(surface);
This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent); surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent);
TRACE("(%p) Released.\n", This); TRACE("Destroyed surface %p.\n", surface);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, surface);
} }
return ref; return refcount;
} }
/* **************************************************** /* ****************************************************
......
...@@ -102,11 +102,32 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, RE ...@@ -102,11 +102,32 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, RE
return E_NOINTERFACE; return E_NOINTERFACE;
} }
ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface) { ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface)
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; {
ULONG ref = InterlockedIncrement(&This->resource.ref); IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
TRACE("(%p) : AddRef increasing from %d\n", This,ref - 1); ULONG refcount;
return ref;
TRACE("Surface %p, container %p of type %#x.\n",
surface, surface->container.u.base, surface->container.type);
switch (surface->container.type)
{
case WINED3D_CONTAINER_TEXTURE:
return wined3d_texture_incref(surface->container.u.texture);
case WINED3D_CONTAINER_SWAPCHAIN:
return wined3d_swapchain_incref(surface->container.u.swapchain);
default:
ERR("Unhandled container type %#x.\n", surface->container.type);
case WINED3D_CONTAINER_NONE:
break;
}
refcount = InterlockedIncrement(&surface->resource.ref);
TRACE("%p increasing refcount to %u.\n", surface, refcount);
return refcount;
} }
HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface,
......
...@@ -114,20 +114,41 @@ static const struct wined3d_surface_ops gdi_surface_ops = ...@@ -114,20 +114,41 @@ static const struct wined3d_surface_ops gdi_surface_ops =
* to destroy all the GL things. * to destroy all the GL things.
* *
*****************************************************************************/ *****************************************************************************/
static ULONG WINAPI IWineGDISurfaceImpl_Release(IWineD3DSurface *iface) { static ULONG WINAPI IWineGDISurfaceImpl_Release(IWineD3DSurface *iface)
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; {
ULONG ref = InterlockedDecrement(&This->resource.ref); IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
TRACE("(%p) : Releasing from %d\n", This, ref + 1); ULONG refcount;
TRACE("Surface %p, container %p of type %#x.\n",
surface, surface->container.u.base, surface->container.type);
switch (surface->container.type)
{
case WINED3D_CONTAINER_TEXTURE:
return wined3d_texture_decref(surface->container.u.texture);
case WINED3D_CONTAINER_SWAPCHAIN:
return wined3d_swapchain_decref(surface->container.u.swapchain);
default:
ERR("Unhandled container type %#x.\n", surface->container.type);
case WINED3D_CONTAINER_NONE:
break;
}
refcount = InterlockedDecrement(&surface->resource.ref);
TRACE("%p decreasing refcount to %u.\n", surface, refcount);
if (!ref) if (!refcount)
{ {
surface_gdi_cleanup(This); surface_gdi_cleanup(surface);
surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent);
TRACE("(%p) Released.\n", This); TRACE("Destroyed surface %p.\n", surface);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, surface);
} }
return ref; return refcount;
} }
/***************************************************************************** /*****************************************************************************
......
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