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.
oldstable
Henri Verbeet 2011-04-15 18:33:37 +02:00 committed by Alexandre Julliard
parent a5983e0c3d
commit fadfdf21c0
3 changed files with 84 additions and 23 deletions

View File

@ -1376,20 +1376,39 @@ HRESULT surface_load(IWineD3DSurfaceImpl *surface, BOOL srgb)
/* Do not call while under the GL lock. */
static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
{
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
ULONG ref = InterlockedDecrement(&This->resource.ref);
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
ULONG refcount;
if (!ref)
TRACE("Surface %p, container %p of type %#x.\n",
surface, surface->container.u.base, surface->container.type);
switch (surface->container.type)
{
surface_cleanup(This);
This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent);
case WINED3D_CONTAINER_TEXTURE:
return wined3d_texture_decref(surface->container.u.texture);
TRACE("(%p) Released.\n", This);
HeapFree(GetProcessHeap(), 0, This);
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;
}
return ref;
refcount = InterlockedDecrement(&surface->resource.ref);
TRACE("%p decreasing refcount to %u.\n", surface, refcount);
if (!refcount)
{
surface_cleanup(surface);
surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent);
TRACE("Destroyed surface %p.\n", surface);
HeapFree(GetProcessHeap(), 0, surface);
}
return refcount;
}
/* ****************************************************

View File

@ -102,11 +102,32 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, RE
return E_NOINTERFACE;
}
ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
ULONG ref = InterlockedIncrement(&This->resource.ref);
TRACE("(%p) : AddRef increasing from %d\n", This,ref - 1);
return ref;
ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface)
{
IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
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_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,

View File

@ -114,20 +114,41 @@ static const struct wined3d_surface_ops gdi_surface_ops =
* to destroy all the GL things.
*
*****************************************************************************/
static ULONG WINAPI IWineGDISurfaceImpl_Release(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
ULONG ref = InterlockedDecrement(&This->resource.ref);
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
static ULONG WINAPI IWineGDISurfaceImpl_Release(IWineD3DSurface *iface)
{
IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
ULONG refcount;
if (!ref)
TRACE("Surface %p, container %p of type %#x.\n",
surface, surface->container.u.base, surface->container.type);
switch (surface->container.type)
{
surface_gdi_cleanup(This);
case WINED3D_CONTAINER_TEXTURE:
return wined3d_texture_decref(surface->container.u.texture);
TRACE("(%p) Released.\n", This);
HeapFree(GetProcessHeap(), 0, This);
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;
}
return ref;
refcount = InterlockedDecrement(&surface->resource.ref);
TRACE("%p decreasing refcount to %u.\n", surface, refcount);
if (!refcount)
{
surface_gdi_cleanup(surface);
surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent);
TRACE("Destroyed surface %p.\n", surface);
HeapFree(GetProcessHeap(), 0, surface);
}
return refcount;
}
/*****************************************************************************