Markus Amsler : d3d: Callback infrastructure for implicit surface destruction in IWineD3DTexture .

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


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

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

d3d: Callback infrastructure for implicit surface destruction in IWineD3DTexture.

---

 dlls/wined3d/directx.c           |   10 ++++++++
 dlls/wined3d/texture.c           |   43 +++++++++++++++++++------------------
 dlls/wined3d/wined3d_private.h   |    3 ++
 include/wine/wined3d_interface.h |    7 ++++++
 4 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index dd50ecf..5f8bb74 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2490,6 +2490,16 @@ static HRESULT WINAPI IWineD3DImpl_GetPa
     return WINED3D_OK;
 }
 
+ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
+    IUnknown* surfaceParent;
+    TRACE("(%p) call back\n", pSurface);
+
+    /* Now, release the parent, which will take care of cleaning up the surface for us */
+    IWineD3DSurface_GetParent(pSurface, &surfaceParent);
+    IUnknown_Release(surfaceParent);
+    return IUnknown_Release(surfaceParent);
+}
+
 /**********************************************************
  * IWineD3D VTbl follows
  **********************************************************/
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index a1ce721..e9a78cc 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -58,31 +58,12 @@ static ULONG WINAPI IWineD3DTextureImpl_
     TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
     ref = InterlockedDecrement(&This->resource.ref);
     if (ref == 0) {
-        int i;
-
-        TRACE("(%p) : Cleaning up\n",This);
-        for (i = 0; i < This->baseTexture.levels; i++) {
-            if (This->surfaces[i] != NULL) {
-                /* Because the surfaces were created using a callback we need to release there parent otehrwise we leave the parent hanging */
-                IUnknown* surfaceParent;
-                /* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
-                IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], 0, 0);
-                /* Cleanup the container */
-                IWineD3DSurface_SetContainer(This->surfaces[i], 0);
-                /* Now, release the parent, which will take care of cleaning up the surface for us */
-                IWineD3DSurface_GetParent(This->surfaces[i], &surfaceParent);
-                IUnknown_Release(surfaceParent);
-                IUnknown_Release(surfaceParent);
-            }
-        }
-        TRACE("(%p) : cleaning up base texture\n", This);
-        IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *)iface);
-        /* free the object */
-        HeapFree(GetProcessHeap(), 0, This);
+        IWineD3DTexture_Destroy(iface, D3DCB_DefaultDestroySurface);
     }
     return ref;
 }
 
+
 /* ****************************************************
    IWineD3DTexture IWineD3DResource parts follow
    **************************************************** */
@@ -246,6 +227,25 @@ static void WINAPI IWineD3DTextureImpl_A
 /* *******************************************
    IWineD3DTexture IWineD3DTexture parts follow
    ******************************************* */
+static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
+    IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
+    int i;
+
+    TRACE("(%p) : Cleaning up\n",This);
+    for (i = 0; i < This->baseTexture.levels; i++) {
+        if (This->surfaces[i] != NULL) {
+            /* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
+            IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], 0, 0);
+            IWineD3DSurface_SetContainer(This->surfaces[i], 0);
+            D3DCB_DestroySurface(This->surfaces[i]);
+        }
+    }
+    TRACE("(%p) : cleaning up base texture\n", This);
+    IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *)iface);
+    /* free the object */
+    HeapFree(GetProcessHeap(), 0, This);
+}
+
 static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) {
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
 
@@ -343,6 +343,7 @@ const IWineD3DTextureVtbl IWineD3DTextur
     IWineD3DTextureImpl_GetTextureDimensions,
     IWineD3DTextureImpl_ApplyStateChanges,
     /* IWineD3DTexture */
+    IWineD3DTextureImpl_Destroy,
     IWineD3DTextureImpl_GetLevelDesc,
     IWineD3DTextureImpl_GetSurfaceLevel,
     IWineD3DTextureImpl_LockRect,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0776767..208ec0b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -416,6 +416,9 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *i
 #define WINE_D3D8_CAPABLE(gl_info) WINE_D3D7_CAPABLE(gl_info) && (gl_info->supported[ARB_MULTISAMPLE] && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
 #define WINE_D3D9_CAPABLE(gl_info) WINE_D3D8_CAPABLE(gl_info) && (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[ARB_VERTEX_SHADER])
 
+/* Default callbacks for implicit object destruction */
+extern ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface);
+
 /*****************************************************************************
  * Internal representation of a light
  */
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index 6a779f3..1e0e08e 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -241,6 +241,11 @@ typedef HRESULT WINAPI (*D3DCB_ENUMDISPL
                                                           LPVOID context);
 
 /*****************************************************************************
+ * Callback functions for custom implicit surface / volume destruction.
+ */
+typedef ULONG WINAPI (*D3DCB_DESTROYSURFACEFN) (struct IWineD3DSurface *pSurface);
+
+/*****************************************************************************
  * IWineD3DBase interface
  */
 
@@ -855,6 +860,7 @@ DECLARE_INTERFACE_(IWineD3DTexture,IWine
     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;
     /*** IWineD3DTexture methods ***/
+    STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE;
     STDMETHOD(GetLevelDesc)(THIS_ UINT Level, WINED3DSURFACE_DESC* pDesc) PURE;
     STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level, struct IWineD3DSurface** ppSurfaceLevel) PURE;
     STDMETHOD(LockRect)(THIS_ UINT Level, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) PURE;
@@ -893,6 +899,7 @@ DECLARE_INTERFACE_(IWineD3DTexture,IWine
 #define IWineD3DTexture_GetTextureDimensions(p)    (p)->lpVtbl->GetTextureDimensions(p)
 #define IWineD3DTexture_ApplyStateChanges(p,a,b)   (p)->lpVtbl->ApplyStateChanges(p,a,b)
 /*** IWineD3DTexture methods ***/
+#define IWineD3DTexture_Destroy(p,a)               (p)->lpVtbl->Destroy(p,a)
 #define IWineD3DTexture_GetLevelDesc(p,a,b)        (p)->lpVtbl->GetLevelDesc(p,a,b)
 #define IWineD3DTexture_GetSurfaceLevel(p,a,b)     (p)->lpVtbl->GetSurfaceLevel(p,a,b)
 #define IWineD3DTexture_LockRect(p,a,b,c,d)        (p)->lpVtbl->LockRect(p,a,b,c,d)




More information about the wine-cvs mailing list