wined3d: Fix the relation between surfaces and their container.
This commit is contained in:
parent
fd2739b023
commit
f7356a34c3
|
@ -41,24 +41,46 @@ HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface, RE
|
|||
|
||||
ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return ref;
|
||||
IWineD3DSurface_GetContainerParent(This->wineD3DSurface, &containerParent);
|
||||
if (containerParent) {
|
||||
/* Forward to the containerParent */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, containerParent);
|
||||
return IUnknown_AddRef(containerParent);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG WINAPI IDirect3DSurface8Impl_Release(LPDIRECT3DSURFACE8 iface) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DSurface_Release(This->wineD3DSurface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
IWineD3DSurface_GetContainerParent(This->wineD3DSurface, &containerParent);
|
||||
if (containerParent) {
|
||||
/* Forward to the containerParent */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, containerParent);
|
||||
return IUnknown_Release(containerParent);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DSurface_Release(This->wineD3DSurface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DSurface8 IDirect3DResource8 Interface follow: */
|
||||
|
|
|
@ -42,24 +42,48 @@ HRESULT WINAPI IDirect3DSurface9Impl_QueryInterface(LPDIRECT3DSURFACE9 iface, RE
|
|||
|
||||
ULONG WINAPI IDirect3DSurface9Impl_AddRef(LPDIRECT3DSURFACE9 iface) {
|
||||
IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
|
||||
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);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) {
|
||||
IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DSurface_Release(This->wineD3DSurface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
IWineD3DSurface_GetContainerParent(This->wineD3DSurface, &containerParent);
|
||||
if (containerParent) {
|
||||
/* Forward to the containerParent */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, containerParent);
|
||||
return IUnknown_Release(containerParent);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DSurface_Release(This->wineD3DSurface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DSurface9 IDirect3DResource9 Interface follow: */
|
||||
|
|
|
@ -84,6 +84,9 @@ ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface) {
|
|||
IUnknown* surfaceParent;
|
||||
/* Clean out the texture name we gave to the suface so that the surface doesn't try and release it */
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], 0, 0);
|
||||
/* Cleanup the container */
|
||||
IWineD3DSurface_SetContainer(This->surfaces[j][i], 0);
|
||||
/* Now, release the parent, which will take care of cleaning up the surface for us */
|
||||
TRACE("(%p) : Releasing surface%d %d %p\n", This, j, i, This->surfaces[j][i]);
|
||||
IWineD3DSurface_GetParent(This->surfaces[j][i], &surfaceParent);
|
||||
IUnknown_Release(surfaceParent);
|
||||
|
|
|
@ -1433,7 +1433,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac
|
|||
&This->depthStencilBuffer,
|
||||
NULL /* pShared (always null)*/ );
|
||||
if (This->depthStencilBuffer != NULL)
|
||||
IWineD3DSurface_SetContainer(This->depthStencilBuffer, (IWineD3DBase *)iface);
|
||||
IWineD3DSurface_SetContainer(This->depthStencilBuffer, 0);
|
||||
}
|
||||
|
||||
/** TODO: A check on width, height and multisample types
|
||||
|
|
|
@ -173,6 +173,29 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **
|
|||
IWineD3DSurface IWineD3DSurface parts follow
|
||||
****************************************************** */
|
||||
|
||||
HRESULT WINAPI IWineD3DSurfaceImpl_GetContainerParent(IWineD3DSurface* iface, IUnknown **ppContainerParent) {
|
||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||
|
||||
TRACE("(%p) : ppContainerParent %p)\n", This, ppContainerParent);
|
||||
|
||||
if (!ppContainerParent) {
|
||||
ERR("(%p) : Called without a valid ppContainerParent.\n", This);
|
||||
}
|
||||
|
||||
if (This->container) {
|
||||
IWineD3DBase_GetParent(This->container, ppContainerParent);
|
||||
if (!ppContainerParent) {
|
||||
/* WineD3D objects should always have a parent */
|
||||
ERR("(%p) : GetParent returned NULL\n", This);
|
||||
}
|
||||
IUnknown_Release(*ppContainerParent); /* GetParent adds a reference; we want just the pointer */
|
||||
} else {
|
||||
*ppContainerParent = NULL;
|
||||
}
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer) {
|
||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||
IWineD3DBase *container = 0;
|
||||
|
@ -1439,6 +1462,7 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
|
|||
IWineD3DSurfaceImpl_PreLoad,
|
||||
IWineD3DSurfaceImpl_GetType,
|
||||
/* IWineD3DSurface */
|
||||
IWineD3DSurfaceImpl_GetContainerParent,
|
||||
IWineD3DSurfaceImpl_GetContainer,
|
||||
IWineD3DSurfaceImpl_GetDesc,
|
||||
IWineD3DSurfaceImpl_LockRect,
|
||||
|
|
|
@ -93,12 +93,14 @@ ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
|
|||
IWineD3DDevice_SwapChainReleased((IWineD3DDevice *)This->wineD3DDevice, iface);
|
||||
|
||||
/* release the ref to the front and back buffer parents */
|
||||
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);
|
||||
}
|
||||
|
||||
IWineD3DSurface_SetContainer(This->backBuffer, 0);
|
||||
IWineD3DSurface_GetParent(This->backBuffer, &bufferParent);
|
||||
IUnknown_Release(bufferParent); /* once for the get parent */
|
||||
if(IUnknown_Release(bufferParent) > 0){
|
||||
|
|
|
@ -66,6 +66,9 @@ ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) {
|
|||
IUnknown* surfaceParent;
|
||||
/* Clean out the texture name we gave to the suface so that the surface doesn't try and release it */
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], 0, 0);
|
||||
/* Cleanup the container */
|
||||
IWineD3DSurface_SetContainer(This->surfaces[i], 0);
|
||||
/* Now, release the parent, which will take care of cleaning up the surface for us */
|
||||
IWineD3DSurface_GetParent(This->surfaces[i], &surfaceParent);
|
||||
IUnknown_Release(surfaceParent);
|
||||
IUnknown_Release(surfaceParent);
|
||||
|
|
|
@ -1045,6 +1045,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
|
|||
STDMETHOD_(void,PreLoad)(THIS) PURE;
|
||||
STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
|
||||
/*** IWineD3DSurface methods ***/
|
||||
STDMETHOD(GetContainerParent)(THIS_ IUnknown **ppContainerParent) PURE;
|
||||
STDMETHOD(GetContainer)(THIS_ REFIID riid, void ** ppContainer) PURE;
|
||||
STDMETHOD(GetDesc)(THIS_ WINED3DSURFACE_DESC * pDesc) PURE;
|
||||
STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT * pLockedRect, CONST RECT * pRect,DWORD Flags) PURE;
|
||||
|
@ -1082,6 +1083,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
|
|||
#define IWineD3DSurface_PreLoad(p) (p)->lpVtbl->PreLoad(p)
|
||||
#define IWineD3DSurface_GetType(p) (p)->lpVtbl->GetType(p)
|
||||
/*** IWineD3DSurface methods ***/
|
||||
#define IWineD3DSurface_GetContainerParent(p,a) (p)->lpVtbl->GetContainerParent(p,a)
|
||||
#define IWineD3DSurface_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b)
|
||||
#define IWineD3DSurface_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
|
||||
#define IWineD3DSurface_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c)
|
||||
|
|
Loading…
Reference in New Issue