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

This commit is contained in:
Andrew Nguyen 2011-06-03 07:23:27 -05:00 committed by Alexandre Julliard
parent 174b03cad8
commit 94785ab4d5
4 changed files with 23 additions and 23 deletions

View File

@ -166,6 +166,7 @@ typedef struct IDirect3DDevice9Impl
struct wined3d_device_parent device_parent; struct wined3d_device_parent device_parent;
LONG ref; LONG ref;
struct wined3d_device *wined3d_device; struct wined3d_device *wined3d_device;
IDirect3D9Ex *d3d_parent;
/* Avoids recursion with nested ReleaseRef to 0 */ /* Avoids recursion with nested ReleaseRef to 0 */
BOOL inDestruction; BOOL inDestruction;
@ -175,7 +176,7 @@ typedef struct IDirect3DDevice9Impl
BOOL notreset; BOOL notreset;
} IDirect3DDevice9Impl; } 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; HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode) DECLSPEC_HIDDEN;
/***************************************************************************** /*****************************************************************************

View File

@ -265,6 +265,8 @@ static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(IDirect3DDevi
wined3d_device_decref(This->wined3d_device); wined3d_device_decref(This->wined3d_device);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
IDirect3D9_Release(This->d3d_parent);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
return ref; return ref;
@ -317,8 +319,6 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(IDirect3DDevice9Ex *iface
IDirect3D9 **ppD3D9) IDirect3D9 **ppD3D9)
{ {
IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface); IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
struct wined3d *wined3d;
HRESULT hr = D3D_OK;
TRACE("iface %p, d3d9 %p.\n", iface, ppD3D9); TRACE("iface %p, d3d9 %p.\n", iface, ppD3D9);
@ -326,23 +326,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(IDirect3DDevice9Ex *iface
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
wined3d_mutex_lock(); return IDirect3D9Ex_QueryInterface(This->d3d_parent, &IID_IDirect3D9, (void **)ppD3D9);
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;
} }
static HRESULT WINAPI IDirect3DDevice9Impl_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *pCaps) static HRESULT WINAPI IDirect3DDevice9Impl_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *pCaps)
@ -3347,7 +3331,7 @@ static void setup_fpu(void)
#endif #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) HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode)
{ {
WINED3DPRESENT_PARAMETERS *wined3d_parameters; WINED3DPRESENT_PARAMETERS *wined3d_parameters;
@ -3483,5 +3467,8 @@ HRESULT device_init(IDirect3DDevice9Impl *device, struct wined3d *wined3d, UINT
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
device->d3d_parent = &parent->IDirect3D9Ex_iface;
IDirect3D9_AddRef(device->d3d_parent);
return D3D_OK; return D3D_OK;
} }

View File

@ -449,7 +449,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3D9Impl_CreateDevice(IDirect3D9Ex
return E_OUTOFMEMORY; 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)) if (FAILED(hr))
{ {
WARN("Failed to initialize device, hr %#x.\n", 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; 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)) if (FAILED(hr))
{ {
WARN("Failed to initialize device, hr %#x.\n", hr); WARN("Failed to initialize device, hr %#x.\n", hr);

View File

@ -423,6 +423,7 @@ static void test_refcount(void)
HRESULT hr; HRESULT hr;
HWND hwnd = NULL; HWND hwnd = NULL;
IDirect3D9 *pD3d = NULL; IDirect3D9 *pD3d = NULL;
IDirect3D9 *pD3d2 = NULL;
IDirect3DDevice9 *pDevice = NULL; IDirect3DDevice9 *pDevice = NULL;
IDirect3DVertexBuffer9 *pVertexBuffer = NULL; IDirect3DVertexBuffer9 *pVertexBuffer = NULL;
IDirect3DIndexBuffer9 *pIndexBuffer = NULL; IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
@ -467,6 +468,8 @@ static void test_refcount(void)
ok(hwnd != NULL, "Failed to create window\n"); ok(hwnd != NULL, "Failed to create window\n");
if (!pD3d || !hwnd) goto cleanup; if (!pD3d || !hwnd) goto cleanup;
CHECK_REFCOUNT( pD3d, 1 );
IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm ); IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
ZeroMemory( &d3dpp, sizeof(d3dpp) ); ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE; d3dpp.Windowed = TRUE;
@ -484,6 +487,15 @@ static void test_refcount(void)
refcount = get_refcount( (IUnknown *)pDevice ); refcount = get_refcount( (IUnknown *)pDevice );
ok(refcount == 1, "Invalid device RefCount %d\n", refcount); 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: * Check refcount of implicit surfaces and implicit swapchain. Findings:
* - the container is the device OR swapchain * - the container is the device OR swapchain