From cb8652947adceba566c93d21e54021661e803799 Mon Sep 17 00:00:00 2001 From: Markus Amsler Date: Tue, 5 Dec 2006 00:29:14 +0100 Subject: [PATCH] d3d: Callback infrastructure for implicit render target destruction in IWineD3DSwapChain. --- dlls/wined3d/swapchain.c | 71 ++++++++++++++++++++-------------------- include/wine/wined3d_interface.h | 3 +- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index b9bf032f4df..865703d0c4c 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -88,41 +88,7 @@ static ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) { refCount = InterlockedDecrement(&This->ref); TRACE("(%p) : ReleaseRef to %d\n", This, refCount); if (refCount == 0) { - IUnknown* bufferParent; - - /* release the ref to the front and back buffer parents */ - if(This->frontBuffer) { - IWineD3DSurface_SetContainer(This->frontBuffer, 0); - IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent); - IUnknown_Release(bufferParent); /* once for the get parent */ - if(IUnknown_Release(bufferParent) > 0){ - FIXME("(%p) Something's still holding the front buffer\n",This); - } - } - - if(This->backBuffer) { - int i; - for(i = 0; i < This->presentParms.BackBufferCount; i++) { - IWineD3DSurface_SetContainer(This->backBuffer[i], 0); - IWineD3DSurface_GetParent(This->backBuffer[i], &bufferParent); - IUnknown_Release(bufferParent); /* once for the get parent */ - if(IUnknown_Release(bufferParent) > 0){ - FIXME("(%p) Something's still holding the back buffer\n",This); - } - } - } - - /* Clean up the context */ - /* check that we are the current context first */ - if(glXGetCurrentContext() == This->glCtx){ - glXMakeCurrent(This->display, None, NULL); - } - glXDestroyContext(This->display, This->glCtx); - /* IUnknown_Release(This->parent); This should only apply to the primary swapchain, - all others are created by the caller, so releasing the parent should cause - the child to be released, not the other way around! - */ - HeapFree(GetProcessHeap(), 0, This); + IWineD3DSwapChain_Destroy(iface, D3DCB_DefaultDestroySurface); } return refCount; } @@ -136,6 +102,40 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface, } /*IWineD3DSwapChain parts follow: */ +static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderTarget) { + IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; + + /* release the ref to the front and back buffer parents */ + if(This->frontBuffer) { + IWineD3DSurface_SetContainer(This->frontBuffer, 0); + if(D3DCB_DestroyRenderTarget(This->frontBuffer) > 0) { + FIXME("(%p) Something's still holding the front buffer\n",This); + } + } + + if(This->backBuffer) { + int i; + for(i = 0; i < This->presentParms.BackBufferCount; i++) { + IWineD3DSurface_SetContainer(This->backBuffer[i], 0); + if(D3DCB_DestroyRenderTarget(This->backBuffer[i]) > 0) { + FIXME("(%p) Something's still holding the back buffer\n",This); + } + } + } + + /* Clean up the context */ + /* check that we are the current context first */ + if(glXGetCurrentContext() == This->glCtx){ + glXMakeCurrent(This->display, None, NULL); + } + glXDestroyContext(This->display, This->glCtx); + /* IUnknown_Release(This->parent); This should only apply to the primary swapchain, + all others are created by the caller, so releasing the parent should cause + the child to be released, not the other way around! + */ + HeapFree(GetProcessHeap(), 0, This); +} + static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; @@ -572,6 +572,7 @@ IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl = IWineD3DSwapChainImpl_Release, /* IWineD3DSwapChain */ IWineD3DSwapChainImpl_GetParent, + IWineD3DSwapChainImpl_Destroy, IWineD3DSwapChainImpl_GetDevice, IWineD3DSwapChainImpl_Present, IWineD3DSwapChainImpl_GetFrontBufferData, diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index cb59eba603f..f546872255e 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -1367,6 +1367,7 @@ DECLARE_INTERFACE_(IWineD3DSwapChain,IWineD3DBase) /*** IWineD3DBase methods ***/ STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE; /*** IDirect3DSwapChain9 methods ***/ + STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE; STDMETHOD(GetDevice)(THIS_ IWineD3DDevice **ppDevice) PURE; STDMETHOD(Present)(THIS_ CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) PURE; STDMETHOD(GetFrontBufferData)(THIS_ IWineD3DSurface *pDestSurface) PURE; @@ -1387,7 +1388,7 @@ DECLARE_INTERFACE_(IWineD3DSwapChain,IWineD3DBase) /*** IWineD3DBase methods ***/ #define IWineD3DSwapChain_GetParent(p,a) (p)->lpVtbl->GetParent(p,a) /*** IWineD3DSwapChain methods ***/ - +#define IWineD3DSwapChain_Destroy(p,a) (p)->lpVtbl->Destroy(p,a) #define IWineD3DSwapChain_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) #define IWineD3DSwapChain_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e) #define IWineD3DSwapChain_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a) -- 2.11.4.GIT