Ričardas Barkauskas : ddraw: Separate IDirectDrawSurface4 reference count.

Alexandre Julliard julliard at winehq.org
Tue Jun 28 17:25:15 CDT 2011


Module: wine
Branch: master
Commit: 9190d349d20694007e236fecfae93da232ecd003
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9190d349d20694007e236fecfae93da232ecd003

Author: Ričardas Barkauskas <rbarkauskas at codeweavers.com>
Date:   Tue Jun 28 02:34:23 2011 +0300

ddraw: Separate IDirectDrawSurface4 reference count.

---

 dlls/ddraw/ddraw.c          |    7 +++++++
 dlls/ddraw/ddraw_private.h  |    2 +-
 dlls/ddraw/device.c         |    2 ++
 dlls/ddraw/main.c           |    7 +++++--
 dlls/ddraw/surface.c        |   43 +++++++++++++++++++++++++++++++++++--------
 dlls/ddraw/tests/dsurface.c |   14 +++++++-------
 6 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index c3e1a38..d039388 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2051,6 +2051,8 @@ static HRESULT WINAPI ddraw4_GetGDISurface(IDirectDraw4 *iface, IDirectDrawSurfa
     }
     surface_impl = impl_from_IDirectDrawSurface7(surface7);
     *surface = &surface_impl->IDirectDrawSurface4_iface;
+    IDirectDrawSurface4_AddRef(*surface);
+    IDirectDrawSurface7_Release(surface7);
 
     return hr;
 }
@@ -3809,6 +3811,9 @@ static HRESULT CALLBACK EnumSurfacesCallback2Thunk(IDirectDrawSurface7 *surface,
     IDirectDrawSurfaceImpl *surface_impl = impl_from_IDirectDrawSurface7(surface);
     struct surfacescallback2_context *cbcontext = context;
 
+    IDirectDrawSurface4_AddRef(&surface_impl->IDirectDrawSurface4_iface);
+    IDirectDrawSurface7_Release(surface);
+
     return cbcontext->func(&surface_impl->IDirectDrawSurface4_iface,
             surface_desc, cbcontext->context);
 }
@@ -4266,6 +4271,8 @@ static HRESULT WINAPI ddraw4_DuplicateSurface(IDirectDraw4 *iface, IDirectDrawSu
     }
     dst_impl = impl_from_IDirectDrawSurface7(dst7);
     *dst = &dst_impl->IDirectDrawSurface4_iface;
+    IDirectDrawSurface4_AddRef(*dst);
+    IDirectDrawSurface7_Release(dst7);
 
     return hr;
 }
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 1a8dc20..92dad30 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, ref3, ref2, iface_count;
+    LONG                     ref, ref4, ref3, ref2, iface_count;
     IUnknown                *ifaceToRelease;
 
     int                     version;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 9699939..a019bec 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -1970,6 +1970,8 @@ static HRESULT WINAPI IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *if
     if(hr != D3D_OK) return hr;
     RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7);
     *RenderTarget = &RenderTargetImpl->IDirectDrawSurface4_iface;
+    IDirectDrawSurface4_AddRef(*RenderTarget);
+    IDirectDrawSurface7_Release(RenderTarget7);
     return D3D_OK;
 }
 
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 37404d8..8d161f5 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -752,14 +752,17 @@ DestroyCallback(IDirectDrawSurface7 *surf,
                 void *context)
 {
     IDirectDrawSurfaceImpl *Impl = impl_from_IDirectDrawSurface7(surf);
-    ULONG ref, ref3, ref2, iface_count;
+    ULONG ref, ref4, ref3, ref2, iface_count;
 
     ref = 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 %d 3: %d 2: %d\n", Impl, ref, ref3, ref2);
+    WARN("Surface %p has an reference counts of %u 4: %u 3: %u 2: %u\n",
+            Impl, ref, ref4, ref3, ref2);
 
     /* 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 e391b3d..248aa37 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -83,7 +83,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface,
     }
     else if (IsEqualGUID(riid, &IID_IDirectDrawSurface4))
     {
-        IUnknown_AddRef(iface);
+        IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface);
         *obj = &This->IDirectDrawSurface4_iface;
         TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This, *obj);
         return S_OK;
@@ -258,9 +258,16 @@ static ULONG WINAPI ddraw_surface7_AddRef(IDirectDrawSurface7 *iface)
 static ULONG WINAPI ddraw_surface4_AddRef(IDirectDrawSurface4 *iface)
 {
     IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
-    TRACE("iface %p.\n", iface);
+    ULONG refcount = InterlockedIncrement(&This->ref4);
 
-    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_surface3_AddRef(IDirectDrawSurface3 *iface)
@@ -349,8 +356,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 3: %d 2: %d\n", This, This->ref,
-			This->ref3, This->ref2);
+        WARN("(%p): Destroying surface with refcounts %d 4: %d 3: %d 2: %d\n",
+                This, This->ref, This->ref4, This->ref3, This->ref2);
     }
 
     if (This->wined3d_surface)
@@ -521,9 +528,16 @@ static ULONG WINAPI ddraw_surface7_Release(IDirectDrawSurface7 *iface)
 static ULONG WINAPI ddraw_surface4_Release(IDirectDrawSurface4 *iface)
 {
     IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
-    TRACE("iface %p.\n", iface);
+    ULONG refcount = InterlockedDecrement(&This->ref4);
 
-    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_surface3_Release(IDirectDrawSurface3 *iface)
@@ -726,6 +740,8 @@ static HRESULT WINAPI ddraw_surface4_GetAttachedSurface(IDirectDrawSurface4 *ifa
     }
     attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
     *attachment = &attachment_impl->IDirectDrawSurface4_iface;
+    ddraw_surface4_AddRef(*attachment);
+    ddraw_surface7_Release(attachment7);
 
     return hr;
 }
@@ -2282,6 +2298,9 @@ static HRESULT CALLBACK EnumCallback2(IDirectDrawSurface7 *surface, DDSURFACEDES
     IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(surface);
     const struct callback_info2 *info = context;
 
+    ddraw_surface4_AddRef(&This->IDirectDrawSurface4_iface);
+    ddraw_surface7_Release(surface);
+
     return info->callback(&This->IDirectDrawSurface4_iface, surface_desc, info->context);
 }
 
@@ -5143,11 +5162,19 @@ HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddr
     surface->IDirectDrawGammaControl_iface.lpVtbl = &ddraw_gamma_control_vtbl;
     surface->IDirect3DTexture2_vtbl = &d3d_texture2_vtbl;
     surface->IDirect3DTexture_vtbl = &d3d_texture1_vtbl;
-    surface->ref = 1;
     surface->iface_count = 1;
     surface->version = version;
     surface->ddraw = ddraw;
 
+    if (version == 4)
+    {
+        surface->ref4 = 1;
+    }
+    else
+    {
+        surface->ref = 1;
+    }
+
     copy_to_surfacedesc2(&surface->surface_desc, desc);
 
     surface->first_attached = surface;
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index 4cfe469..62532dd 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -1096,7 +1096,7 @@ static void IFaceRefCount(void)
 
     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
     ref = getRefcount((IUnknown *) surf4);
-    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 **) &surf7a);
     ref = getRefcount((IUnknown *) surf7a);
@@ -1151,7 +1151,7 @@ static void IFaceRefCount(void)
     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);
+    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);
@@ -3135,9 +3135,9 @@ static void GetDCTest(void)
     ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
 
     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 = getRefcount((IUnknown *) surf4);
-    todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
+    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
 
     hr = IDirectDrawSurface4_GetDC(surf4, &dc);
     ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
@@ -3150,11 +3150,11 @@ static void GetDCTest(void)
     ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
 
     ref = getRefcount((IUnknown *) surf);
-    todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
+    ok(ref == 2, "Refcount is %u, expected 2\n", ref);
     ref = getRefcount((IUnknown *) tmp);
-    todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
+    ok(ref == 2, "Refcount is %u, expected 2\n", ref);
     ref = getRefcount((IUnknown *) surf4);
-    todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
+    ok(ref == 1, "Refcount is %u, expected 1\n", ref);
 
     hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
     ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);




More information about the wine-cvs mailing list