d3d8: Handle surface refcount forwarding in d3d8.

This commit is contained in:
Markus Amsler 2006-12-05 00:29:37 +01:00 committed by Alexandre Julliard
parent 3fd04308ab
commit 0d725490d6
6 changed files with 28 additions and 15 deletions

View File

@ -57,7 +57,7 @@ static ULONG WINAPI IDirect3DCubeTexture8Impl_Release(LPDIRECT3DCUBETEXTURE8 ifa
if (ref == 0) {
TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
IWineD3DCubeTexture_Release(This->wineD3DCubeTexture);
IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D8CB_DestroySurface);
IUnknown_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}

View File

@ -246,6 +246,9 @@ struct IDirect3DSurface8Impl
/* Parent reference */
LPDIRECT3DDEVICE8 parentDevice;
/* If set forward refcounting to this object */
IUnknown *forwardReference;
};
/* ------------------ */
@ -593,4 +596,6 @@ extern HRESULT WINAPI D3D8CB_CreateRenderTarget(IUnknown *device, IUnknown *pSup
extern ULONG WINAPI D3D8CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface);
extern ULONG WINAPI D3D8CB_DestroySurface(IWineD3DSurface *pSurface);
#endif /* __WINE_D3DX8_PRIVATE_H */

View File

@ -1622,8 +1622,20 @@ HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, IUnknown *pSuperior, UINT
*ppSurface = d3dSurface->wineD3DSurface;
IUnknown_Release(d3dSurface->parentDevice);
d3dSurface->parentDevice = NULL;
d3dSurface->forwardReference = pSuperior;
} else {
FIXME("(%p) IDirect3DDevice8_CreateSurface failed\n", device);
}
return res;
}
ULONG WINAPI D3D8CB_DestroySurface(IWineD3DSurface *pSurface) {
IDirect3DSurface8Impl* 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 IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
}

View File

@ -42,15 +42,13 @@ static HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 if
static ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)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);
@ -61,15 +59,13 @@ static ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) {
static ULONG WINAPI IDirect3DSurface8Impl_Release(LPDIRECT3DSURFACE8 iface) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)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_Release(containerParent);
if (This->forwardReference) {
/* Forward refcounting */
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);

View File

@ -490,7 +490,7 @@ static void test_refcount(void)
/* check implicit back buffer */
hr = IDirect3DSwapChain8_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)
{
todo_wine CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DDevice8, pDevice);

View File

@ -57,7 +57,7 @@ static ULONG WINAPI IDirect3DTexture8Impl_Release(LPDIRECT3DTEXTURE8 iface) {
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
IWineD3DTexture_Release(This->wineD3DTexture);
IWineD3DTexture_Destroy(This->wineD3DTexture, D3D8CB_DestroySurface);
IUnknown_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}