static ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) { IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; ULONG ref; TRACE("(%p) : Releasing from %ld\n", This, This->resource.ref); ref = InterlockedDecrement(&This->resource.ref); if (ref == 0) { int i; TRACE("(%p) : Cleaning up\n",This); for (i = 0; i < This->baseTexture.levels; i++) { if (This->surfaces[i] != NULL) { /* Because the surfaces were created using a callback we need to release there parent otehrwise we leave the parent hanging */ 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); } } TRACE("(%p) : cleaning up base texture\n", This); IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *)iface); /* free the object */ HeapFree(GetProcessHeap(), 0, This); } return ref; }
ULONG WINAPI D3D9CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface) { IDirect3DSurface9Impl* surfaceParent; TRACE("(%p) call back\n", pSurface); IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent); surfaceParent->isImplicit = FALSE; /* Surface had refcount of 0 GetParent addrefed to 1, so 1 Release is enough */ return IDirect3DSurface9_Release((IDirect3DSurface9*) surfaceParent); }
static HRESULT WINAPI IDirect3DTexture9Impl_GetSurfaceLevel(LPDIRECT3DTEXTURE9 iface, UINT Level, IDirect3DSurface9** ppSurfaceLevel) { IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface; HRESULT hrc = D3D_OK; IWineD3DSurface *mySurface = NULL; TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); hrc = IWineD3DTexture_GetSurfaceLevel(This->wineD3DTexture, Level, &mySurface); if (hrc == D3D_OK && NULL != ppSurfaceLevel) { IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppSurfaceLevel); IWineD3DSurface_Release(mySurface); } LeaveCriticalSection(&d3d9_cs); return hrc; }
static HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(IDirect3DSwapChain8 *iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8 **ppBackBuffer) { IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface; IWineD3DSurface *mySurface = NULL; HRESULT hr; TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n", iface, iBackBuffer, Type, ppBackBuffer); wined3d_mutex_lock(); hr = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, (WINED3DBACKBUFFER_TYPE)Type, &mySurface); if (SUCCEEDED(hr) && mySurface) { *ppBackBuffer = IWineD3DSurface_GetParent(mySurface); IDirect3DSurface8_AddRef(*ppBackBuffer); IWineD3DSurface_Release(mySurface); } wined3d_mutex_unlock(); return hr; }