Henri Verbeet : wined3d: Forward surface refcounts to the container.

Alexandre Julliard julliard at winehq.org
Mon Apr 18 11:10:51 CDT 2011


Module: wine
Branch: master
Commit: fadfdf21c055caf833a137ffc269c2073dc87fd6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fadfdf21c055caf833a137ffc269c2073dc87fd6

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Fri Apr 15 18:33:37 2011 +0200

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.

---

 dlls/wined3d/surface.c      |   37 ++++++++++++++++++++++++++++---------
 dlls/wined3d/surface_base.c |   31 ++++++++++++++++++++++++++-----
 dlls/wined3d/surface_gdi.c  |   39 ++++++++++++++++++++++++++++++---------
 3 files changed, 84 insertions(+), 23 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 4a72183..c7a3571 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -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;
+
+    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);
-        This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent);
+        surface_cleanup(surface);
+        surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent);
 
-        TRACE("(%p) Released.\n", This);
-        HeapFree(GetProcessHeap(), 0, This);
+        TRACE("Destroyed surface %p.\n", surface);
+        HeapFree(GetProcessHeap(), 0, surface);
     }
 
-    return ref;
+    return refcount;
 }
 
 /* ****************************************************
diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c
index 906c7ef..0705719 100644
--- a/dlls/wined3d/surface_base.c
+++ b/dlls/wined3d/surface_base.c
@@ -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,
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index db9cf8b..0cb675b 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -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;
+
+    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);
-        HeapFree(GetProcessHeap(), 0, This);
+        TRACE("Destroyed surface %p.\n", surface);
+        HeapFree(GetProcessHeap(), 0, surface);
     }
 
-    return ref;
+    return refcount;
 }
 
 /*****************************************************************************




More information about the wine-cvs mailing list