ddraw: Add iface count for IDirectSurfaceImpl.
Ričardas Barkauskas
rbarkauskas at codeweavers.com
Tue Jun 14 08:17:44 CDT 2011
---
dlls/ddraw/ddraw_private.h | 2 +-
dlls/ddraw/surface.c | 67 ++++++++++++++++++++++++++++++--------------
2 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 42c1f13..9c1bc0c 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -161,7 +161,7 @@ struct IDirectDrawSurfaceImpl
const IDirect3DTexture2Vtbl *IDirect3DTexture2_vtbl;
const IDirect3DTextureVtbl *IDirect3DTexture_vtbl;
- LONG ref;
+ LONG ref, numIfaces;
IUnknown *ifaceToRelease;
int version;
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 504e107..1b3fa61 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -215,6 +215,22 @@ static HRESULT WINAPI d3d_texture1_QueryInterface(IDirect3DTexture *iface, REFII
return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object);
}
+static void ddraw_surface_add_iface(IDirectDrawSurfaceImpl *This)
+{
+ ULONG refCount = InterlockedIncrement(&This->numIfaces);
+ TRACE("%p increasing iface count to %u.\n", This, refCount);
+
+ if (refCount == 1)
+ {
+ EnterCriticalSection(&ddraw_cs);
+ if (This->wined3d_surface)
+ wined3d_surface_incref(This->wined3d_surface);
+ if (This->wined3d_texture)
+ wined3d_texture_incref(This->wined3d_texture);
+ LeaveCriticalSection(&ddraw_cs);
+ }
+}
+
/*****************************************************************************
* IDirectDrawSurface7::AddRef
*
@@ -233,12 +249,7 @@ static ULONG WINAPI ddraw_surface7_AddRef(IDirectDrawSurface7 *iface)
if (refCount == 1)
{
- EnterCriticalSection(&ddraw_cs);
- if (This->wined3d_surface)
- wined3d_surface_incref(This->wined3d_surface);
- if (This->wined3d_texture)
- wined3d_texture_incref(This->wined3d_texture);
- LeaveCriticalSection(&ddraw_cs);
+ ddraw_surface_add_iface(This);
}
return refCount;
@@ -317,8 +328,8 @@ void ddraw_surface_destroy(IDirectDrawSurfaceImpl *This)
{
TRACE("surface %p.\n", This);
- /* Check the refcount and give a warning */
- if(This->ref > 1)
+ /* Check the iface count and give a warning */
+ if(This->numIfaces > 1)
{
/* This can happen when a complex surface is destroyed,
* because the 2nd surface was addref()ed when the app
@@ -423,6 +434,31 @@ static void ddraw_surface_cleanup(IDirectDrawSurfaceImpl *surface)
IUnknown_Release(ifaceToRelease);
}
+static void ddraw_surface_release_iface(IDirectDrawSurfaceImpl *This)
+{
+ ULONG ref = InterlockedDecrement(&This->numIfaces);
+ TRACE("%p decreasing iface count to %u.\n", This, ref);
+
+ if (ref == 0)
+ {
+ /* Complex attached surfaces are destroyed implicitly when the root is released */
+ EnterCriticalSection(&ddraw_cs);
+ if(!This->is_complex_root)
+ {
+ WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This);
+ LeaveCriticalSection(&ddraw_cs);
+ return;
+ }
+ if (This->wined3d_texture) /* If it's a texture, destroy the wined3d texture. */
+ wined3d_texture_decref(This->wined3d_texture);
+ else
+ ddraw_surface_cleanup(This);
+ LeaveCriticalSection(&ddraw_cs);
+ }
+
+ return;
+}
+
/*****************************************************************************
* IDirectDrawSurface7::Release
*
@@ -461,19 +497,7 @@ static ULONG WINAPI ddraw_surface7_Release(IDirectDrawSurface7 *iface)
if (ref == 0)
{
- /* Complex attached surfaces are destroyed implicitly when the root is released */
- EnterCriticalSection(&ddraw_cs);
- if(!This->is_complex_root)
- {
- WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This);
- LeaveCriticalSection(&ddraw_cs);
- return ref;
- }
- if (This->wined3d_texture) /* If it's a texture, destroy the wined3d texture. */
- wined3d_texture_decref(This->wined3d_texture);
- else
- ddraw_surface_cleanup(This);
- LeaveCriticalSection(&ddraw_cs);
+ ddraw_surface_release_iface(This);
}
return ref;
@@ -5003,6 +5027,7 @@ HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddr
surface->IDirect3DTexture2_vtbl = &d3d_texture2_vtbl;
surface->IDirect3DTexture_vtbl = &d3d_texture1_vtbl;
surface->ref = 1;
+ surface->numIfaces = 1;
surface->version = 7;
surface->ddraw = ddraw;
--
1.7.5.3
------=_20110614091328_49286--
More information about the wine-patches
mailing list