Module: wine Branch: master Commit: 9ff40749f92d773f6aed74ba5e018daf8e3838f9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9ff40749f92d773f6aed74ba5e... Author: Henri Verbeet <hverbeet(a)codeweavers.com> Date: Tue Mar 15 16:55:09 2016 +0100 ddraw: Do not destroy surfaces that are still attached. Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ddraw/surface.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index d133e7e..4259c10 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -531,7 +531,14 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface) ULONG ddraw_surface_release_iface(struct ddraw_surface *This) { - ULONG iface_count = InterlockedDecrement(&This->iface_count); + ULONG iface_count; + + /* Prevent the surface from being destroyed if it's still attached to + * another surface. It will be destroyed when the root is destroyed. */ + if (This->iface_count == 1 && This->attached_iface) + IUnknown_AddRef(This->attached_iface); + iface_count = InterlockedDecrement(&This->iface_count); + TRACE("%p decreasing iface count to %u.\n", This, iface_count); if (iface_count == 0) @@ -5623,20 +5630,10 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren TRACE("surface %p.\n", surface); - /* Check for attached surfaces and detach them. */ + /* This shouldn't happen, ddraw_surface_release_iface() should prevent the + * surface from being destroyed in this case. */ if (surface->first_attached != surface) - { - /* Well, this shouldn't happen: The surface being attached is - * referenced in AddAttachedSurface(), so it shouldn't be released - * until DeleteAttachedSurface() is called, because the refcount is - * held. It looks like the application released it often enough to - * force this. */ - WARN("Surface is still attached to surface %p.\n", surface->first_attached); - - /* The refcount will drop to -1 here */ - if (FAILED(ddraw_surface_delete_attached_surface(surface->first_attached, surface, surface->attached_iface))) - ERR("DeleteAttachedSurface failed.\n"); - } + ERR("Surface is still attached to surface %p.\n", surface->first_attached); while (surface->next_attached) if (FAILED(ddraw_surface_delete_attached_surface(surface,