On 12/02/06, Stefan Dösinger stefandoesinger@gmx.at wrote:
Hi, I've thought over this: If you want to connect the IWineD3DTexture and IWineD3DSurface refcounts only, then there's no problem for me. If you want to connect the Texture's and Surface's Parents refcount,
Are you talking about IDirect3DSurface9 <=> IDirect3DTexture9 or do you mean IDirect3DSurface9 <=> IWineD3DSurface?
then you have do the same for the rendertargets and the swapchain(I guess that Windows does that too), and I can use that connection to manage complex ddraw surfaces.
I haven't verified it, but the MSDN documentation for GetContainer appears to imply that it does. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/... Unfortunately my knowledge of ddraw and d3d7 is somewhat limited, so it's a bit hard for me to oversee all the implications those changes would have for ddraw / d3d7. The choice for Surface and Texture as an example is somewhat arbitrary I guess, but probably the one for which it matters the most. (As in, is most likely to break stuff if it isn't implemented correctly). In principle it would change for any object that has a container or uses similar construction. Perhaps it would even make sense to forward AddRef and Release calls for all d3d7/8/9 objects that directly wrap a wined3d object.
For reference, the code for Release & CleanUp would look something like this for the different objects:
/* WineD3D Surface */ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; if (This->container) { return IWineD3DBase_Release(This->container); } else { /* Handle our own refcounting */ } }
void WINAPI IWineD3DSurfaceImpl_CleanUp(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
/* Do some cleaning for ourselves */
This->parentCleanUp(This->parent); }
/* WineD3D Texture */ ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) { IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; ULONG ref = InterlockedDecrement(&This->resource.ref); if (!ref) { IWineD3DTexture_CleanUp(iface); }
return ref; }
void WINAPI IWineD3DTextureImpl_CleanUp(IWineD3DTexture *iface) { IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; int i; for (i = 0; i < This->baseTexture.levels; ++i) { IWineD3DSurface_Cleanup(This->surfaces[i]); }
/* Do some cleaning for ourselves */
This->parentCleanUp(This->parent); }
/* IDirect3DSurface9 */ ULONG WINAPI IDirect3DSurface9Impl_Release(IDirect3DSurface9 *iface) { IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface; return IWineD3DSurface_Release(This->wineD3DSurface); }
void WINAPI IDirect3DSurface9Impl_CleanUp(IDirect3DSurface9 *iface) { IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface; /* Cleanup Some stuff */ }
/* IDirect3DTexture9 */ ULONG WINAPI IDirect3DTexture9Impl_Release(IDirect3DTexture9 *iface) { IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface; return IWineD3DTexture_Release(This->wineD3DTexture); }
void WINAPI IDirect3DTexture9Impl_CleanUp(IDirect3DTexture9 *iface) { IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface; /* Cleanup Some stuff */ }
AddRef would follow a similar pattern, although somewhat simpler since it doesn't have to handle cleaning up the object.