d3d: Callback infrastructure for implicit swap chain destruction in IWineD3DDevice.

This commit is contained in:
Markus Amsler 2006-12-18 00:17:24 +01:00 committed by Alexandre Julliard
parent f9f3ec2f00
commit 5e0fc62135
11 changed files with 44 additions and 13 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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);

View File

@ -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);
/*****************************************************************************

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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)