wined3d: Fix the relation between volumes and their container.
This commit is contained in:
parent
f7356a34c3
commit
07004966a8
|
@ -40,24 +40,47 @@ HRESULT WINAPI IDirect3DVolume8Impl_QueryInterface(LPDIRECT3DVOLUME8 iface, REFI
|
|||
|
||||
ULONG WINAPI IDirect3DVolume8Impl_AddRef(LPDIRECT3DVOLUME8 iface) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return ref;
|
||||
IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &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 IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DVolume_Release(This->wineD3DVolume);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &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) {
|
||||
IWineD3DVolume_Release(This->wineD3DVolume);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DVolume8 Interface follow: */
|
||||
|
|
|
@ -41,24 +41,46 @@ HRESULT WINAPI IDirect3DVolume9Impl_QueryInterface(LPDIRECT3DVOLUME9 iface, REFI
|
|||
|
||||
ULONG WINAPI IDirect3DVolume9Impl_AddRef(LPDIRECT3DVOLUME9 iface) {
|
||||
IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return ref;
|
||||
IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &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 IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) {
|
||||
IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
IUnknown *containerParent = NULL;
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DVolume_Release(This->wineD3DVolume);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &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) {
|
||||
IWineD3DVolume_Release(This->wineD3DVolume);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DVolume9 Interface follow: */
|
||||
|
|
|
@ -103,6 +103,29 @@ D3DRESOURCETYPE WINAPI IWineD3DVolumeImpl_GetType(IWineD3DVolume *iface) {
|
|||
/* *******************************************
|
||||
IWineD3DVolume parts follow
|
||||
******************************************* */
|
||||
HRESULT WINAPI IWineD3DVolumeImpl_GetContainerParent(IWineD3DVolume *iface, IUnknown **ppContainerParent) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)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 IWineD3DVolumeImpl_GetContainer(IWineD3DVolume *iface, REFIID riid, void** ppContainer) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
|
||||
|
@ -304,6 +327,7 @@ const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl =
|
|||
IWineD3DVolumeImpl_PreLoad,
|
||||
IWineD3DVolumeImpl_GetType,
|
||||
/* IWineD3DVolume */
|
||||
IWineD3DVolumeImpl_GetContainerParent,
|
||||
IWineD3DVolumeImpl_GetContainer,
|
||||
IWineD3DVolumeImpl_GetDesc,
|
||||
IWineD3DVolumeImpl_LockBox,
|
||||
|
|
|
@ -60,8 +60,19 @@ ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *iface) {
|
|||
if (ref == 0) {
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
if (This->volumes[i] != NULL) {
|
||||
/* Since the volumes were created by callback, the texture is
|
||||
* keeping the reference to the parent, so the texture should
|
||||
* release it. */
|
||||
IUnknown *volumeParent = NULL;
|
||||
|
||||
TRACE("(%p) : Releasing volume %p\n", This, This->volumes[i]);
|
||||
IWineD3DVolume_Release(This->volumes[i]);
|
||||
|
||||
/* Cleanup the container */
|
||||
IWineD3DVolume_SetContainer(This->volumes[i], 0);
|
||||
/* Now, release the parent, which will take care of cleaning up the volume for us */
|
||||
IWineD3DVolume_GetParent(This->volumes[i], &volumeParent);
|
||||
IUnknown_Release(volumeParent); /* Once for the reference GetParent added */
|
||||
IUnknown_Release(volumeParent); /* Once for the reference we're keeping */
|
||||
}
|
||||
}
|
||||
IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *) iface);
|
||||
|
|
|
@ -1125,6 +1125,7 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD3DResource)
|
|||
STDMETHOD_(void,PreLoad)(THIS) PURE;
|
||||
STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
|
||||
/*** IWineD3DVolume methods ***/
|
||||
STDMETHOD(GetContainerParent)(THIS_ IUnknown **ppContainerParent) PURE;
|
||||
STDMETHOD(GetContainer)(THIS_ REFIID riid, void ** ppContainer) PURE;
|
||||
STDMETHOD(GetDesc)(THIS_ WINED3DVOLUME_DESC * pDesc) PURE;
|
||||
STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) PURE;
|
||||
|
@ -1153,6 +1154,7 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD3DResource)
|
|||
#define IWineD3DVolume_PreLoad(p) (p)->lpVtbl->PreLoad(p)
|
||||
#define IWineD3DVolume_GetType(p) (p)->lpVtbl->GetType(p)
|
||||
/*** IWineD3DVolume methods ***/
|
||||
#define IWineD3DVolume_GetContainerParent(p,a) (p)->lpVtbl->GetContainerParent(p,a)
|
||||
#define IWineD3DVolume_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b)
|
||||
#define IWineD3DVolume_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
|
||||
#define IWineD3DVolume_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c)
|
||||
|
|
Loading…
Reference in New Issue