Module: wine
Branch: master
Commit: 9ff40749f92d773f6aed74ba5e018daf8e3838f9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9ff40749f92d773f6aed74ba5…
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,