From 50a0c21265e3cd41026025073e2ea5074258788c Mon Sep 17 00:00:00 2001 From: Markus Amsler Date: Tue, 5 Dec 2006 00:29:21 +0100 Subject: [PATCH] d3d: Callback infrastructure for implicit volume destruction in IWineD3DVolumeTexture. --- dlls/wined3d/directx.c | 10 +++++++++ dlls/wined3d/volumetexture.c | 37 +++++++++++++++----------------- dlls/wined3d/wined3d_private.h | 2 ++ include/wine/wined3d_interface.h | 4 ++++ 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 5f8bb7455e9..59f8c83f291 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2500,6 +2500,16 @@ ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) { return IUnknown_Release(surfaceParent); } +ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) { + IUnknown* volumeParent; + TRACE("(%p) call back\n", pVolume); + + /* Now, release the parent, which will take care of cleaning up the volume for us */ + IWineD3DVolume_GetParent(pVolume, &volumeParent); + IUnknown_Release(volumeParent); + return IUnknown_Release(volumeParent); +} + /********************************************************** * IWineD3D VTbl follows **********************************************************/ diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c index 13c0e1e2fc4..46e0c4d7cbc 100644 --- a/dlls/wined3d/volumetexture.c +++ b/dlls/wined3d/volumetexture.c @@ -55,29 +55,10 @@ static ULONG WINAPI IWineD3DVolumeTextureImpl_AddRef(IWineD3DVolumeTexture *ifac static ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *iface) { IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; ULONG ref; - int i; TRACE("(%p) : Releasing from %d\n", This, This->resource.ref); ref = InterlockedDecrement(&This->resource.ref); 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]); - - /* 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); - HeapFree(GetProcessHeap(), 0, This); + IWineD3DVolumeTexture_Destroy(iface, D3DCB_DefaultDestroyVolume); } return ref; } @@ -207,6 +188,21 @@ static void WINAPI IWineD3DVolumeTextureImpl_ApplyStateChanges(IWineD3DVolumeTex /* ******************************************* IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow ******************************************* */ +static void WINAPI IWineD3DVolumeTextureImpl_Destroy(IWineD3DVolumeTexture *iface, D3DCB_DESTROYVOLUMEFN D3DCB_DestroyVolume) { + IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; + int i; + TRACE("(%p) : Cleaning up\n",This); + for (i = 0; i < This->baseTexture.levels; i++) { + if (This->volumes[i] != NULL) { + /* Cleanup the container */ + IWineD3DVolume_SetContainer(This->volumes[i], 0); + D3DCB_DestroyVolume(This->volumes[i]); + } + } + IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *) iface); + HeapFree(GetProcessHeap(), 0, This); +} + static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, UINT Level,WINED3DVOLUME_DESC *pDesc) { IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; if (Level < This->baseTexture.levels) { @@ -298,6 +294,7 @@ const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl = IWineD3DVolumeTextureImpl_GetTextureDimensions, IWineD3DVolumeTextureImpl_ApplyStateChanges, /* volume texture */ + IWineD3DVolumeTextureImpl_Destroy, IWineD3DVolumeTextureImpl_GetLevelDesc, IWineD3DVolumeTextureImpl_GetVolumeLevel, IWineD3DVolumeTextureImpl_LockBox, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 208ec0b463e..8eea594d7be 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -419,6 +419,8 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display); /* Default callbacks for implicit object destruction */ extern ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface); +extern ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pSurface); + /***************************************************************************** * Internal representation of a light */ diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index f546872255e..58ab88a9e04 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -245,6 +245,8 @@ typedef HRESULT WINAPI (*D3DCB_ENUMDISPLAYMODESCALLBACK) (IUnknown *pDevice, */ typedef ULONG WINAPI (*D3DCB_DESTROYSURFACEFN) (struct IWineD3DSurface *pSurface); +typedef ULONG WINAPI (*D3DCB_DESTROYVOLUMEFN) (struct IWineD3DVolume *pVolume); + /***************************************************************************** * IWineD3DBase interface */ @@ -1025,6 +1027,7 @@ DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture) STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE; STDMETHOD_(void, ApplyStateChanges)(THIS_ const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE; /*** IWineD3DVolumeTexture methods ***/ + STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYVOLUMEFN pFn) PURE; STDMETHOD(GetLevelDesc)(THIS_ UINT Level, WINED3DVOLUME_DESC *pDesc) PURE; STDMETHOD(GetVolumeLevel)(THIS_ UINT Level, struct IWineD3DVolume** ppVolumeLevel) PURE; STDMETHOD(LockBox)(THIS_ UINT Level, WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) PURE; @@ -1063,6 +1066,7 @@ DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture) #define IWineD3DVolumeTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p) #define IWineD3DVolumeTexture_ApplyStateChanges(p,a,b) (p)->lpVtbl->ApplyStateChanges(p,a,b) /*** IWineD3DVolumeTexture methods ***/ +#define IWineD3DVolumeTexture_Destroy(p,a) (p)->lpVtbl->Destroy(p,a) #define IWineD3DVolumeTexture_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) #define IWineD3DVolumeTexture_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b) #define IWineD3DVolumeTexture_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d)