Markus Amsler : d3d: Callback infrastructure for implicit volume destruction in IWineD3DVolumeTexture .

Alexandre Julliard julliard at wine.codeweavers.com
Wed Dec 6 05:49:08 CST 2006


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

Author: Markus Amsler <markus.amsler at oribi.org>
Date:   Tue Dec  5 00:29:21 2006 +0100

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 5f8bb74..59f8c83 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2500,6 +2500,16 @@ ULONG WINAPI D3DCB_DefaultDestroySurface
     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 13c0e1e..46e0c4d 100644
--- a/dlls/wined3d/volumetexture.c
+++ b/dlls/wined3d/volumetexture.c
@@ -55,29 +55,10 @@ static ULONG WINAPI IWineD3DVolumeTextur
 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 IWineD3DVolumeTexture
 /* *******************************************
    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 IWineD3D
     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 208ec0b..8eea594 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -419,6 +419,8 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *i
 /* 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 f546872..58ab88a 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -245,6 +245,8 @@ typedef HRESULT WINAPI (*D3DCB_ENUMDISPL
  */
 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
     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
 #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)




More information about the wine-cvs mailing list