Markus Amsler : d3d9: Handle volume refcount forwarding in d3d9.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Dec 18 05:34:38 CST 2006


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

Author: Markus Amsler <markus.amsler at oribi.org>
Date:   Mon Dec 18 00:16:56 2006 +0100

d3d9: Handle volume refcount forwarding in d3d9.

---

 dlls/d3d9/d3d9_private.h  |    6 +++++-
 dlls/d3d9/volume.c        |   31 +++++++++++++++++++------------
 dlls/d3d9/volumetexture.c |    2 +-
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 0555b3a..aa4a49f 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -235,7 +235,9 @@ typedef struct IDirect3DVolume9Impl
 
     /* IDirect3DVolume9 fields */
     IWineD3DVolume         *wineD3DVolume;
-    
+
+    /* If set forward refcounting to this object */
+    IUnknown                    *forwardReference;
 } IDirect3DVolume9Impl;
 
 /* ------------------- */
@@ -548,4 +550,6 @@ extern ULONG WINAPI D3D9CB_DestroyDepthS
 
 extern ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface);
 
+extern ULONG WINAPI D3D9CB_DestroyVolume(IWineD3DVolume *pVolume);
+
 #endif /* __WINE_D3D9_PRIVATE_H */
diff --git a/dlls/d3d9/volume.c b/dlls/d3d9/volume.c
index 1575763..f9ce7fc 100644
--- a/dlls/d3d9/volume.c
+++ b/dlls/d3d9/volume.c
@@ -42,15 +42,13 @@ static HRESULT WINAPI IDirect3DVolume9Im
 
 static ULONG WINAPI IDirect3DVolume9Impl_AddRef(LPDIRECT3DVOLUME9 iface) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
-    IUnknown *containerParent = NULL;
 
     TRACE("(%p)\n", This);
 
-    IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent);
-    if (containerParent) {
-        /* Forward to the containerParent */
-        TRACE("(%p) : Forwarding to %p\n", This, containerParent);
-        return IUnknown_AddRef(containerParent);
+    if (This->forwardReference) {
+        /* Forward refcounting */
+        TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
+        return IUnknown_AddRef(This->forwardReference);
     } else {
         /* No container, handle our own refcounting */
         ULONG ref = InterlockedIncrement(&This->ref);
@@ -61,15 +59,13 @@ static ULONG WINAPI IDirect3DVolume9Impl
 
 static ULONG WINAPI IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
-    IUnknown *containerParent = NULL;
 
     TRACE("(%p)\n", This);
 
-    IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent);
-    if (containerParent) {
-        /* Forward to the containerParent */
-        TRACE("(%p) : Forwarding to %p\n", This, containerParent);
-        return IUnknown_Release(containerParent);
+    if (This->forwardReference) {
+        /* Forward refcounting */
+        TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
+        return IUnknown_Release(This->forwardReference);
     } else {
         /* No container, handle our own refcounting */
         ULONG ref = InterlockedDecrement(&This->ref);
@@ -228,7 +224,18 @@ HRESULT WINAPI D3D9CB_CreateVolume(IUnkn
         *ppVolume = NULL;
     } else {
         *ppVolume = (IWineD3DVolume *)object->wineD3DVolume;
+        object->forwardReference = pSuperior;
     }
     TRACE("(%p) Created volume %p\n", This, *ppVolume);
     return hrc;
 }
+
+ULONG WINAPI D3D9CB_DestroyVolume(IWineD3DVolume *pVolume) {
+    IDirect3DVolume9Impl* volumeParent;
+
+    IWineD3DVolume_GetParent(pVolume, (IUnknown **) &volumeParent);
+    /* GetParent's AddRef was forwarded to an object in destruction.
+     * Releasing it here again would cause an endless recursion. */
+    volumeParent->forwardReference = NULL;
+    return IDirect3DVolume9_Release((IDirect3DVolume9*) volumeParent);
+}
diff --git a/dlls/d3d9/volumetexture.c b/dlls/d3d9/volumetexture.c
index 3397bb7..d45ca0e 100644
--- a/dlls/d3d9/volumetexture.c
+++ b/dlls/d3d9/volumetexture.c
@@ -58,7 +58,7 @@ static ULONG WINAPI IDirect3DVolumeTextu
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        IWineD3DVolumeTexture_Release(This->wineD3DVolumeTexture);
+        IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D9CB_DestroyVolume);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }




More information about the wine-cvs mailing list