From 5e0fc62135005323bf9e27abbf18c38daf171397 Mon Sep 17 00:00:00 2001 From: Markus Amsler Date: Mon, 18 Dec 2006 00:17:24 +0100 Subject: [PATCH] d3d: Callback infrastructure for implicit swap chain destruction in IWineD3DDevice. --- dlls/d3d8/d3d8_private.h | 2 ++ dlls/d3d8/device.c | 2 +- dlls/d3d8/directx.c | 9 +++++++++ dlls/d3d9/d3d9_private.h | 2 ++ dlls/d3d9/device.c | 2 +- dlls/d3d9/directx.c | 9 +++++++++ dlls/ddraw/ddraw.c | 11 ++++++++++- dlls/ddraw/ddraw_private.h | 2 ++ dlls/ddraw/surface.c | 2 +- dlls/wined3d/device.c | 8 ++------ include/wine/wined3d_interface.h | 8 +++++--- 11 files changed, 44 insertions(+), 13 deletions(-) diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 99b7a9b1f3b..fd07053811c 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -603,6 +603,8 @@ extern HRESULT WINAPI D3D8CB_CreateRenderTarget(IUnknown *device, IUnknown *pSup DWORD MultisampleQuality, BOOL Lockable, IWineD3DSurface** ppSurface, HANDLE* pSharedHandle); +extern ULONG WINAPI D3D8CB_DestroySwapChain (IWineD3DSwapChain *pSwapChain); + extern ULONG WINAPI D3D8CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface); extern ULONG WINAPI D3D8CB_DestroyRenderTarget (IWineD3DSurface *pSurface); diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 772d065390a..78c469ba104 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -99,7 +99,7 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) { if (ref == 0) { TRACE("Releasing wined3d device %p\n", This->WineD3DDevice); This->inDestruction = TRUE; - IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroyDepthStencilSurface); + IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroyDepthStencilSurface, D3D8CB_DestroySwapChain); IWineD3DDevice_Release(This->WineD3DDevice); HeapFree(GetProcessHeap(), 0, This->shader_handles); HeapFree(GetProcessHeap(), 0, This); diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 9a3d0aa089b..410107ea2e9 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -277,6 +277,15 @@ static HRESULT WINAPI D3D8CB_CreateAdditionalSwapChain(IUnknown *device, return res; } +ULONG WINAPI D3D8CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) { + IUnknown* swapChainParent; + TRACE("(%p) call back\n", pSwapChain); + + IWineD3DSwapChain_GetParent(pSwapChain, &swapChainParent); + IUnknown_Release(swapChainParent); + return IUnknown_Release(swapChainParent); +} + /* Internal function called back during the CreateDevice to create a render target */ HRESULT WINAPI D3D8CB_CreateDepthStencilSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height, WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample, diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index ad67e28f5bc..1fba1b3cf0f 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -552,6 +552,8 @@ extern HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, IUnknown *pSup DWORD MultisampleQuality, BOOL Lockable, IWineD3DSurface** ppSurface, HANDLE* pSharedHandle); +extern ULONG WINAPI D3D9CB_DestroySwapChain (IWineD3DSwapChain *pSwapChain); + extern ULONG WINAPI D3D9CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface); extern ULONG WINAPI D3D9CB_DestroyRenderTarget (IWineD3DSurface *pSurface); diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index a22324723fb..f89694f27ad 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -62,7 +62,7 @@ static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9 iface) { if (ref == 0) { This->inDestruction = TRUE; - IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface); + IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface, D3D9CB_DestroySwapChain); IWineD3DDevice_Release(This->WineD3DDevice); HeapFree(GetProcessHeap(), 0, This); } diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index be7907b72a4..548d790b57b 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -260,6 +260,15 @@ HRESULT WINAPI D3D9CB_CreateAdditionalSwapChain(IUnknown *device, return res; } +ULONG WINAPI D3D9CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) { + IUnknown* swapChainParent; + TRACE("(%p) call back\n", pSwapChain); + + IWineD3DSwapChain_GetParent(pSwapChain, &swapChainParent); + IUnknown_Release(swapChainParent); + return IUnknown_Release(swapChainParent); +} + /* Internal function called back during the CreateDevice to create a render target */ HRESULT WINAPI D3D9CB_CreateDepthStencilSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height, WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample, diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 0fd3a5b94d1..8f051d4c635 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -1626,7 +1626,7 @@ IDirectDrawImpl_RecreateAllSurfaces(IDirectDrawImpl *This) /* Should happen almost never */ FIXME("(%p) Switching to non-opengl surfaces with d3d started. Is this a bug?\n", This); /* Shutdown d3d */ - IWineD3DDevice_Uninit3D(This->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface); + IWineD3DDevice_Uninit3D(This->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain); } /* Contrary: D3D starting is handled by the caller, because it knows the render target */ @@ -1684,6 +1684,15 @@ D3D7CB_CreateSurface(IUnknown *device, return D3D_OK; } +ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) { + IUnknown* swapChainParent; + TRACE("(%p) call back\n", pSwapChain); + + IWineD3DSwapChain_GetParent(pSwapChain, &swapChainParent); + IUnknown_Release(swapChainParent); + return IUnknown_Release(swapChainParent); +} + ULONG WINAPI D3D7CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface) { IUnknown* surfaceParent; TRACE("(%p) call back\n", pSurface); diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index d31d2805dec..8828aad706e 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -76,6 +76,8 @@ typedef struct IDirect3DVertexBufferImpl IDirect3DVertexBufferImpl; typedef struct IParentImpl IParentImpl; /* Callbacks for implicit object destruction */ +extern ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain); + extern ULONG WINAPI D3D7CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface); /***************************************************************************** diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index b0055795a2e..bfee172ddc0 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -311,7 +311,7 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL, 0); IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL); - if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface) != D3D_OK) + if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain) != D3D_OK) { /* Not good */ ERR("(%p) Failed to uninit 3D\n", This); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 5ff0b34e1e5..685cdf9fe39 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2152,10 +2152,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyDepthStencilSurface) { +static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyDepthStencilSurface, D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; int sampler; - IUnknown* swapChainParent; uint i; TRACE("(%p)\n", This); @@ -2197,10 +2196,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D for(i=0; i < This->NumberOfSwapChains; i++) { TRACE("Releasing the implicit swapchain %d\n", i); - /* Swapchain 0 is special because it's created in startup with a hanging parent, so we have to release its parent now */ - IWineD3DSwapChain_GetParent(This->swapchains[i], &swapChainParent); - IUnknown_Release(swapChainParent); /* once for the get parent */ - if (IUnknown_Release(swapChainParent) > 0) { /* the second time for when it was created */ + if (D3DCB_DestroySwapChain(This->swapchains[i]) > 0) { FIXME("(%p) Something's still holding the implicit swapchain\n", This); } } diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 6947d26cd6f..56d93f46fd2 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -241,8 +241,10 @@ typedef HRESULT WINAPI (*D3DCB_ENUMDISPLAYMODESCALLBACK) (IUnknown *pDevice, LPVOID context); /***************************************************************************** - * Callback functions for custom implicit surface / volume destruction. + * Callback functions for custom implicit object destruction. */ +typedef ULONG WINAPI (*D3DCB_DESTROYSWAPCHAINFN) (struct IWineD3DSwapChain *pSwapChain); + typedef ULONG WINAPI (*D3DCB_DESTROYSURFACEFN) (struct IWineD3DSurface *pSurface); typedef ULONG WINAPI (*D3DCB_DESTROYVOLUMEFN) (struct IWineD3DVolume *pVolume); @@ -359,7 +361,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, struct IWineD3DPixelShader** ppShader, IUnknown *pParent) PURE; STDMETHOD_(HRESULT,CreatePalette)(THIS_ DWORD Flags, PALETTEENTRY *PalEnt, struct IWineD3DPalette **Palette, IUnknown *Parent); STDMETHOD(Init3D)(THIS_ WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain); - STDMETHOD(Uninit3D)(THIS, D3DCB_DESTROYSURFACEFN pFn); + STDMETHOD(Uninit3D)(THIS, D3DCB_DESTROYSURFACEFN pFn, D3DCB_DESTROYSWAPCHAINFN pFn2); STDMETHOD_(void, SetFullscreen)(THIS_ BOOL fullscreen); STDMETHOD(EnumDisplayModes)(THIS_ DWORD Flags, UINT Width, UINT Height, WINED3DFORMAT Format, void *context, D3DCB_ENUMDISPLAYMODESCALLBACK cb) PURE; STDMETHOD(EvictManagedResources)(THIS) PURE; @@ -499,7 +501,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) #define IWineD3DDevice_CreatePixelShader(p,a,b,c) (p)->lpVtbl->CreatePixelShader(p,a,b,c) #define IWineD3DDevice_CreatePalette(p, a, b, c, d) (p)->lpVtbl->CreatePalette(p, a, b, c, d) #define IWineD3DDevice_Init3D(p, a, b) (p)->lpVtbl->Init3D(p, a, b) -#define IWineD3DDevice_Uninit3D(p, a) (p)->lpVtbl->Uninit3D(p, a) +#define IWineD3DDevice_Uninit3D(p, a, b) (p)->lpVtbl->Uninit3D(p, a, b) #define IWineD3DDevice_SetFullscreen(p, a) (p)->lpVtbl->SetFullscreen(p, a) #define IWineD3DDevice_EnumDisplayModes(p,a,b,c,d,e,f) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d,e,f) #define IWineD3DDevice_EvictManagedResources(p) (p)->lpVtbl->EvictManagedResources(p)