Andrew Nguyen : d3d9: Increment the reference count of the IDirect3D9 parent when creating a device .

Alexandre Julliard julliard at winehq.org
Mon Jun 6 15:19:09 CDT 2011


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

Author: Andrew Nguyen <anguyen at codeweavers.com>
Date:   Fri Jun  3 07:23:27 2011 -0500

d3d9: Increment the reference count of the IDirect3D9 parent when creating a device.

---

 dlls/d3d9/d3d9_private.h |    3 ++-
 dlls/d3d9/device.c       |   27 +++++++--------------------
 dlls/d3d9/directx.c      |    4 ++--
 dlls/d3d9/tests/device.c |   12 ++++++++++++
 4 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 23e7f00..87ff3fd 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -166,6 +166,7 @@ typedef struct IDirect3DDevice9Impl
     struct wined3d_device_parent device_parent;
     LONG ref;
     struct wined3d_device *wined3d_device;
+    IDirect3D9Ex *d3d_parent;
     /* Avoids recursion with nested ReleaseRef to 0 */
     BOOL                          inDestruction;
 
@@ -175,7 +176,7 @@ typedef struct IDirect3DDevice9Impl
     BOOL                          notreset;
 } IDirect3DDevice9Impl;
 
-HRESULT device_init(IDirect3DDevice9Impl *device, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type,
+HRESULT device_init(IDirect3DDevice9Impl *device, IDirect3D9Impl *parent, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type,
         HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode) DECLSPEC_HIDDEN;
 
 /*****************************************************************************
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index a95fa16..2e4ca5d 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -265,6 +265,8 @@ static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(IDirect3DDevi
       wined3d_device_decref(This->wined3d_device);
       wined3d_mutex_unlock();
 
+      IDirect3D9_Release(This->d3d_parent);
+
       HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -317,8 +319,6 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(IDirect3DDevice9Ex *iface
         IDirect3D9 **ppD3D9)
 {
     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
-    struct wined3d *wined3d;
-    HRESULT hr = D3D_OK;
 
     TRACE("iface %p, d3d9 %p.\n", iface, ppD3D9);
 
@@ -326,23 +326,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(IDirect3DDevice9Ex *iface
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
-    hr = wined3d_device_get_wined3d(This->wined3d_device, &wined3d);
-    if (hr == D3D_OK && wined3d)
-    {
-        *ppD3D9 = wined3d_get_parent(wined3d);
-        IDirect3D9_AddRef(*ppD3D9);
-        wined3d_decref(wined3d);
-    }
-    else
-    {
-        FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
-        *ppD3D9 = NULL;
-    }
-    TRACE("(%p) returning %p\n", This, *ppD3D9);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return IDirect3D9Ex_QueryInterface(This->d3d_parent, &IID_IDirect3D9, (void **)ppD3D9);
 }
 
 static HRESULT WINAPI IDirect3DDevice9Impl_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *pCaps)
@@ -3347,7 +3331,7 @@ static void setup_fpu(void)
 #endif
 }
 
-HRESULT device_init(IDirect3DDevice9Impl *device, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type,
+HRESULT device_init(IDirect3DDevice9Impl *device, IDirect3D9Impl *parent, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type,
         HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode)
 {
     WINED3DPRESENT_PARAMETERS *wined3d_parameters;
@@ -3483,5 +3467,8 @@ HRESULT device_init(IDirect3DDevice9Impl *device, struct wined3d *wined3d, UINT
         return E_OUTOFMEMORY;
     }
 
+    device->d3d_parent = &parent->IDirect3D9Ex_iface;
+    IDirect3D9_AddRef(device->d3d_parent);
+
     return D3D_OK;
 }
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index 791d835..148b9b7 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -449,7 +449,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3D9Impl_CreateDevice(IDirect3D9Ex
         return E_OUTOFMEMORY;
     }
 
-    hr = device_init(object, This->WineD3D, adapter, device_type, focus_window, flags, parameters, NULL);
+    hr = device_init(object, This, This->WineD3D, adapter, device_type, focus_window, flags, parameters, NULL);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
@@ -507,7 +507,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3D9ExImpl_CreateDeviceEx(IDirect3
         return E_OUTOFMEMORY;
     }
 
-    hr = device_init(object, d3d9->WineD3D, adapter, device_type, focus_window, flags, parameters, mode);
+    hr = device_init(object, d3d9, d3d9->WineD3D, adapter, device_type, focus_window, flags, parameters, mode);
     if (FAILED(hr))
     {
         WARN("Failed to initialize device, hr %#x.\n", hr);
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 1a74d6e..235b06f 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -423,6 +423,7 @@ static void test_refcount(void)
     HRESULT                      hr;
     HWND                         hwnd               = NULL;
     IDirect3D9                  *pD3d               = NULL;
+    IDirect3D9                  *pD3d2              = NULL;
     IDirect3DDevice9            *pDevice            = NULL;
     IDirect3DVertexBuffer9      *pVertexBuffer      = NULL;
     IDirect3DIndexBuffer9       *pIndexBuffer       = NULL;
@@ -467,6 +468,8 @@ static void test_refcount(void)
     ok(hwnd != NULL, "Failed to create window\n");
     if (!pD3d || !hwnd) goto cleanup;
 
+    CHECK_REFCOUNT( pD3d, 1 );
+
     IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
     ZeroMemory( &d3dpp, sizeof(d3dpp) );
     d3dpp.Windowed         = TRUE;
@@ -484,6 +487,15 @@ static void test_refcount(void)
     refcount = get_refcount( (IUnknown *)pDevice );
     ok(refcount == 1, "Invalid device RefCount %d\n", refcount);
 
+    CHECK_REFCOUNT( pD3d, 2 );
+
+    hr = IDirect3DDevice9_GetDirect3D(pDevice, &pD3d2);
+    CHECK_CALL( hr, "GetDirect3D", pDevice, refcount );
+
+    ok(pD3d2 == pD3d, "Expected IDirect3D9 pointers to be equal\n");
+    CHECK_REFCOUNT( pD3d, 3 );
+    CHECK_RELEASE_REFCOUNT( pD3d, 2 );
+
     /**
      * Check refcount of implicit surfaces and implicit swapchain. Findings:
      *   - the container is the device OR swapchain




More information about the wine-cvs mailing list