H. Verbeet : wined3d: Fix the relation between volumes and their
container.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Mar 6 15:27:52 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 07004966a8585f55074d5fff903c51bf2a033070
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=07004966a8585f55074d5fff903c51bf2a033070
Author: H. Verbeet <hverbeet at gmail.com>
Date: Mon Mar 6 18:28:20 2006 +0000
wined3d: Fix the relation between volumes and their container.
---
dlls/d3d8/volume.c | 41 ++++++++++++++++++++++++++++++--------
dlls/d3d9/volume.c | 40 +++++++++++++++++++++++++++++--------
dlls/wined3d/volume.c | 24 ++++++++++++++++++++++
dlls/wined3d/volumetexture.c | 13 +++++++++++-
include/wine/wined3d_interface.h | 2 ++
5 files changed, 101 insertions(+), 19 deletions(-)
diff --git a/dlls/d3d8/volume.c b/dlls/d3d8/volume.c
index cffc50b..20421a8 100644
--- a/dlls/d3d8/volume.c
+++ b/dlls/d3d8/volume.c
@@ -40,24 +40,47 @@ HRESULT WINAPI IDirect3DVolume8Impl_Quer
ULONG WINAPI IDirect3DVolume8Impl_AddRef(LPDIRECT3DVOLUME8 iface) {
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
- ULONG ref = InterlockedIncrement(&This->ref);
+ IUnknown *containerParent = NULL;
- TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
+ TRACE("(%p)\n", This);
- return ref;
+ IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent);
+ if (containerParent) {
+ /* Forward to the containerParent */
+ TRACE("(%p) : Forwarding to %p\n", This, containerParent);
+ return IUnknown_AddRef(containerParent);
+ } else {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedIncrement(&This->ref);
+ TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
+ return ref;
+ }
}
ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
+ IUnknown *containerParent = NULL;
- TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
+ 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);
+ }
+ else {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedDecrement(&This->ref);
+ TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
+
+ if (ref == 0) {
+ IWineD3DVolume_Release(This->wineD3DVolume);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
- if (ref == 0) {
- IWineD3DVolume_Release(This->wineD3DVolume);
- HeapFree(GetProcessHeap(), 0, This);
+ return ref;
}
- return ref;
}
/* IDirect3DVolume8 Interface follow: */
diff --git a/dlls/d3d9/volume.c b/dlls/d3d9/volume.c
index 4e53b2a..1223932 100644
--- a/dlls/d3d9/volume.c
+++ b/dlls/d3d9/volume.c
@@ -41,24 +41,46 @@ HRESULT WINAPI IDirect3DVolume9Impl_Quer
ULONG WINAPI IDirect3DVolume9Impl_AddRef(LPDIRECT3DVOLUME9 iface) {
IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
- ULONG ref = InterlockedIncrement(&This->ref);
+ IUnknown *containerParent = NULL;
- TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
+ TRACE("(%p)\n", This);
- return ref;
+ IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent);
+ if (containerParent) {
+ /* Forward to the containerParent */
+ TRACE("(%p) : Forwarding to %p\n", This, containerParent);
+ return IUnknown_AddRef(containerParent);
+ } else {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedIncrement(&This->ref);
+ TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
+ return ref;
+ }
}
ULONG WINAPI IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) {
IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
+ IUnknown *containerParent = NULL;
- TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
+ 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);
+ } else {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedDecrement(&This->ref);
+ TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
+
+ if (ref == 0) {
+ IWineD3DVolume_Release(This->wineD3DVolume);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
- if (ref == 0) {
- IWineD3DVolume_Release(This->wineD3DVolume);
- HeapFree(GetProcessHeap(), 0, This);
+ return ref;
}
- return ref;
}
/* IDirect3DVolume9 Interface follow: */
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 3fa1717..151ade3 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -103,6 +103,29 @@ D3DRESOURCETYPE WINAPI IWineD3DVolumeImp
/* *******************************************
IWineD3DVolume parts follow
******************************************* */
+HRESULT WINAPI IWineD3DVolumeImpl_GetContainerParent(IWineD3DVolume *iface, IUnknown **ppContainerParent) {
+ IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
+
+ TRACE("(%p) : ppContainerParent %p\n", This, ppContainerParent);
+
+ if (!ppContainerParent) {
+ ERR("(%p) : Called without a valid ppContainerParent\n", This);
+ }
+
+ if (This->container) {
+ IWineD3DBase_GetParent(This->container, ppContainerParent);
+ if (!ppContainerParent) {
+ /* WineD3D objects should always have a parent */
+ ERR("(%p) : GetParent returned NULL\n", This);
+ }
+ IUnknown_Release(*ppContainerParent); /* GetParent adds a reference; we want just the pointer */
+ } else {
+ *ppContainerParent = NULL;
+ }
+
+ return D3D_OK;
+}
+
HRESULT WINAPI IWineD3DVolumeImpl_GetContainer(IWineD3DVolume *iface, REFIID riid, void** ppContainer) {
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
@@ -304,6 +327,7 @@ const IWineD3DVolumeVtbl IWineD3DVolume_
IWineD3DVolumeImpl_PreLoad,
IWineD3DVolumeImpl_GetType,
/* IWineD3DVolume */
+ IWineD3DVolumeImpl_GetContainerParent,
IWineD3DVolumeImpl_GetContainer,
IWineD3DVolumeImpl_GetDesc,
IWineD3DVolumeImpl_LockBox,
diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c
index 14e1154..9464357 100644
--- a/dlls/wined3d/volumetexture.c
+++ b/dlls/wined3d/volumetexture.c
@@ -60,8 +60,19 @@ ULONG WINAPI IWineD3DVolumeTextureImpl_R
if (ref == 0) {
for (i = 0; i < This->baseTexture.levels; i++) {
if (This->volumes[i] != NULL) {
+ /* Since the volumes were created by callback, the texture is
+ * keeping the reference to the parent, so the texture should
+ * release it. */
+ IUnknown *volumeParent = NULL;
+
TRACE("(%p) : Releasing volume %p\n", This, This->volumes[i]);
- IWineD3DVolume_Release(This->volumes[i]);
+
+ /* Cleanup the container */
+ IWineD3DVolume_SetContainer(This->volumes[i], 0);
+ /* Now, release the parent, which will take care of cleaning up the volume for us */
+ IWineD3DVolume_GetParent(This->volumes[i], &volumeParent);
+ IUnknown_Release(volumeParent); /* Once for the reference GetParent added */
+ IUnknown_Release(volumeParent); /* Once for the reference we're keeping */
}
}
IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *) iface);
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index 4184fee..c37ac00 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -1125,6 +1125,7 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD
STDMETHOD_(void,PreLoad)(THIS) PURE;
STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
/*** IWineD3DVolume methods ***/
+ STDMETHOD(GetContainerParent)(THIS_ IUnknown **ppContainerParent) PURE;
STDMETHOD(GetContainer)(THIS_ REFIID riid, void ** ppContainer) PURE;
STDMETHOD(GetDesc)(THIS_ WINED3DVOLUME_DESC * pDesc) PURE;
STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) PURE;
@@ -1153,6 +1154,7 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD
#define IWineD3DVolume_PreLoad(p) (p)->lpVtbl->PreLoad(p)
#define IWineD3DVolume_GetType(p) (p)->lpVtbl->GetType(p)
/*** IWineD3DVolume methods ***/
+#define IWineD3DVolume_GetContainerParent(p,a) (p)->lpVtbl->GetContainerParent(p,a)
#define IWineD3DVolume_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b)
#define IWineD3DVolume_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
#define IWineD3DVolume_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c)
More information about the wine-cvs
mailing list