Markus Amsler : d3d8: Handle volume refcount forwarding in d3d8.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Dec 6 05:49:10 CST 2006
Module: wine
Branch: master
Commit: 0a3f417359e17ddd6fe1b0823dba47c2c52a0698
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0a3f417359e17ddd6fe1b0823dba47c2c52a0698
Author: Markus Amsler <markus.amsler at oribi.org>
Date: Tue Dec 5 00:29:42 2006 +0100
d3d8: Handle volume refcount forwarding in d3d8.
---
dlls/d3d8/d3d8_private.h | 5 +++++
dlls/d3d8/volume.c | 27 +++++++++++++++++----------
dlls/d3d8/volumetexture.c | 2 +-
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index de553c6..a6ae848 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -196,6 +196,9 @@ struct IDirect3DVolume8Impl
/* IDirect3DVolume8 fields */
IWineD3DVolume *wineD3DVolume;
+
+ /* If set forward refcounting to this object */
+ IUnknown *forwardReference;
};
/* ------------------- */
@@ -598,4 +601,6 @@ extern ULONG WINAPI D3D8CB_DestroyDepthS
extern ULONG WINAPI D3D8CB_DestroySurface(IWineD3DSurface *pSurface);
+extern ULONG WINAPI D3D8CB_DestroyVolume(IWineD3DVolume *pVolume);
+
#endif /* __WINE_D3DX8_PRIVATE_H */
diff --git a/dlls/d3d8/volume.c b/dlls/d3d8/volume.c
index 53dba41..0eba97a 100644
--- a/dlls/d3d8/volume.c
+++ b/dlls/d3d8/volume.c
@@ -41,15 +41,13 @@ static HRESULT WINAPI IDirect3DVolume8Im
static ULONG WINAPI IDirect3DVolume8Impl_AddRef(LPDIRECT3DVOLUME8 iface) {
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
- IUnknown *containerParent = NULL;
TRACE("(%p)\n", This);
- IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent);
- if (containerParent) {
+ if (This->forwardReference) {
/* Forward to the containerParent */
- TRACE("(%p) : Forwarding to %p\n", This, containerParent);
- return IUnknown_AddRef(containerParent);
+ 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);
@@ -60,15 +58,13 @@ static ULONG WINAPI IDirect3DVolume8Impl
static ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
- IUnknown *containerParent = NULL;
TRACE("(%p)\n", This);
- IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent);
- if (containerParent) {
+ if (This->forwardReference) {
/* Forward to the containerParent */
- TRACE("(%p) : Forwarding to %p\n", This, containerParent);
- return IUnknown_Release(containerParent);
+ TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
+ return IUnknown_Release(This->forwardReference);
}
else {
/* No container, handle our own refcounting */
@@ -227,7 +223,18 @@ HRESULT WINAPI D3D8CB_CreateVolume(IUnkn
*ppVolume = NULL;
} else {
*ppVolume = (IWineD3DVolume *)object->wineD3DVolume;
+ object->forwardReference = pSuperior;
}
TRACE("(%p) Created volume %p\n", This, *ppVolume);
return hrc;
}
+
+ULONG WINAPI D3D8CB_DestroyVolume(IWineD3DVolume *pVolume) {
+ IDirect3DVolume8Impl* 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 IDirect3DVolume8_Release((IDirect3DVolume8*) volumeParent);
+}
diff --git a/dlls/d3d8/volumetexture.c b/dlls/d3d8/volumetexture.c
index cf0202c..430f0b4 100644
--- a/dlls/d3d8/volumetexture.c
+++ b/dlls/d3d8/volumetexture.c
@@ -57,7 +57,7 @@ static ULONG WINAPI IDirect3DVolumeTextu
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
- IWineD3DVolumeTexture_Release(This->wineD3DVolumeTexture);
+ IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D8CB_DestroyVolume);
IUnknown_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}
More information about the wine-cvs
mailing list