From e144f0f5c4d8b5f6aaadee75d1e4a3c5df00cd19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ri=C4=8Dardas=20Barkauskas?= Date: Tue, 21 Jun 2011 00:15:55 +0300 Subject: ddraw: Separate IDirectDrawSurface and IDirectDrawSurface7 reference counts. --- dlls/ddraw/ddraw.c | 19 +++++++++++++++++ dlls/ddraw/ddraw_private.h | 2 +- dlls/ddraw/device.c | 2 + dlls/ddraw/main.c | 10 +++++--- dlls/ddraw/surface.c | 47 ++++++++++++++++++++++++++++++++----------- dlls/ddraw/tests/dsurface.c | 10 ++++---- 6 files changed, 68 insertions(+), 22 deletions(-) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index d039388..34b4dbd 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -2074,6 +2074,8 @@ static HRESULT WINAPI ddraw3_GetGDISurface(IDirectDraw3 *iface, IDirectDrawSurfa } surface_impl = impl_from_IDirectDrawSurface7(surface7); *surface = &surface_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*surface); + IDirectDrawSurface7_Release(surface7); return hr; } @@ -2095,6 +2097,8 @@ static HRESULT WINAPI ddraw2_GetGDISurface(IDirectDraw2 *iface, IDirectDrawSurfa } surface_impl = impl_from_IDirectDrawSurface7(surface7); *surface = &surface_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*surface); + IDirectDrawSurface7_Release(surface7); return hr; } @@ -2116,6 +2120,8 @@ static HRESULT WINAPI ddraw1_GetGDISurface(IDirectDraw *iface, IDirectDrawSurfac } surface_impl = impl_from_IDirectDrawSurface7(surface7); *surface = &surface_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*surface); + IDirectDrawSurface7_Release(surface7); return hr; } @@ -2489,6 +2495,8 @@ static HRESULT WINAPI ddraw4_GetSurfaceFromDC(IDirectDraw4 *iface, HDC dc, surface_impl = impl_from_IDirectDrawSurface7(surface7); /* Tests say this is true */ *surface = (IDirectDrawSurface4 *)&surface_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(&surface_impl->IDirectDrawSurface_iface); + IDirectDrawSurface7_Release(surface7); return hr; } @@ -2514,6 +2522,8 @@ static HRESULT WINAPI ddraw3_GetSurfaceFromDC(IDirectDraw3 *iface, HDC dc, surface_impl = impl_from_IDirectDrawSurface7(surface7); *surface = &surface_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*surface); + IDirectDrawSurface7_Release(surface7); return hr; } @@ -3824,6 +3834,9 @@ static HRESULT CALLBACK EnumSurfacesCallbackThunk(IDirectDrawSurface7 *surface, IDirectDrawSurfaceImpl *surface_impl = impl_from_IDirectDrawSurface7(surface); struct surfacescallback_context *cbcontext = context; + IDirectDrawSurface_AddRef(&surface_impl->IDirectDrawSurface_iface); + IDirectDrawSurface7_Release(surface); + return cbcontext->func(&surface_impl->IDirectDrawSurface_iface, (DDSURFACEDESC *)surface_desc, cbcontext->context); } @@ -4293,6 +4306,8 @@ static HRESULT WINAPI ddraw3_DuplicateSurface(IDirectDraw3 *iface, IDirectDrawSu return hr; dst_impl = impl_from_IDirectDrawSurface7(dst7); *dst = &dst_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*dst); + IDirectDrawSurface7_Release(dst7); return hr; } @@ -4313,6 +4328,8 @@ static HRESULT WINAPI ddraw2_DuplicateSurface(IDirectDraw2 *iface, return hr; dst_impl = impl_from_IDirectDrawSurface7(dst7); *dst = &dst_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*dst); + IDirectDrawSurface7_Release(dst7); return hr; } @@ -4333,6 +4350,8 @@ static HRESULT WINAPI ddraw1_DuplicateSurface(IDirectDraw *iface, IDirectDrawSur return hr; dst_impl = impl_from_IDirectDrawSurface7(dst7); *dst = &dst_impl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*dst); + IDirectDrawSurface7_Release(dst7); return hr; } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 92dad30..fe736b2 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, ref4, ref3, ref2, iface_count; + LONG ref7, ref4, ref3, ref2, ref1, iface_count; IUnknown *ifaceToRelease; int version; diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index a019bec..85f9dda 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -1992,6 +1992,8 @@ static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *if if(hr != D3D_OK) return hr; RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7); *RenderTarget = &RenderTargetImpl->IDirectDrawSurface_iface; + IDirectDrawSurface_AddRef(*RenderTarget); + IDirectDrawSurface7_Release(RenderTarget7); return D3D_OK; } diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index 8d161f5..d2d2c9d 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -752,17 +752,19 @@ DestroyCallback(IDirectDrawSurface7 *surf, void *context) { IDirectDrawSurfaceImpl *Impl = impl_from_IDirectDrawSurface7(surf); - ULONG ref, ref4, ref3, ref2, iface_count; + ULONG ref7, ref4, ref3, ref2, ref1, iface_count; - ref = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */ + ref7 = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */ IDirectDrawSurface4_AddRef(&Impl->IDirectDrawSurface4_iface); ref4 = IDirectDrawSurface4_Release(&Impl->IDirectDrawSurface4_iface); IDirectDrawSurface3_AddRef(&Impl->IDirectDrawSurface3_iface); ref3 = IDirectDrawSurface3_Release(&Impl->IDirectDrawSurface3_iface); IDirectDrawSurface2_AddRef(&Impl->IDirectDrawSurface2_iface); ref2 = IDirectDrawSurface2_Release(&Impl->IDirectDrawSurface2_iface); - WARN("Surface %p has an reference counts of %u 4: %u 3: %u 2: %u\n", - Impl, ref, ref4, ref3, ref2); + IDirectDrawSurface_AddRef(&Impl->IDirectDrawSurface_iface); + ref1 = IDirectDrawSurface_Release(&Impl->IDirectDrawSurface_iface); + WARN("Surface %p has an reference counts of 7: %u 4: %u 3: %u 2: %u 1: %u\n", + Impl, ref7, ref4, ref3, ref2, ref1); /* Skip surfaces which are attached somewhere or which are * part of a complex compound. They will get released when destroying diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 248aa37..aac680c 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -76,7 +76,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirectDrawSurface7) ) { - IUnknown_AddRef(iface); + IDirectDrawSurface7_AddRef(iface); *obj = iface; TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj); return S_OK; @@ -104,7 +104,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, } else if (IsEqualGUID(riid, &IID_IDirectDrawSurface)) { - IUnknown_AddRef(iface); + IDirectDrawSurface_AddRef(&This->IDirectDrawSurface_iface); *obj = &This->IDirectDrawSurface_iface; TRACE("(%p) returning IDirectDrawSurface interface at %p\n", This, *obj); return S_OK; @@ -243,7 +243,7 @@ static void ddraw_surface_add_iface(IDirectDrawSurfaceImpl *This) static ULONG WINAPI ddraw_surface7_AddRef(IDirectDrawSurface7 *iface) { IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); - ULONG refcount = InterlockedIncrement(&This->ref); + ULONG refcount = InterlockedIncrement(&This->ref7); TRACE("iface %p increasing refcount to %u.\n", iface, refcount); @@ -303,9 +303,16 @@ static ULONG WINAPI ddraw_surface2_AddRef(IDirectDrawSurface2 *iface) static ULONG WINAPI ddraw_surface1_AddRef(IDirectDrawSurface *iface) { IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); - TRACE("iface %p.\n", iface); + ULONG refcount = InterlockedIncrement(&This->ref1); - return ddraw_surface7_AddRef(&This->IDirectDrawSurface7_iface); + TRACE("iface %p increasing refcount to %u.\n", iface, refcount); + + if (refcount == 1) + { + ddraw_surface_add_iface(This); + } + + return refcount; } static ULONG WINAPI ddraw_gamma_control_AddRef(IDirectDrawGammaControl *iface) @@ -356,8 +363,8 @@ void ddraw_surface_destroy(IDirectDrawSurfaceImpl *This) * because the 2nd surface was addref()ed when the app * called GetAttachedSurface */ - WARN("(%p): Destroying surface with refcounts %d 4: %d 3: %d 2: %d\n", - This, This->ref, This->ref4, This->ref3, This->ref2); + WARN("(%p): Destroying surface with refcounts 7: %d 4: %d 3: %d 2: %d 1: %d\n", + This, This->ref7, This->ref4, This->ref3, This->ref2, This->ref1); } if (This->wined3d_surface) @@ -513,7 +520,7 @@ ULONG ddraw_surface_release_iface(IDirectDrawSurfaceImpl *This) static ULONG WINAPI ddraw_surface7_Release(IDirectDrawSurface7 *iface) { IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); - ULONG refcount = InterlockedDecrement(&This->ref); + ULONG refcount = InterlockedDecrement(&This->ref7); TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); @@ -573,9 +580,16 @@ static ULONG WINAPI ddraw_surface2_Release(IDirectDrawSurface2 *iface) static ULONG WINAPI ddraw_surface1_Release(IDirectDrawSurface *iface) { IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); - TRACE("iface %p.\n", iface); + ULONG refcount = InterlockedDecrement(&This->ref1); - return ddraw_surface7_Release(&This->IDirectDrawSurface7_iface); + TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); + + if (refcount == 0) + { + ddraw_surface_release_iface(This); + } + + return refcount; } static ULONG WINAPI ddraw_gamma_control_Release(IDirectDrawGammaControl *iface) @@ -833,6 +847,8 @@ static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *ifac } attachment_impl = impl_from_IDirectDrawSurface7(attachment7); *attachment = &attachment_impl->IDirectDrawSurface_iface; + ddraw_surface1_AddRef(*attachment); + ddraw_surface7_Release(attachment7); return hr; } @@ -2309,6 +2325,9 @@ static HRESULT CALLBACK EnumCallback(IDirectDrawSurface7 *surface, DDSURFACEDESC IDirectDrawSurfaceImpl *surface_impl = impl_from_IDirectDrawSurface7(surface); const struct callback_info *info = context; + ddraw_surface1_AddRef(&surface_impl->IDirectDrawSurface_iface); + ddraw_surface7_Release(surface); + return info->callback(&surface_impl->IDirectDrawSurface_iface, (DDSURFACEDESC *)surface_desc, info->context); } @@ -5166,13 +5185,17 @@ HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddr surface->version = version; surface->ddraw = ddraw; - if (version == 4) + if (version == 7) + { + surface->ref7 = 1; + } + else if (version == 4) { surface->ref4 = 1; } else { - surface->ref = 1; + surface->ref1 = 1; } copy_to_surfacedesc2(&surface->surface_desc, desc); diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c index 62532dd..3af6e6d 100644 --- a/dlls/ddraw/tests/dsurface.c +++ b/dlls/ddraw/tests/dsurface.c @@ -1100,11 +1100,11 @@ static void IFaceRefCount(void) IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a); ref = getRefcount((IUnknown *) surf7a); - 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_IDirectDrawSurface7, (void **) &surf7b); ref = getRefcount((IUnknown *) surf7b); - todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref); + ok(ref == 2, "Refcount is %u, expected 2\n", ref); /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */ ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex); @@ -1135,7 +1135,7 @@ static void IFaceRefCount(void) ref = IDirect3DTexture_Release(tex); /* Release the texture */ todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); 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); ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */ todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref); @@ -1154,10 +1154,10 @@ static void IFaceRefCount(void) ok(ref == 0, "Refcount is %u, expected 0\n", ref); ref = IDirectDrawSurface7_Release(surf7a); - todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); + ok(ref == 1, "Refcount is %u, expected 1\n", ref); ref = IDirectDrawSurface7_Release(surf7b); - todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref); + ok(ref == 0, "Refcount is %u, expected 0\n", ref); ref = IDirectDrawSurface_Release(surf); ok(ref == 0, "Refcount is %u, expected 0\n", ref); -- 1.7.5.4