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.
This commit is contained in:
parent
a5983e0c3d
commit
fadfdf21c0
|
@ -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;
|
||||
}
|
||||
|
||||
/* ****************************************************
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
Loading…
Reference in New Issue