ddraw: Separate IDirectDrawSurface2 reference count.
Ričardas Barkauskas
rbarkauskas at codeweavers.com
Tue Jun 14 08:18:13 CDT 2011
---
dlls/ddraw/ddraw_private.h | 2 +-
dlls/ddraw/main.c | 4 +++-
dlls/ddraw/surface.c | 28 ++++++++++++++++++++++------
dlls/ddraw/tests/dsurface.c | 12 ++++++------
4 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 9c1bc0c..4bc8953 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, numIfaces;
+ LONG ref, ref2, numIfaces;
IUnknown *ifaceToRelease;
int version;
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 7a693ee..6a11384 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -755,7 +755,7 @@ DestroyCallback(IDirectDrawSurface7 *surf,
ULONG ref;
ref = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */
- WARN("Surface %p has an reference count of %d\n", Impl, ref);
+ WARN("Surface %p has an reference counts of %d 2: %d\n", Impl, ref, Impl->ref2);
/* Skip surfaces which are attached somewhere or which are
* part of a complex compound. They will get released when destroying
@@ -766,6 +766,8 @@ DestroyCallback(IDirectDrawSurface7 *surf,
/* Destroy the surface */
while(ref) ref = IDirectDrawSurface7_Release(surf);
+ ref = Impl->ref2;
+ while(ref) ref = IDirectDrawSurface2_Release(&Impl->IDirectDrawSurface2_iface);
return DDENUMRET_OK;
}
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 923677f..25c5547 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -97,7 +97,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface,
}
else if (IsEqualGUID(riid, &IID_IDirectDrawSurface2))
{
- IUnknown_AddRef(iface);
+ IDirectDrawSurface2_AddRef(&This->IDirectDrawSurface2_iface);
*obj = &This->IDirectDrawSurface2_iface;
TRACE("(%p) returning IDirectDrawSurface2 interface at %p\n", This, *obj);
return S_OK;
@@ -274,9 +274,16 @@ static ULONG WINAPI ddraw_surface3_AddRef(IDirectDrawSurface3 *iface)
static ULONG WINAPI ddraw_surface2_AddRef(IDirectDrawSurface2 *iface)
{
IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface);
- TRACE("iface %p.\n", iface);
+ ULONG refCount = InterlockedIncrement(&This->ref2);
- return ddraw_surface7_AddRef(&This->IDirectDrawSurface7_iface);
+ TRACE("%p increasing refcount to %u.\n", This, refCount);
+
+ if (refCount == 1)
+ {
+ ddraw_surface_add_iface(This);
+ }
+
+ return refCount;
}
static ULONG WINAPI ddraw_surface1_AddRef(IDirectDrawSurface *iface)
@@ -335,7 +342,7 @@ void ddraw_surface_destroy(IDirectDrawSurfaceImpl *This)
* because the 2nd surface was addref()ed when the app
* called GetAttachedSurface
*/
- WARN("(%p): Destroying surface with refount %d\n", This, This->ref);
+ WARN("(%p): Destroying surface with refounts %d 2: %d\n", This, This->ref, This->ref2);
}
if (This->wined3d_surface)
@@ -522,9 +529,16 @@ static ULONG WINAPI ddraw_surface3_Release(IDirectDrawSurface3 *iface)
static ULONG WINAPI ddraw_surface2_Release(IDirectDrawSurface2 *iface)
{
IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface);
- TRACE("iface %p.\n", iface);
+ ULONG ref = InterlockedDecrement(&This->ref2);
- return ddraw_surface7_Release(&This->IDirectDrawSurface7_iface);
+ TRACE("%p decreasing refcount to %u.\n", This, ref);
+
+ if (ref == 0)
+ {
+ ddraw_surface_release_iface(This);
+ }
+
+ return ref;
}
static ULONG WINAPI ddraw_surface1_Release(IDirectDrawSurface *iface)
@@ -755,6 +769,8 @@ static HRESULT WINAPI ddraw_surface2_GetAttachedSurface(IDirectDrawSurface2 *ifa
}
attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
*attachment = &attachment_impl->IDirectDrawSurface2_iface;
+ ddraw_surface2_AddRef(*attachment);
+ ddraw_surface7_Release(attachment7);
return hr;
}
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index 7416c93..4a17bd0 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -1079,15 +1079,15 @@ static void IFaceRefCount(void)
IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
ref = getRefcount((IUnknown *) surf);
- todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
+ ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
ref = getRefcount((IUnknown *) surf2);
- todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
+ ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
ref = getRefcount((IUnknown *) surf2);
- todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref); /* Surf2's refcount should be 2 now, but surf should be 1 */
+ ok(ref == 2, "Refcount is %u, expected 2\n", ref); /* Surf2's refcount should be 2 now, but surf should be 1 */
ref = getRefcount((IUnknown *) surf);
- todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
+ ok(ref == 1, "Refcount is %u, expected 1\n", ref);
IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
ref = getRefcount((IUnknown *) surf4);
@@ -1137,10 +1137,10 @@ static void IFaceRefCount(void)
}
ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
- todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
+ ok(ref == 1, "Refcount is %u, expected 1\n", ref);
ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
- todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
+ ok(ref == 0, "Refcount is %u, expected 0\n", ref);
ref = IDirectDrawSurface4_Release(surf4);
todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
--
1.7.5.3
------=_20110614091547_48355--
More information about the wine-patches
mailing list