[PATCH 01/10] wined3d: Don't free D3D surfaces until the wined3d surface is destroyed.
Henri Verbeet
hverbeet at codeweavers.com
Wed Sep 16 01:37:15 CDT 2009
This prevents for example a d3d9 depth stencil from being destroyed when it
has no external references but is still in use by the device/stateblock. A
nice side effect is that it simplifies handling of "implicit" surfaces like
the frontbuffer and backbuffers, as well as the forwarding of reference counts
for surfaces that are part of a texture.
---
dlls/d3d10core/device.c | 6 ++
dlls/d3d10core/texture2d.c | 21 +++++++-
dlls/d3d8/cubetexture.c | 2 +-
dlls/d3d8/d3d8_private.h | 6 --
dlls/d3d8/device.c | 23 +++-----
dlls/d3d8/directx.c | 20 -------
dlls/d3d8/surface.c | 31 ++++++++---
dlls/d3d8/swapchain.c | 2 +-
dlls/d3d8/texture.c | 2 +-
dlls/d3d9/cubetexture.c | 2 +-
dlls/d3d9/d3d9_private.h | 6 --
dlls/d3d9/device.c | 22 +++-----
dlls/d3d9/directx.c | 20 -------
dlls/d3d9/surface.c | 31 ++++++++---
dlls/d3d9/swapchain.c | 2 +-
dlls/d3d9/texture.c | 2 +-
dlls/ddraw/ddraw.c | 109 ++++++++--------------------------------
dlls/ddraw/ddraw_private.h | 3 -
dlls/ddraw/main.c | 4 --
dlls/ddraw/surface.c | 9 +++-
dlls/dxgi/swapchain.c | 14 +-----
dlls/wined3d/cubetexture.c | 13 +++--
dlls/wined3d/device.c | 31 ++++-------
dlls/wined3d/directx.c | 18 +++----
dlls/wined3d/surface.c | 6 ++-
dlls/wined3d/surface_base.c | 4 +-
dlls/wined3d/swapchain.c | 11 ++--
dlls/wined3d/swapchain_base.c | 2 +-
dlls/wined3d/swapchain_gdi.c | 13 +++--
dlls/wined3d/texture.c | 13 +++--
dlls/wined3d/wined3d_private.h | 6 +-
include/wine/wined3d.idl | 13 +++--
32 files changed, 188 insertions(+), 279 deletions(-)
diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c
index 9026b75..6b685b0 100644
--- a/dlls/d3d10core/device.c
+++ b/dlls/d3d10core/device.c
@@ -1379,6 +1379,8 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
}
*surface = texture->wined3d_surface;
+ IWineD3DSurface_AddRef(*surface);
+ ID3D10Texture2D_Release((ID3D10Texture2D *)texture);
return S_OK;
}
@@ -1418,6 +1420,8 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDevice
}
*surface = texture->wined3d_surface;
+ IWineD3DSurface_AddRef(*surface);
+ ID3D10Texture2D_Release((ID3D10Texture2D *)texture);
return S_OK;
}
@@ -1457,6 +1461,8 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
}
*surface = texture->wined3d_surface;
+ IWineD3DSurface_AddRef(*surface);
+ ID3D10Texture2D_Release((ID3D10Texture2D *)texture);
return S_OK;
}
diff --git a/dlls/d3d10core/texture2d.c b/dlls/d3d10core/texture2d.c
index edb2329..3d5eea1 100644
--- a/dlls/d3d10core/texture2d.c
+++ b/dlls/d3d10core/texture2d.c
@@ -61,9 +61,19 @@ static ULONG STDMETHODCALLTYPE d3d10_texture2d_AddRef(ID3D10Texture2D *iface)
TRACE("%p increasing refcount to %u\n", This, refcount);
+ if (refcount == 1 && This->wined3d_surface) IWineD3DSurface_AddRef(This->wined3d_surface);
+
return refcount;
}
+static void STDMETHODCALLTYPE d3d10_texture2d_wined3d_object_released(void *parent)
+{
+ struct d3d10_texture2d *This = parent;
+
+ if (This->dxgi_surface) IDXGISurface_Release(This->dxgi_surface);
+ HeapFree(GetProcessHeap(), 0, This);
+}
+
static ULONG STDMETHODCALLTYPE d3d10_texture2d_Release(ID3D10Texture2D *iface)
{
struct d3d10_texture2d *This = (struct d3d10_texture2d *)iface;
@@ -73,9 +83,8 @@ static ULONG STDMETHODCALLTYPE d3d10_texture2d_Release(ID3D10Texture2D *iface)
if (!refcount)
{
- if (This->dxgi_surface) IDXGISurface_Release(This->dxgi_surface);
if (This->wined3d_surface) IWineD3DSurface_Release(This->wined3d_surface);
- HeapFree(GetProcessHeap(), 0, This);
+ else d3d10_texture2d_wined3d_object_released(This);
}
return refcount;
@@ -182,6 +191,11 @@ static const struct ID3D10Texture2DVtbl d3d10_texture2d_vtbl =
d3d10_texture2d_GetDesc,
};
+static const struct wined3d_parent_ops d3d10_texture2d_wined3d_parent_ops =
+{
+ d3d10_texture2d_wined3d_object_released,
+};
+
HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device,
const D3D10_TEXTURE2D_DESC *desc)
{
@@ -217,7 +231,8 @@ HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_devic
wined3dformat_from_dxgi_format(desc->Format), FALSE, FALSE, 0,
&texture->wined3d_surface, desc->Usage, WINED3DPOOL_DEFAULT,
desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3DMULTISAMPLE_NONE,
- desc->SampleDesc.Quality, SURFACE_OPENGL, (IUnknown *)texture);
+ desc->SampleDesc.Quality, SURFACE_OPENGL, (IUnknown *)texture,
+ &d3d10_texture2d_wined3d_parent_ops);
if (FAILED(hr))
{
ERR("CreateSurface failed, returning %#x\n", hr);
diff --git a/dlls/d3d8/cubetexture.c b/dlls/d3d8/cubetexture.c
index d0b8f72..4377693 100644
--- a/dlls/d3d8/cubetexture.c
+++ b/dlls/d3d8/cubetexture.c
@@ -59,7 +59,7 @@ static ULONG WINAPI IDirect3DCubeTexture8Impl_Release(LPDIRECT3DCUBETEXTURE8 ifa
TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
wined3d_mutex_lock();
- IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D8CB_DestroySurface);
+ IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture);
wined3d_mutex_unlock();
IUnknown_Release(This->parentDevice);
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index ba58cc3..af5b77a 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -284,9 +284,6 @@ struct IDirect3DSurface8Impl
/* If set forward refcounting to this object */
IUnknown *forwardReference;
-
- /* Flags an implicit surface */
- BOOL isImplicit;
};
HRESULT surface_init(IDirect3DSurface8Impl *surface, IDirect3DDevice8Impl *device,
@@ -650,9 +647,6 @@ size_t parse_token(const DWORD* pToken);
/* Callbacks */
extern ULONG WINAPI D3D8CB_DestroySwapChain (IWineD3DSwapChain *pSwapChain);
-extern ULONG WINAPI D3D8CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface);
-extern ULONG WINAPI D3D8CB_DestroyRenderTarget (IWineD3DSurface *pSurface);
-extern ULONG WINAPI D3D8CB_DestroySurface(IWineD3DSurface *pSurface);
extern ULONG WINAPI D3D8CB_DestroyVolume(IWineD3DVolume *pVolume);
#endif /* __WINE_D3DX8_PRIVATE_H */
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 76cfe88..95425e5 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -309,7 +309,7 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
}
HeapFree(GetProcessHeap(), 0, This->decls);
- IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroyDepthStencilSurface, D3D8CB_DestroySwapChain);
+ IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroySwapChain);
IWineD3DDevice_Release(This->WineD3DDevice);
HeapFree(GetProcessHeap(), 0, This->handle_table.entries);
HeapFree(GetProcessHeap(), 0, This);
@@ -2602,17 +2602,6 @@ const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl =
IDirect3DDevice8Impl_DeletePatch
};
-ULONG WINAPI D3D8CB_DestroySurface(IWineD3DSurface *pSurface) {
- IDirect3DSurface8Impl* surfaceParent;
- TRACE("(%p) call back\n", pSurface);
-
- IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
- /* GetParent's AddRef was forwarded to an object in destruction.
- * Releasing it here again would cause an endless recursion. */
- surfaceParent->forwardReference = NULL;
- return IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
-}
-
/* IWineD3DDeviceParent IUnknown methods */
static inline struct IDirect3DDevice8Impl *device_from_device_parent(IWineD3DDeviceParent *iface)
@@ -2672,9 +2661,13 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
}
*surface = d3d_surface->wineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
+
d3d_surface->container = superior;
IUnknown_Release(d3d_surface->parentDevice);
d3d_surface->parentDevice = NULL;
+
+ IDirect3DSurface8_Release((IDirect3DSurface8 *)d3d_surface);
d3d_surface->forwardReference = superior;
return hr;
@@ -2701,8 +2694,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDevice
}
*surface = d3d_surface->wineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
+
d3d_surface->container = (IUnknown *)This;
- d3d_surface->isImplicit = TRUE;
/* Implicit surfaces are created with an refcount of 0 */
IUnknown_Release((IUnknown *)d3d_surface);
@@ -2730,8 +2724,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
}
*surface = d3d_surface->wineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
+
d3d_surface->container = (IUnknown *)This;
- d3d_surface->isImplicit = TRUE;
/* Implicit surfaces are created with an refcount of 0 */
IUnknown_Release((IUnknown *)d3d_surface);
diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index 3368794..1ad7aef 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -312,16 +312,6 @@ static HMONITOR WINAPI IDirect3D8Impl_GetAdapterMonitor(LPDIRECT3D8 iface, UINT
return ret;
}
-ULONG WINAPI D3D8CB_DestroyRenderTarget(IWineD3DSurface *pSurface) {
- IDirect3DSurface8Impl* 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 IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
-}
-
ULONG WINAPI D3D8CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
IUnknown* swapChainParent;
TRACE("(%p) call back\n", pSwapChain);
@@ -331,16 +321,6 @@ ULONG WINAPI D3D8CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
return IUnknown_Release(swapChainParent);
}
-ULONG WINAPI D3D8CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface) {
- IDirect3DSurface8Impl* 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 IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
-}
-
static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice8** ppReturnedDeviceInterface) {
diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c
index 4cbe1c6..2d00fce 100644
--- a/dlls/d3d8/surface.c
+++ b/dlls/d3d8/surface.c
@@ -52,7 +52,13 @@ static ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) {
} else {
/* No container, handle our own refcounting */
ULONG ref = InterlockedIncrement(&This->ref);
- if(ref == 1 && This->parentDevice) IUnknown_AddRef(This->parentDevice);
+ if (ref == 1)
+ {
+ if (This->parentDevice) IUnknown_AddRef(This->parentDevice);
+ wined3d_mutex_lock();
+ IUnknown_AddRef(This->wineD3DSurface);
+ wined3d_mutex_unlock();
+ }
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
return ref;
}
@@ -75,13 +81,9 @@ static ULONG WINAPI IDirect3DSurface8Impl_Release(LPDIRECT3DSURFACE8 iface) {
if (ref == 0) {
if (This->parentDevice) IUnknown_Release(This->parentDevice);
/* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
- if (!This->isImplicit) {
- wined3d_mutex_lock();
- IWineD3DSurface_Release(This->wineD3DSurface);
- wined3d_mutex_unlock();
-
- HeapFree(GetProcessHeap(), 0, This);
- }
+ wined3d_mutex_lock();
+ IWineD3DSurface_Release(This->wineD3DSurface);
+ wined3d_mutex_unlock();
}
return ref;
@@ -247,6 +249,16 @@ static const IDirect3DSurface8Vtbl Direct3DSurface8_Vtbl =
IDirect3DSurface8Impl_UnlockRect
};
+static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
+{
+ surface_wined3d_object_destroyed,
+};
+
HRESULT surface_init(IDirect3DSurface8Impl *surface, IDirect3DDevice8Impl *device,
UINT width, UINT height, D3DFORMAT format, BOOL lockable, BOOL discard, UINT level,
DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
@@ -266,7 +278,8 @@ HRESULT surface_init(IDirect3DSurface8Impl *surface, IDirect3DDevice8Impl *devic
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateSurface(device->WineD3DDevice, width, height, wined3dformat_from_d3dformat(format),
lockable, discard, level, &surface->wineD3DSurface, usage & WINED3DUSAGE_MASK, (WINED3DPOOL)pool,
- multisample_type, multisample_quality, SURFACE_OPENGL, (IUnknown *)surface);
+ multisample_type, multisample_quality, SURFACE_OPENGL, (IUnknown *)surface,
+ &d3d8_surface_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{
diff --git a/dlls/d3d8/swapchain.c b/dlls/d3d8/swapchain.c
index 67f3429..e851548 100644
--- a/dlls/d3d8/swapchain.c
+++ b/dlls/d3d8/swapchain.c
@@ -57,7 +57,7 @@ static ULONG WINAPI IDirect3DSwapChain8Impl_Release(LPDIRECT3DSWAPCHAIN8 iface)
if (ref == 0) {
wined3d_mutex_lock();
- IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D8CB_DestroyRenderTarget);
+ IWineD3DSwapChain_Destroy(This->wineD3DSwapChain);
wined3d_mutex_unlock();
if (This->parentDevice) IUnknown_Release(This->parentDevice);
diff --git a/dlls/d3d8/texture.c b/dlls/d3d8/texture.c
index c22c491..b4c4a5b 100644
--- a/dlls/d3d8/texture.c
+++ b/dlls/d3d8/texture.c
@@ -58,7 +58,7 @@ static ULONG WINAPI IDirect3DTexture8Impl_Release(LPDIRECT3DTEXTURE8 iface) {
if (ref == 0) {
wined3d_mutex_lock();
- IWineD3DTexture_Destroy(This->wineD3DTexture, D3D8CB_DestroySurface);
+ IWineD3DTexture_Destroy(This->wineD3DTexture);
wined3d_mutex_unlock();
IUnknown_Release(This->parentDevice);
diff --git a/dlls/d3d9/cubetexture.c b/dlls/d3d9/cubetexture.c
index 8209d0b..8ab29fd 100644
--- a/dlls/d3d9/cubetexture.c
+++ b/dlls/d3d9/cubetexture.c
@@ -62,7 +62,7 @@ static ULONG WINAPI IDirect3DCubeTexture9Impl_Release(LPDIRECT3DCUBETEXTURE9 ifa
TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
wined3d_mutex_lock();
- IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D9CB_DestroySurface);
+ IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture);
IDirect3DDevice9Ex_Release(This->parentDevice);
wined3d_mutex_unlock();
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 5c30024..494a6f3 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -301,9 +301,6 @@ typedef struct IDirect3DSurface9Impl
/* If set forward refcounting to this object */
IUnknown *forwardReference;
- /* Flags an implicit surface */
- BOOL isImplicit;
-
BOOL getdc_supported;
} IDirect3DSurface9Impl;
@@ -539,9 +536,6 @@ typedef struct IDirect3DQuery9Impl {
/* Callbacks */
extern ULONG WINAPI D3D9CB_DestroySwapChain (IWineD3DSwapChain *pSwapChain);
-extern ULONG WINAPI D3D9CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface);
-extern ULONG WINAPI D3D9CB_DestroyRenderTarget (IWineD3DSurface *pSurface);
-extern ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface);
extern ULONG WINAPI D3D9CB_DestroyVolume(IWineD3DVolume *pVolume);
#endif /* __WINE_D3D9_PRIVATE_H */
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index f57eb4d..e681542 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -257,7 +257,7 @@ static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
}
HeapFree(GetProcessHeap(), 0, This->convertedDecls);
- IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface, D3D9CB_DestroySwapChain);
+ IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroySwapChain);
IWineD3DDevice_Release(This->WineD3DDevice);
wined3d_mutex_unlock();
@@ -1997,17 +1997,6 @@ const IDirect3DDevice9ExVtbl Direct3DDevice9_Vtbl =
IDirect3DDevice9ExImpl_GetDisplayModeEx
};
-ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface) {
- IDirect3DSurface9Impl* surfaceParent;
- TRACE("(%p) call back\n", pSurface);
-
- IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
- /* GetParent's AddRef was forwarded to an object in destruction.
- * Releasing it here again would cause an endless recursion. */
- surfaceParent->forwardReference = NULL;
- return IDirect3DSurface9_Release((IDirect3DSurface9*) surfaceParent);
-}
-
/* IWineD3DDeviceParent IUnknown methods */
static inline struct IDirect3DDevice9Impl *device_from_device_parent(IWineD3DDeviceParent *iface)
@@ -2067,9 +2056,13 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
}
*surface = d3d_surface->wineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
+
d3d_surface->container = superior;
IDirect3DDevice9Ex_Release(d3d_surface->parentDevice);
d3d_surface->parentDevice = NULL;
+
+ IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
d3d_surface->forwardReference = superior;
return hr;
@@ -2097,8 +2090,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDevice
}
*surface = d3d_surface->wineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
+
d3d_surface->container = superior;
- d3d_surface->isImplicit = TRUE;
/* Implicit surfaces are created with an refcount of 0 */
IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
@@ -2127,8 +2121,8 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
}
*surface = d3d_surface->wineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
d3d_surface->container = (IUnknown *)This;
- d3d_surface->isImplicit = TRUE;
/* Implicit surfaces are created with an refcount of 0 */
IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index fe22916..aba3362 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -383,16 +383,6 @@ static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9EX iface, UIN
return ret;
}
-ULONG WINAPI D3D9CB_DestroyRenderTarget(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);
-}
-
ULONG WINAPI D3D9CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
IDirect3DSwapChain9Impl* swapChainParent;
TRACE("(%p) call back\n", pSwapChain);
@@ -403,16 +393,6 @@ ULONG WINAPI D3D9CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
return IDirect3DSwapChain9_Release((IDirect3DSwapChain9*) swapChainParent);
}
-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 IDirect3D9Impl_CreateDevice(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType,
HWND hFocusWindow, DWORD BehaviourFlags,
D3DPRESENT_PARAMETERS* pPresentationParameters,
diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c
index adb0420..f9b2794 100644
--- a/dlls/d3d9/surface.c
+++ b/dlls/d3d9/surface.c
@@ -53,7 +53,13 @@ static ULONG WINAPI IDirect3DSurface9Impl_AddRef(LPDIRECT3DSURFACE9 iface) {
} else {
/* No container, handle our own refcounting */
ULONG ref = InterlockedIncrement(&This->ref);
- if(ref == 1 && This->parentDevice) IDirect3DDevice9Ex_AddRef(This->parentDevice);
+ if (ref == 1)
+ {
+ if (This->parentDevice) IDirect3DDevice9Ex_AddRef(This->parentDevice);
+ wined3d_mutex_lock();
+ IWineD3DSurface_AddRef(This->wineD3DSurface);
+ wined3d_mutex_unlock();
+ }
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
return ref;
@@ -77,13 +83,9 @@ static ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) {
if (ref == 0) {
if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice);
- if (!This->isImplicit) {
- wined3d_mutex_lock();
- IWineD3DSurface_Release(This->wineD3DSurface);
- wined3d_mutex_unlock();
-
- HeapFree(GetProcessHeap(), 0, This);
- }
+ wined3d_mutex_lock();
+ IWineD3DSurface_Release(This->wineD3DSurface);
+ wined3d_mutex_unlock();
}
return ref;
@@ -322,6 +324,16 @@ static const IDirect3DSurface9Vtbl Direct3DSurface9_Vtbl =
IDirect3DSurface9Impl_ReleaseDC
};
+static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops =
+{
+ surface_wined3d_object_destroyed,
+};
+
HRESULT surface_init(IDirect3DSurface9Impl *surface, IDirect3DDevice9Impl *device,
UINT width, UINT height, D3DFORMAT format, BOOL lockable, BOOL discard, UINT level,
DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
@@ -357,7 +369,8 @@ HRESULT surface_init(IDirect3DSurface9Impl *surface, IDirect3DDevice9Impl *devic
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateSurface(device->WineD3DDevice, width, height, wined3dformat_from_d3dformat(format),
lockable, discard, level, &surface->wineD3DSurface, usage & WINED3DUSAGE_MASK, (WINED3DPOOL)pool,
- multisample_type, multisample_quality, SURFACE_OPENGL, (IUnknown *)surface);
+ multisample_type, multisample_quality, SURFACE_OPENGL, (IUnknown *)surface,
+ &d3d9_surface_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c
index fb66807..e63e343 100644
--- a/dlls/d3d9/swapchain.c
+++ b/dlls/d3d9/swapchain.c
@@ -63,7 +63,7 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface)
if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice);
if (!This->isImplicit) {
wined3d_mutex_lock();
- IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D9CB_DestroyRenderTarget);
+ IWineD3DSwapChain_Destroy(This->wineD3DSwapChain);
wined3d_mutex_unlock();
HeapFree(GetProcessHeap(), 0, This);
diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c
index 7db7037..ea1cde8 100644
--- a/dlls/d3d9/texture.c
+++ b/dlls/d3d9/texture.c
@@ -60,7 +60,7 @@ static ULONG WINAPI IDirect3DTexture9Impl_Release(LPDIRECT3DTEXTURE9 iface) {
if (ref == 0) {
wined3d_mutex_lock();
- IWineD3DTexture_Destroy(This->wineD3DTexture, D3D9CB_DestroySurface);
+ IWineD3DTexture_Destroy(This->wineD3DTexture);
wined3d_mutex_unlock();
IDirect3DDevice9Ex_Release(This->parentDevice);
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 9f9a157..98c30b4 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -62,6 +62,13 @@ static const DDDEVICEIDENTIFIER2 deviceidentifier =
0
};
+static void STDMETHODCALLTYPE ddraw_null_wined3d_object_destroyed(void *parent) {}
+
+static const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops =
+{
+ ddraw_null_wined3d_object_destroyed,
+};
+
/*****************************************************************************
* IUnknown Methods
*****************************************************************************/
@@ -1655,11 +1662,9 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
IDirectDrawSurfaceImpl *surfImpl = (IDirectDrawSurfaceImpl *)surf;
IDirectDrawImpl *This = surfImpl->ddraw;
IUnknown *Parent;
- IParentImpl *parImpl = NULL;
IWineD3DSurface *wineD3DSurface;
IWineD3DSwapChain *swapchain;
HRESULT hr;
- void *tmp;
IWineD3DClipper *clipper = NULL;
WINED3DSURFACE_DESC Desc;
@@ -1683,18 +1688,6 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
swapchain = surfImpl->wineD3DSwapChain;
surfImpl->wineD3DSwapChain = NULL;
wineD3DSurface = surfImpl->WineD3DSurface;
- IWineD3DSurface_GetParent(wineD3DSurface, &Parent);
- IUnknown_Release(Parent); /* For the getParent */
-
- /* Is the parent an IParent interface? */
- if(IUnknown_QueryInterface(Parent, &IID_IParent, &tmp) == S_OK)
- {
- /* It is a IParent interface! */
- IUnknown_Release(Parent); /* For the QueryInterface */
- parImpl = (IParentImpl *)Parent;
- /* Release the reference the parent interface is holding */
- IWineD3DSurface_Release(wineD3DSurface);
- }
/* get the clipper */
IWineD3DSurface_GetClipper(wineD3DSurface, &clipper);
@@ -1711,34 +1704,19 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
Width = Desc.width;
Height = Desc.height;
- if(swapchain) {
- /* If there's a swapchain, it owns the IParent interface. Create a new one for the
- * new surface
- */
- parImpl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parImpl));
- parImpl->lpVtbl = &IParent_Vtbl;
- parImpl->ref = 1;
-
- Parent = (IUnknown *) parImpl;
- }
+ IWineD3DSurface_GetParent(wineD3DSurface, &Parent);
/* Create the new surface */
hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, Width, Height, Format,
- TRUE /* Lockable */, FALSE /* Discard */, surfImpl->mipmap_level, &surfImpl->WineD3DSurface,
- Usage, Pool, MultiSampleType, MultiSampleQuality, This->ImplType, Parent);
+ TRUE /* Lockable */, FALSE /* Discard */, surfImpl->mipmap_level, &surfImpl->WineD3DSurface, Usage, Pool,
+ MultiSampleType, MultiSampleQuality, This->ImplType, Parent, &ddraw_null_wined3d_parent_ops);
+ IUnknown_Release(Parent);
if(hr != D3D_OK)
return hr;
IWineD3DSurface_SetClipper(surfImpl->WineD3DSurface, clipper);
- /* Update the IParent if it exists */
- if(parImpl)
- {
- parImpl->child = (IUnknown *) surfImpl->WineD3DSurface;
- /* Add a reference for the IParent */
- IWineD3DSurface_AddRef(surfImpl->WineD3DSurface);
- }
/* TODO: Copy the surface content, except for render targets */
/* If there's a swapchain, it owns the wined3d surfaces. So Destroy
@@ -1787,7 +1765,7 @@ IDirectDrawImpl_RecreateAllSurfaces(IDirectDrawImpl *This)
/* Should happen almost never */
FIXME("(%p) Switching to non-opengl surfaces with d3d started. Is this a bug?\n", This);
/* Shutdown d3d */
- IWineD3DDevice_Uninit3D(This->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain);
+ IWineD3DDevice_Uninit3D(This->wineD3DDevice, D3D7CB_DestroySwapChain);
}
/* Contrary: D3D starting is handled by the caller, because it knows the render target */
@@ -1806,15 +1784,6 @@ ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
return IUnknown_Release(swapChainParent);
}
-ULONG WINAPI D3D7CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface) {
- IUnknown* surfaceParent;
- TRACE("(%p) call back\n", pSurface);
-
- IWineD3DSurface_GetParent(pSurface, &surfaceParent);
- IUnknown_Release(surfaceParent);
- return IUnknown_Release(surfaceParent);
-}
-
/*****************************************************************************
* IDirectDrawImpl_CreateNewSurface
*
@@ -1841,8 +1810,6 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
DWORD Usage = 0;
WINED3DSURFTYPE ImplType = This->ImplType;
WINED3DSURFACE_DESC Desc;
- IUnknown *Parent;
- IParentImpl *parImpl = NULL;
WINED3DPOOL Pool = WINED3DPOOL_DEFAULT;
if (TRACE_ON(ddraw))
@@ -1990,34 +1957,11 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
/* A trace message for debugging */
TRACE("(%p) Created IDirectDrawSurface implementation structure at %p\n", This, *ppSurf);
- if(pDDSD->ddsCaps.dwCaps & ( DDSCAPS_PRIMARYSURFACE | DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE) )
- {
- /* Render targets and textures need a IParent interface,
- * because WineD3D will destroy them when the swapchain
- * is released
- */
- parImpl = HeapAlloc(GetProcessHeap(), 0, sizeof(IParentImpl));
- if(!parImpl)
- {
- ERR("Out of memory when allocating memory for a IParent implementation\n");
- return DDERR_OUTOFMEMORY;
- }
- parImpl->ref = 1;
- parImpl->lpVtbl = &IParent_Vtbl;
- Parent = (IUnknown *)parImpl;
- TRACE("Using IParent interface %p as parent\n", parImpl);
- }
- else
- {
- /* Use the surface as parent */
- Parent = (IUnknown *)*ppSurf;
- TRACE("Using Surface interface %p as parent\n", *ppSurf);
- }
-
/* Now create the WineD3D Surface */
hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, pDDSD->dwWidth, pDDSD->dwHeight, Format,
TRUE /* Lockable */, FALSE /* Discard */, level, &(*ppSurf)->WineD3DSurface,
- Usage, Pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, ImplType, Parent);
+ Usage, Pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, ImplType,
+ (IUnknown *)*ppSurf, &ddraw_null_wined3d_parent_ops);
if(hr != D3D_OK)
{
@@ -2025,16 +1969,6 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
return hr;
}
- /* Set the child of the parent implementation if it exists */
- if(parImpl)
- {
- parImpl->child = (IUnknown *) (*ppSurf)->WineD3DSurface;
- /* The IParent releases the WineD3DSurface, and
- * the ddraw surface does that too. Hold a reference
- */
- IWineD3DSurface_AddRef((*ppSurf)->WineD3DSurface);
- }
-
/* Increase the surface counter, and attach the surface */
InterlockedIncrement(&This->surfaces);
list_add_head(&This->surface_list, &(*ppSurf)->surface_list_entry);
@@ -3032,9 +2966,7 @@ IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This,
{
ERR("Error allocating an array for the converted vertex decls\n");
This->declArraySize = 0;
- hr = IWineD3DDevice_Uninit3D(This->wineD3DDevice,
- D3D7CB_DestroyDepthStencilSurface,
- D3D7CB_DestroySwapChain);
+ hr = IWineD3DDevice_Uninit3D(This->wineD3DDevice, D3D7CB_DestroySwapChain);
return E_OUTOFMEMORY;
}
@@ -3436,6 +3368,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
/* Return the surface */
*surface = surf->WineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *surface, surf);
@@ -3472,6 +3405,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDevice
/* TODO: Return failure if the dimensions do not match, but this shouldn't happen */
*surface = target->WineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
target->isRenderTarget = TRUE;
TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *surface, d3d_surface);
@@ -3484,7 +3418,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
DWORD multisample_quality, BOOL discard, IWineD3DSurface **surface)
{
struct IDirectDrawImpl *This = ddraw_from_device_parent(iface);
- /* Create a Depth Stencil surface to make WineD3D happy */
+ IDirectDrawSurfaceImpl *ddraw_surface;
DDSURFACEDESC2 ddsd;
HRESULT hr;
@@ -3512,8 +3446,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
}
This->depthstencil = TRUE;
- hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)This,
- &ddsd, (IDirectDrawSurface7 **)&This->DepthStencilBuffer, NULL);
+ hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)This, &ddsd, (IDirectDrawSurface7 **)&ddraw_surface, NULL);
This->depthstencil = FALSE;
if(FAILED(hr))
{
@@ -3521,7 +3454,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
return hr;
}
- *surface = This->DepthStencilBuffer->WineD3DSurface;
+ *surface = ddraw_surface->WineD3DSurface;
+ IWineD3DSurface_AddRef(*surface);
+ IDirectDrawSurface7_Release((IDirectDrawSurface7 *)ddraw_surface);
return D3D_OK;
}
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 72dfff5..7c2883e 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -79,8 +79,6 @@ typedef struct IParentImpl IParentImpl;
/* Callbacks for implicit object destruction */
extern ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain);
-extern ULONG WINAPI D3D7CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface);
-
/* Global critical section */
extern CRITICAL_SECTION ddraw_cs;
@@ -115,7 +113,6 @@ struct IDirectDrawImpl
/* WineD3D linkage */
IWineD3D *wineD3D;
IWineD3DDevice *wineD3DDevice;
- IDirectDrawSurfaceImpl *DepthStencilBuffer;
BOOL d3d_initialized;
/* Misc ddraw fields */
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 6908a62..b7eed02 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -748,7 +748,6 @@ DestroyCallback(IDirectDrawSurface7 *surf,
void *context)
{
IDirectDrawSurfaceImpl *Impl = (IDirectDrawSurfaceImpl *)surf;
- IDirectDrawImpl *ddraw = context;
ULONG ref;
ref = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */
@@ -760,9 +759,6 @@ DestroyCallback(IDirectDrawSurface7 *surf,
*/
if( (!Impl->is_complex_root) || (Impl->first_attached != Impl) )
return DDENUMRET_OK;
- /* Skip our depth stencil surface, it will be released with the render target */
- if( Impl == ddraw->DepthStencilBuffer)
- return DDENUMRET_OK;
/* Destroy the surface */
while(ref) ref = IDirectDrawSurface7_Release(surf);
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index b59d01a..24246c7 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -159,6 +159,13 @@ IDirectDrawSurfaceImpl_AddRef(IDirectDrawSurface7 *iface)
IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
+ if (refCount == 1 && This->WineD3DSurface)
+ {
+ EnterCriticalSection(&ddraw_cs);
+ IWineD3DSurface_AddRef(This->WineD3DSurface);
+ LeaveCriticalSection(&ddraw_cs);
+ }
+
TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
return refCount;
}
@@ -320,7 +327,7 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface)
HeapFree(GetProcessHeap(), 0, ddraw->decls);
ddraw->numConvertedDecls = 0;
- if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain) != D3D_OK)
+ if (FAILED(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice, D3D7CB_DestroySwapChain)))
{
/* Not good */
ERR("(%p) Failed to uninit 3D\n", This);
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 8b4fe75..a76cb12 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -56,18 +56,6 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_AddRef(IDXGISwapChain *iface)
return refcount;
}
-static ULONG STDMETHODCALLTYPE destroy_surface(IWineD3DSurface *surface)
-{
- IDXGISurface *dxgi_surface;
-
- TRACE("surface %p\n", surface);
-
- IWineD3DSurface_GetParent(surface, (IUnknown **)&dxgi_surface);
- IDXGISurface_Release(dxgi_surface);
-
- return IDXGISurface_Release(dxgi_surface);
-}
-
static ULONG STDMETHODCALLTYPE destroy_swapchain(IWineD3DSwapChain *swapchain)
{
TRACE("swapchain %p\n", swapchain);
@@ -96,7 +84,7 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface)
}
else
{
- hr = IWineD3DDevice_Uninit3D(wined3d_device, destroy_surface, destroy_swapchain);
+ hr = IWineD3DDevice_Uninit3D(wined3d_device, destroy_swapchain);
IWineD3DDevice_Release(wined3d_device);
if (FAILED(hr))
{
diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c
index 4b6900a..eb01e96 100644
--- a/dlls/wined3d/cubetexture.c
+++ b/dlls/wined3d/cubetexture.c
@@ -110,7 +110,7 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3
*dirty = FALSE;
}
-static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This, D3DCB_DESTROYSURFACEFN surface_destroy_cb)
+static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This)
{
unsigned int i, j;
@@ -130,7 +130,7 @@ static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This, D3DCB_DESTROYSURF
surface_set_texture_name(surface, 0, FALSE);
surface_set_texture_target(surface, 0);
IWineD3DSurface_SetContainer(surface, NULL);
- surface_destroy_cb(surface);
+ IWineD3DSurface_Release(surface);
}
}
}
@@ -237,7 +237,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN
{
FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr);
texture->surfaces[j][i] = NULL;
- cubetexture_cleanup(texture, D3DCB_DefaultDestroySurface);
+ cubetexture_cleanup(texture);
return hr;
}
@@ -289,7 +289,7 @@ static ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface)
TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
ref = InterlockedDecrement(&This->resource.ref);
if (ref == 0) {
- IWineD3DCubeTexture_Destroy(iface, D3DCB_DefaultDestroySurface);
+ IWineD3DCubeTexture_Destroy(iface);
}
return ref;
}
@@ -432,10 +432,11 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_IsCondNP2(IWineD3DCubeTexture *iface)
/* *******************************************
IWineD3DCubeTexture IWineD3DCubeTexture parts follow
******************************************* */
-static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
+static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface)
+{
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
- cubetexture_cleanup(This, D3DCB_DestroySurface);
+ cubetexture_cleanup(This);
/* finally delete the object */
HeapFree(GetProcessHeap(), 0, This);
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index aab45a0..a30a9b1 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -901,7 +901,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Width, UINT Height,
WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IWineD3DSurface **ppSurface,
DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,
- WINED3DSURFTYPE Impl, IUnknown *parent)
+ WINED3DSURFTYPE Impl, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DSurfaceImpl *object;
@@ -924,7 +924,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UI
}
hr = surface_init(object, Impl, This->surface_alignment, Width, Height, Level, Lockable,
- Discard, MultiSample, MultisampleQuality, This, Usage, Format, Pool, parent);
+ Discard, MultiSample, MultisampleQuality, This, Usage, Format, Pool, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize surface, returning %#x.\n", hr);
@@ -1343,7 +1343,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface,
HDC hDc;
IWineD3DSwapChainImpl *object; /** NOTE: impl ref allowed since this is a create function **/
HRESULT hr;
- IUnknown *bufferParent;
BOOL displaymode_set = FALSE;
WINED3DDISPLAYMODE Mode;
const struct GlPixelFormatDesc *format_desc;
@@ -1604,26 +1603,14 @@ error:
if (object->backBuffer) {
UINT i;
for(i = 0; i < object->presentParms.BackBufferCount; i++) {
- if(object->backBuffer[i]) {
- IWineD3DSurface_GetParent(object->backBuffer[i], &bufferParent);
- IUnknown_Release(bufferParent); /* once for the get parent */
- if (IUnknown_Release(bufferParent) > 0) {
- FIXME("(%p) Something's still holding the back buffer\n",This);
- }
- }
+ if (object->backBuffer[i]) IWineD3DSurface_Release(object->backBuffer[i]);
}
HeapFree(GetProcessHeap(), 0, object->backBuffer);
object->backBuffer = NULL;
}
if(object->context && object->context[0])
DestroyContext(This, object->context[0]);
- if(object->frontBuffer) {
- IWineD3DSurface_GetParent(object->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);
- }
- }
+ if (object->frontBuffer) IWineD3DSurface_Release(object->frontBuffer);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
@@ -1983,7 +1970,8 @@ static void IWineD3DDeviceImpl_LoadLogo(IWineD3DDeviceImpl *This, const char *fi
}
hr = IWineD3DDevice_CreateSurface((IWineD3DDevice *) This, bm.bmWidth, bm.bmHeight, WINED3DFMT_R5G6B5, TRUE,
- FALSE, 0, &This->logo_surface, 0, WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, SURFACE_OPENGL, NULL);
+ FALSE, 0, &This->logo_surface, 0, WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, SURFACE_OPENGL,
+ NULL, &wined3d_null_parent_ops);
if(FAILED(hr)) {
ERR("Wine logo requested, but failed to create surface\n");
goto out;
@@ -2287,7 +2275,9 @@ static HRESULT WINAPI device_unload_resource(IWineD3DResource *resource, void *c
return WINED3D_OK;
}
-static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyDepthStencilSurface, D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain) {
+static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
+ D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain)
+{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
int sampler;
UINT i;
@@ -2399,7 +2389,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D
This->render_targets[0] = NULL;
if (This->auto_depth_stencil_buffer) {
- if(D3DCB_DestroyDepthStencilSurface(This->auto_depth_stencil_buffer) > 0) {
+ if (IWineD3DSurface_Release(This->auto_depth_stencil_buffer) > 0)
+ {
FIXME("(%p) Something's still holding the auto depth stencil buffer\n", This);
}
This->auto_depth_stencil_buffer = NULL;
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 1ac8b11..6b92c0c 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -6,6 +6,7 @@
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -4316,16 +4317,6 @@ static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent
return WINED3D_OK;
}
-ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) {
- IUnknown* surfaceParent;
- TRACE("(%p) call back\n", pSurface);
-
- /* Now, release the parent, which will take care of cleaning up the surface for us */
- IWineD3DSurface_GetParent(pSurface, &surfaceParent);
- IUnknown_Release(surfaceParent);
- return IUnknown_Release(surfaceParent);
-}
-
ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
IUnknown* volumeParent;
TRACE("(%p) call back\n", pVolume);
@@ -4830,3 +4821,10 @@ const IWineD3DVtbl IWineD3D_Vtbl =
IWineD3DImpl_GetDeviceCaps,
IWineD3DImpl_CreateDevice
};
+
+static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
+
+const struct wined3d_parent_ops wined3d_null_parent_ops =
+{
+ wined3d_null_wined3d_object_destroyed,
+};
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index a8f6c4b..c3aff86 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -10,6 +10,7 @@
* Copyright 2006-2008 Stefan Dösinger for CodeWeavers
* Copyright 2007-2008 Henri Verbeet
* Copyright 2006-2008 Roderick Colenbrander
+ * Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -122,7 +123,7 @@ UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT al
HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
- WINED3DPOOL pool, IUnknown *parent)
+ WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &GLINFO_LOCATION);
@@ -166,6 +167,8 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type,
return hr;
}
+ surface->parent_ops = parent_ops;
+
/* "Standalone" surface. */
IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL);
@@ -727,6 +730,7 @@ static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
if (!ref)
{
surface_cleanup(This);
+ This->parent_ops->wined3d_object_destroyed(This->resource.parent);
TRACE("(%p) Released.\n", This);
HeapFree(GetProcessHeap(), 0, This);
diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c
index c45533b..51a80a5 100644
--- a/dlls/wined3d/surface_base.c
+++ b/dlls/wined3d/surface_base.c
@@ -10,6 +10,7 @@
* Copyright 2006-2008 Stefan Dösinger for CodeWeavers
* Copyright 2007 Henri Verbeet
* Copyright 2006-2007 Roderick Colenbrander
+ * Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -799,7 +800,8 @@ static IWineD3DSurfaceImpl *surface_convert_format(IWineD3DSurfaceImpl *source,
IWineD3DDevice_CreateSurface((IWineD3DDevice *)source->resource.wineD3DDevice, source->currentDesc.Width,
source->currentDesc.Height, to_fmt, TRUE /* lockable */, TRUE /* discard */, 0 /* level */, &ret,
0 /* usage */, WINED3DPOOL_SCRATCH, WINED3DMULTISAMPLE_NONE /* TODO: Multisampled conversion */,
- 0 /* MultiSampleQuality */, IWineD3DSurface_GetImplType((IWineD3DSurface *) source), NULL /* parent */);
+ 0 /* MultiSampleQuality */, IWineD3DSurface_GetImplType((IWineD3DSurface *) source),
+ NULL /* parent */, &wined3d_null_parent_ops);
if(!ret) {
ERR("Failed to create a destination surface for conversion\n");
return NULL;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index d8d3733..38cdf46 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -36,7 +36,8 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
/*IWineD3DSwapChain parts follow: */
-static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderTarget) {
+static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
+{
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
WINED3DDISPLAYMODE mode;
unsigned int i;
@@ -50,9 +51,9 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
if (This->frontBuffer)
{
IWineD3DSurface_SetContainer(This->frontBuffer, 0);
- if (D3DCB_DestroyRenderTarget(This->frontBuffer))
+ if (IWineD3DSurface_Release(This->frontBuffer))
{
- FIXME("(%p) Something's still holding the front buffer (%p).\n",
+ WARN("(%p) Something's still holding the front buffer (%p).\n",
This, This->frontBuffer);
}
This->frontBuffer = NULL;
@@ -65,8 +66,8 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
while (i--)
{
IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
- if (D3DCB_DestroyRenderTarget(This->backBuffer[i]))
- FIXME("(%p) Something's still holding back buffer %u (%p).\n",
+ if (IWineD3DSurface_Release(This->backBuffer[i]))
+ WARN("(%p) Something's still holding back buffer %u (%p).\n",
This, i, This->backBuffer[i]);
}
HeapFree(GetProcessHeap(), 0, This->backBuffer);
diff --git a/dlls/wined3d/swapchain_base.c b/dlls/wined3d/swapchain_base.c
index 7272c95..31b9d07 100644
--- a/dlls/wined3d/swapchain_base.c
+++ b/dlls/wined3d/swapchain_base.c
@@ -59,7 +59,7 @@ ULONG WINAPI IWineD3DBaseSwapChainImpl_Release(IWineD3DSwapChain *iface) {
refCount = InterlockedDecrement(&This->ref);
TRACE("(%p) : ReleaseRef to %d\n", This, refCount);
if (refCount == 0) {
- IWineD3DSwapChain_Destroy(iface, D3DCB_DefaultDestroySurface);
+ IWineD3DSwapChain_Destroy(iface);
}
return refCount;
}
diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c
index 5968201..f4909bc 100644
--- a/dlls/wined3d/swapchain_gdi.c
+++ b/dlls/wined3d/swapchain_gdi.c
@@ -27,7 +27,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(fps);
-static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderback) {
+static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
+{
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
WINED3DDISPLAYMODE mode;
@@ -38,8 +39,9 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
/* release the ref to the front and back buffer parents */
if(This->frontBuffer) {
IWineD3DSurface_SetContainer(This->frontBuffer, 0);
- if(D3DCB_DestroyRenderback(This->frontBuffer) > 0) {
- FIXME("(%p) Something's still holding the front buffer\n",This);
+ if (IWineD3DSurface_Release(This->frontBuffer) > 0)
+ {
+ WARN("(%p) Something's still holding the front buffer\n",This);
}
}
@@ -47,8 +49,9 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
UINT i;
for(i = 0; i < This->presentParms.BackBufferCount; i++) {
IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
- if(D3DCB_DestroyRenderback(This->backBuffer[i]) > 0) {
- FIXME("(%p) Something's still holding the back buffer\n",This);
+ if (IWineD3DSurface_Release(This->backBuffer[i]) > 0)
+ {
+ WARN("(%p) Something's still holding the back buffer\n",This);
}
}
HeapFree(GetProcessHeap(), 0, This->backBuffer);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index dd8f32e..ddca452 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -100,7 +100,7 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG
*dirty = FALSE;
}
-static void texture_cleanup(IWineD3DTextureImpl *This, D3DCB_DESTROYSURFACEFN surface_destroy_cb)
+static void texture_cleanup(IWineD3DTextureImpl *This)
{
unsigned int i;
@@ -116,7 +116,7 @@ static void texture_cleanup(IWineD3DTextureImpl *This, D3DCB_DESTROYSURFACEFN su
surface_set_texture_name(This->surfaces[i], 0, FALSE);
surface_set_texture_target(This->surfaces[i], 0);
IWineD3DSurface_SetContainer(This->surfaces[i], 0);
- surface_destroy_cb(This->surfaces[i]);
+ IWineD3DSurface_Release(This->surfaces[i]);
}
}
@@ -266,7 +266,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT
{
FIXME("Failed to create surface %p, hr %#x\n", texture, hr);
texture->surfaces[i] = NULL;
- texture_cleanup(texture, D3DCB_DefaultDestroySurface);
+ texture_cleanup(texture);
return hr;
}
@@ -319,7 +319,7 @@ static ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) {
TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
ref = InterlockedDecrement(&This->resource.ref);
if (ref == 0) {
- IWineD3DTexture_Destroy(iface, D3DCB_DefaultDestroySurface);
+ IWineD3DTexture_Destroy(iface);
}
return ref;
}
@@ -480,10 +480,11 @@ static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture *iface) {
/* *******************************************
IWineD3DTexture IWineD3DTexture parts follow
******************************************* */
-static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
+static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface)
+{
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
- texture_cleanup(This, D3DCB_DestroySurface);
+ texture_cleanup(This);
/* free the object */
HeapFree(GetProcessHeap(), 0, This);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b65c0b5..cb6fa84 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1337,8 +1337,6 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *
#define WINE_D3D9_CAPABLE(gl_info) WINE_D3D8_CAPABLE(gl_info) && (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[ARB_VERTEX_SHADER])
/* Default callbacks for implicit object destruction */
-extern ULONG WINAPI D3DCB_DefaultDestroySurface(IWineD3DSurface *pSurface) DECLSPEC_HIDDEN;
-
extern ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pSurface) DECLSPEC_HIDDEN;
/*****************************************************************************
@@ -1467,6 +1465,7 @@ struct ffp_frag_desc
};
extern const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions DECLSPEC_HIDDEN;
+extern const struct wined3d_parent_ops wined3d_null_parent_ops DECLSPEC_HIDDEN;
void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings,
BOOL ignore_textype) DECLSPEC_HIDDEN;
@@ -1958,6 +1957,7 @@ struct IWineD3DSurfaceImpl
IWineD3DResourceClass resource;
/* IWineD3DSurface fields */
+ const struct wined3d_parent_ops *parent_ops;
IWineD3DBase *container;
WINED3DSURFACET_DESC currentDesc;
IWineD3DPaletteImpl *palette; /* D3D7 style palette handling */
@@ -2023,7 +2023,7 @@ void surface_gdi_cleanup(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN;
HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
- WINED3DPOOL pool, IUnknown *parent) DECLSPEC_HIDDEN;
+ WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
/* Predeclare the shared Surface functions */
HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface,
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index 77e1fb2..46d2335 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -2143,6 +2143,11 @@ struct wined3d_shader_signature
char *string_data;
};
+struct wined3d_parent_ops
+{
+ void (*wined3d_object_destroyed)(void *parent);
+};
+
interface IWineD3DResource;
interface IWineD3DSurface;
interface IWineD3DVolume;
@@ -2210,7 +2215,6 @@ interface IWineD3DDeviceParent : IUnknown
[out] IWineD3DSwapChain **swapchain
);
}
-typedef ULONG (*D3DCB_DESTROYSURFACEFN)(IWineD3DSurface *pSurface);
typedef ULONG (*D3DCB_DESTROYVOLUMEFN)(IWineD3DVolume *pVolume);
typedef ULONG (*D3DCB_DESTROYSWAPCHAINFN)(IWineD3DSwapChain *pSwapChain);
typedef HRESULT (*D3DCB_ENUMRESOURCES)(IWineD3DResource *resource, void *pData);
@@ -2619,7 +2623,6 @@ interface IWineD3DBaseTexture : IWineD3DResource
interface IWineD3DTexture : IWineD3DBaseTexture
{
void Destroy(
- [in] D3DCB_DESTROYSURFACEFN destroy_surface_callback
);
HRESULT GetLevelDesc(
[in] UINT level,
@@ -2651,7 +2654,6 @@ interface IWineD3DTexture : IWineD3DBaseTexture
interface IWineD3DCubeTexture : IWineD3DBaseTexture
{
void Destroy(
- [in] D3DCB_DESTROYSURFACEFN destroy_surface_callback
);
HRESULT GetLevelDesc(
[in] UINT level,
@@ -2773,7 +2775,6 @@ interface IWineD3DQuery : IWineD3DBase
interface IWineD3DSwapChain : IWineD3DBase
{
void Destroy(
- [in] D3DCB_DESTROYSURFACEFN destroy_surface_callback
);
HRESULT GetDevice(
[out] IWineD3DDevice **device
@@ -2930,7 +2931,8 @@ interface IWineD3DDevice : IWineD3DBase
[in] WINED3DMULTISAMPLE_TYPE multisample_type,
[in] DWORD multisample_quality,
[in] WINED3DSURFTYPE surface_type,
- [in] IUnknown *parent
+ [in] IUnknown *parent,
+ [in] const struct wined3d_parent_ops *parent_ops
);
HRESULT CreateRendertargetView(
[in] IWineD3DResource *resource,
@@ -3024,7 +3026,6 @@ interface IWineD3DDevice : IWineD3DBase
[in] WINED3DPRESENT_PARAMETERS *present_parameters
);
HRESULT Uninit3D(
- [in] D3DCB_DESTROYSURFACEFN destroy_surface_callback,
[in] D3DCB_DESTROYSWAPCHAINFN destroy_swapchain_callback
);
HRESULT UninitGDI(
--
1.6.0.6
More information about the wine-patches
mailing list