Commit 07004966 authored by H. Verbeet's avatar H. Verbeet Committed by Alexandre Julliard

wined3d: Fix the relation between volumes and their container.

parent f7356a34
......@@ -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)\n", 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);
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
if (ref == 0) {
IWineD3DVolume_Release(This->wineD3DVolume);
HeapFree(GetProcessHeap(), 0, This);
}
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)\n", 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);
TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
if (ref == 0) {
IWineD3DVolume_Release(This->wineD3DVolume);
HeapFree(GetProcessHeap(), 0, This);
}
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment