mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
d3d9: Handle surface refcount forwarding in d3d9.
This commit is contained in:
parent
0bceec1be8
commit
04dcffe393
@ -60,7 +60,7 @@ static ULONG WINAPI IDirect3DCubeTexture9Impl_Release(LPDIRECT3DCUBETEXTURE9 ifa
|
||||
|
||||
if (ref == 0) {
|
||||
TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
|
||||
IWineD3DCubeTexture_Release(This->wineD3DCubeTexture);
|
||||
IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D9CB_DestroySurface);
|
||||
IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
@ -301,6 +301,9 @@ typedef struct IDirect3DSurface9Impl
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE9 parentDevice;
|
||||
|
||||
/* If set forward refcounting to this object */
|
||||
IUnknown *forwardReference;
|
||||
} IDirect3DSurface9Impl;
|
||||
|
||||
/* ---------------------- */
|
||||
@ -543,4 +546,6 @@ extern HRESULT WINAPI D3D9CB_CreateRenderTarget(IUnknown *device, IUnknown *pSup
|
||||
|
||||
extern ULONG WINAPI D3D9CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface);
|
||||
|
||||
extern ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface);
|
||||
|
||||
#endif /* __WINE_D3D9_PRIVATE_H */
|
||||
|
@ -1011,8 +1011,20 @@ HRESULT WINAPI D3D9CB_CreateSurface(IUnknown *device, IUnknown *pSuperior, UINT
|
||||
*ppSurface = d3dSurface->wineD3DSurface;
|
||||
IUnknown_Release(d3dSurface->parentDevice);
|
||||
d3dSurface->parentDevice = NULL;
|
||||
d3dSurface->forwardReference = pSuperior;
|
||||
} else {
|
||||
FIXME("(%p) IDirect3DDevice9_CreateSurface failed\n", device);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface) {
|
||||
IDirect3DSurface9Impl* surfaceParent;
|
||||
TRACE("(%p) call back\n", pSurface);
|
||||
|
||||
IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
|
||||
/* GetParent's AddRef was forwarded to an object in destruction.
|
||||
* Releasing it here again would cause an endless recursion. */
|
||||
surfaceParent->forwardReference = NULL;
|
||||
return IDirect3DSurface9_Release((IDirect3DSurface9*) surfaceParent);
|
||||
}
|
||||
|
@ -43,15 +43,13 @@ static HRESULT WINAPI IDirect3DSurface9Impl_QueryInterface(LPDIRECT3DSURFACE9 if
|
||||
|
||||
static ULONG WINAPI IDirect3DSurface9Impl_AddRef(LPDIRECT3DSURFACE9 iface) {
|
||||
IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
IWineD3DSurface_GetContainerParent(This->wineD3DSurface, &containerParent);
|
||||
if (containerParent) {
|
||||
/* Forward to the containerParent */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, containerParent);
|
||||
return IUnknown_AddRef(containerParent);
|
||||
if (This->forwardReference) {
|
||||
/* Forward refcounting */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
|
||||
return IUnknown_AddRef(This->forwardReference);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
@ -64,15 +62,13 @@ static ULONG WINAPI IDirect3DSurface9Impl_AddRef(LPDIRECT3DSURFACE9 iface) {
|
||||
|
||||
static ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) {
|
||||
IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
IWineD3DSurface_GetContainerParent(This->wineD3DSurface, &containerParent);
|
||||
if (containerParent) {
|
||||
if (This->forwardReference) {
|
||||
/* Forward to the containerParent */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, containerParent);
|
||||
return IUnknown_Release(containerParent);
|
||||
TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
|
||||
return IUnknown_Release(This->forwardReference);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
@ -540,7 +540,7 @@ static void test_refcount(void)
|
||||
/* check implicit back buffer */
|
||||
hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer);
|
||||
todo_wine CHECK_CALL( hr, "GetBackBuffer", pDevice, ++refcount);
|
||||
todo_wine CHECK_REFCOUNT( pSwapChain, 1);
|
||||
CHECK_REFCOUNT( pSwapChain, 1);
|
||||
if(pBackBuffer)
|
||||
{
|
||||
CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain);
|
||||
|
@ -59,7 +59,7 @@ static ULONG WINAPI IDirect3DTexture9Impl_Release(LPDIRECT3DTEXTURE9 iface) {
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DTexture_Release(This->wineD3DTexture);
|
||||
IWineD3DTexture_Destroy(This->wineD3DTexture, D3D9CB_DestroySurface);
|
||||
IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user