mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
ddraw: Split up the ddraw refcount.
This commit is contained in:
parent
d690094807
commit
0a81295782
@ -131,7 +131,13 @@ IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface,
|
||||
TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
|
||||
}
|
||||
|
||||
/* Direct3D */
|
||||
/* Direct3D
|
||||
* The refcount unit test revealed that an IDirect3D7 interface can only be queried
|
||||
* from a DirectDraw object that was created as an IDirectDraw7 interface. No idea
|
||||
* who had this idea and why. The older interfaces can query and IDirect3D version
|
||||
* because they are all created as IDirectDraw(1). This isn't really crucial behavior,
|
||||
* and messy to implement with the common creation function, so it has been left out here.
|
||||
*/
|
||||
else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
|
||||
IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
|
||||
IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
|
||||
@ -197,17 +203,30 @@ IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface,
|
||||
/*****************************************************************************
|
||||
* IDirectDraw7::AddRef
|
||||
*
|
||||
* Increases the interfaces refcount. Used for version 1, 2, 4 and 7
|
||||
* Increases the interfaces refcount, basically
|
||||
*
|
||||
* DDraw refcounting is a bit tricky. The different DirectDraw interface
|
||||
* versions have individual refcounts, but the IDirect3D interfaces do not.
|
||||
* All interfaces are from one object, that means calling QueryInterface on an
|
||||
* IDirectDraw7 interface for an IDirectDraw4 interface does not create a new
|
||||
* IDirectDrawImpl object.
|
||||
*
|
||||
* That means all AddRef and Release implementations of IDirectDrawX work
|
||||
* with their own counter, and IDirect3DX::AddRef thunk to IDirectDraw (1),
|
||||
* except of IDirect3D7 which thunks to IDirectDraw7
|
||||
*
|
||||
* Returns: The new refcount
|
||||
*
|
||||
*****************************************************************************/
|
||||
static ULONG WINAPI
|
||||
IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
ULONG ref = InterlockedIncrement(&This->ref7);
|
||||
|
||||
TRACE("(%p) : incrementing from %lu.\n", This, ref -1);
|
||||
TRACE("(%p) : incrementing IDirectDraw7 refcount from %lu.\n", This, ref -1);
|
||||
|
||||
if(ref == 1) InterlockedIncrement(&This->numIfaces);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@ -215,8 +234,8 @@ IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
|
||||
/*****************************************************************************
|
||||
* IDirectDrawImpl_Destroy
|
||||
*
|
||||
* Destroys a ddraw object. This is to share code between normal Release
|
||||
* and the dll unload cleanup code
|
||||
* Destroys a ddraw object if all refcounts are 0. This is to share code
|
||||
* between the IDirectDrawX::Release functions
|
||||
*
|
||||
* Params:
|
||||
* This: DirectDraw object to destroy
|
||||
@ -225,45 +244,49 @@ IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
|
||||
void
|
||||
IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
|
||||
{
|
||||
IDirectDrawImpl *prev;
|
||||
IDirectDrawImpl *prev;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
/* Clear the cooplevel to restore window and display mode */
|
||||
IDirectDraw7_SetCooperativeLevel(ICOM_INTERFACE(This, IDirectDraw7),
|
||||
NULL,
|
||||
DDSCL_NORMAL);
|
||||
|
||||
/* Destroy the device window if we created one */
|
||||
if(This->devicewindow != 0)
|
||||
{
|
||||
TRACE(" (%p) Destroying the device window %p\n", This, This->devicewindow);
|
||||
DestroyWindow(This->devicewindow);
|
||||
This->devicewindow = 0;
|
||||
}
|
||||
/* Destroy the device window if we created one */
|
||||
if(This->devicewindow != 0)
|
||||
{
|
||||
TRACE(" (%p) Destroying the device window %p\n", This, This->devicewindow);
|
||||
DestroyWindow(This->devicewindow);
|
||||
This->devicewindow = 0;
|
||||
}
|
||||
|
||||
/* Unregister the window class */
|
||||
UnregisterClassA(This->classname, 0);
|
||||
/* Unregister the window class */
|
||||
UnregisterClassA(This->classname, 0);
|
||||
|
||||
/* Unchain it from the ddraw list */
|
||||
if(ddraw_list == This)
|
||||
{
|
||||
ddraw_list = This->next;
|
||||
/* No need to search for a predecessor here */
|
||||
}
|
||||
/* Unchain it from the ddraw list */
|
||||
if(ddraw_list == This)
|
||||
{
|
||||
ddraw_list = This->next;
|
||||
/* No need to search for a predecessor here */
|
||||
}
|
||||
else
|
||||
{
|
||||
for(prev = ddraw_list; prev; prev = prev->next)
|
||||
if(prev->next == This) break;
|
||||
|
||||
if(prev)
|
||||
prev->next = This->next;
|
||||
else
|
||||
{
|
||||
for(prev = ddraw_list; prev; prev = prev->next)
|
||||
if(prev->next == This) break;
|
||||
ERR("Didn't find the previous ddraw element in the list\n");
|
||||
}
|
||||
|
||||
if(prev)
|
||||
prev->next = This->next;
|
||||
else
|
||||
ERR("Didn't find the previous ddraw element in the list\n");
|
||||
}
|
||||
/* Release the attached WineD3D stuff */
|
||||
IWineD3DDevice_Release(This->wineD3DDevice);
|
||||
IWineD3D_Release(This->wineD3D);
|
||||
|
||||
/* Release the attached WineD3D stuff */
|
||||
IWineD3DDevice_Release(This->wineD3DDevice);
|
||||
IWineD3D_Release(This->wineD3D);
|
||||
|
||||
/* Now free the object */
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
/* Now free the object */
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirectDraw7::Release
|
||||
*
|
||||
@ -275,21 +298,14 @@ static ULONG WINAPI
|
||||
IDirectDrawImpl_Release(IDirectDraw7 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
ULONG ref = InterlockedDecrement(&This->ref7);
|
||||
|
||||
TRACE("(%p)->() decrementing from %lu.\n", This, ref +1);
|
||||
TRACE("(%p)->() decrementing IDirectDraw7 refcount from %lu.\n", This, ref +1);
|
||||
|
||||
if (ref == 0)
|
||||
if(ref == 0)
|
||||
{
|
||||
/* No need to restore the display mode - it's done by SetCooperativeLevel */
|
||||
|
||||
IDirectDraw7_SetCooperativeLevel(ICOM_INTERFACE(This, IDirectDraw7),
|
||||
NULL,
|
||||
DDSCL_NORMAL);
|
||||
|
||||
/* This is for the dll cleanup code in DllMain() */
|
||||
if(!This->DoNotDestroy)
|
||||
IDirectDrawImpl_Destroy(This);
|
||||
ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
|
||||
if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@ -2337,6 +2353,7 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
|
||||
|
||||
/* Addref the ddraw interface to keep an reference for each surface */
|
||||
IDirectDraw7_AddRef(iface);
|
||||
object->ifaceToRelease = (IUnknown *) iface;
|
||||
|
||||
/* If the implementation is OpenGL and there's no d3ddevice, attach a d3ddevice
|
||||
* But attach the d3ddevice only if the currently created surface was
|
||||
|
@ -90,7 +90,8 @@ struct IDirectDrawImpl
|
||||
ICOM_VFIELD_MULTI(IDirect3D2);
|
||||
ICOM_VFIELD_MULTI(IDirect3D);
|
||||
|
||||
LONG ref;
|
||||
/* See comment in IDirectDraw::AddRef */
|
||||
LONG ref7, ref4, ref2, ref1, numIfaces;
|
||||
|
||||
/* WineD3D linkage */
|
||||
IWineD3D *wineD3D;
|
||||
@ -143,7 +144,6 @@ struct IDirectDrawImpl
|
||||
|
||||
/* For the dll unload cleanup code */
|
||||
IDirectDrawImpl *next;
|
||||
BOOL DoNotDestroy;
|
||||
LONG surfaces;
|
||||
};
|
||||
|
||||
@ -202,6 +202,7 @@ struct IDirectDrawSurfaceImpl
|
||||
ICOM_VFIELD_MULTI(IDirect3DTexture);
|
||||
|
||||
LONG ref;
|
||||
IUnknown *ifaceToRelease;
|
||||
|
||||
int version;
|
||||
|
||||
|
@ -17,15 +17,32 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winerror.h"
|
||||
#include "wingdi.h"
|
||||
#include "wine/exception.h"
|
||||
#include "excpt.h"
|
||||
|
||||
#include "ddraw.h"
|
||||
#include "d3d.h"
|
||||
|
||||
#include "ddraw_private.h"
|
||||
#include "ddcomimpl.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ddraw_thunk);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(ddraw);
|
||||
|
||||
static HRESULT WINAPI
|
||||
IDirectDrawImpl_QueryInterface(LPDIRECTDRAW This, REFIID iid, LPVOID *ppObj)
|
||||
@ -56,51 +73,93 @@ IDirectDraw4Impl_QueryInterface(LPDIRECTDRAW4 This, REFIID iid, LPVOID *ppObj)
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IDirectDrawImpl_AddRef(LPDIRECTDRAW This)
|
||||
IDirectDrawImpl_AddRef(LPDIRECTDRAW iface)
|
||||
{
|
||||
return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw, IDirectDraw7,
|
||||
This));
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw, iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref1);
|
||||
|
||||
TRACE("(%p) : incrementing IDirectDraw refcount from %lu.\n", This, ref -1);
|
||||
|
||||
if(ref == 1) InterlockedIncrement(&This->numIfaces);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 This)
|
||||
IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface)
|
||||
{
|
||||
return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw2, IDirectDraw7,
|
||||
This));
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw2, iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref2);
|
||||
|
||||
TRACE("(%p) : incrementing IDirectDraw2 refcount from %lu.\n", This, ref -1);
|
||||
|
||||
if(ref == 1) InterlockedIncrement(&This->numIfaces);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IDirectDraw4Impl_AddRef(LPDIRECTDRAW4 This)
|
||||
IDirectDraw4Impl_AddRef(LPDIRECTDRAW4 iface)
|
||||
{
|
||||
return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw4, IDirectDraw7,
|
||||
This));
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw4, iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref4);
|
||||
|
||||
TRACE("(%p) : incrementing IDirectDraw4 refcount from %lu.\n", This, ref -1);
|
||||
|
||||
if(ref == 1) InterlockedIncrement(&This->numIfaces);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IDirectDrawImpl_Release(LPDIRECTDRAW This)
|
||||
IDirectDrawImpl_Release(LPDIRECTDRAW iface)
|
||||
{
|
||||
return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw, IDirectDraw7,
|
||||
This));
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw, iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref1);
|
||||
|
||||
TRACE_(ddraw)("(%p)->() decrementing IDirectDraw refcount from %lu.\n", This, ref +1);
|
||||
|
||||
if(ref == 0)
|
||||
{
|
||||
ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
|
||||
if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IDirectDraw2Impl_Release(LPDIRECTDRAW2 This)
|
||||
IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface)
|
||||
{
|
||||
return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw2, IDirectDraw7,
|
||||
This));
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw2, iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref2);
|
||||
|
||||
TRACE_(ddraw)("(%p)->() decrementing IDirectDraw2 refcount from %lu.\n", This, ref +1);
|
||||
|
||||
if(ref == 0)
|
||||
{
|
||||
ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
|
||||
if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IDirectDraw4Impl_Release(LPDIRECTDRAW4 This)
|
||||
IDirectDraw4Impl_Release(LPDIRECTDRAW4 iface)
|
||||
{
|
||||
return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw4, IDirectDraw7,
|
||||
This));
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw4, iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref4);
|
||||
|
||||
TRACE_(ddraw)("(%p)->() decrementing IDirectDraw4 refcount from %lu.\n", This, ref +1);
|
||||
|
||||
if(ref == 0)
|
||||
{
|
||||
ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
|
||||
if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -169,11 +228,20 @@ IDirectDrawImpl_CreatePalette(LPDIRECTDRAW This, DWORD dwFlags,
|
||||
LPDIRECTDRAWPALETTE *ppPalette,
|
||||
IUnknown *pUnkOuter)
|
||||
{
|
||||
return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
HRESULT hr;
|
||||
hr = IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw,
|
||||
IDirectDraw7,
|
||||
This),
|
||||
dwFlags, pEntries, ppPalette, pUnkOuter);
|
||||
if(SUCCEEDED(hr) && *ppPalette)
|
||||
{
|
||||
IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw,
|
||||
IDirectDraw7,
|
||||
This));
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -182,11 +250,19 @@ IDirectDraw2Impl_CreatePalette(LPDIRECTDRAW2 This, DWORD dwFlags,
|
||||
LPDIRECTDRAWPALETTE *ppPalette,
|
||||
IUnknown *pUnkOuter)
|
||||
{
|
||||
HRESULT hr;
|
||||
return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw2,
|
||||
IDirectDraw7,
|
||||
This),
|
||||
dwFlags, pEntries, ppPalette, pUnkOuter);
|
||||
if(SUCCEEDED(hr) && *ppPalette)
|
||||
{
|
||||
IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw,
|
||||
IDirectDraw7,
|
||||
This));
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -195,11 +271,19 @@ IDirectDraw4Impl_CreatePalette(LPDIRECTDRAW4 This, DWORD dwFlags,
|
||||
LPDIRECTDRAWPALETTE *ppPalette,
|
||||
IUnknown *pUnkOuter)
|
||||
{
|
||||
HRESULT hr;
|
||||
return IDirectDraw7_CreatePalette(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw4,
|
||||
IDirectDraw7,
|
||||
This),
|
||||
dwFlags, pEntries, ppPalette, pUnkOuter);
|
||||
if(SUCCEEDED(hr) && *ppPalette)
|
||||
{
|
||||
IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw,
|
||||
IDirectDraw7,
|
||||
This));
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -226,9 +310,15 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
|
||||
pSurface7);
|
||||
|
||||
impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7);
|
||||
if(impl)
|
||||
if(SUCCEEDED(hr) && impl)
|
||||
{
|
||||
impl->version = 1;
|
||||
IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw,
|
||||
IDirectDraw7,
|
||||
This));
|
||||
IDirectDraw_AddRef(This);
|
||||
impl->ifaceToRelease = (IUnknown *) This;
|
||||
}
|
||||
|
||||
return hr;
|
||||
@ -256,9 +346,15 @@ IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
|
||||
pSurface7);
|
||||
|
||||
impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7);
|
||||
if(impl)
|
||||
if(SUCCEEDED(hr) && impl)
|
||||
{
|
||||
impl->version = 2;
|
||||
IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw2,
|
||||
IDirectDraw7,
|
||||
This));
|
||||
IDirectDraw2_AddRef(This);
|
||||
impl->ifaceToRelease = (IUnknown *) This;
|
||||
}
|
||||
|
||||
return hr;
|
||||
@ -280,9 +376,15 @@ IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
|
||||
(LPDIRECTDRAWSURFACE7 *)ppSurface,
|
||||
pUnkOuter);
|
||||
impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurface);
|
||||
if(impl)
|
||||
if(SUCCEEDED(hr) && impl)
|
||||
{
|
||||
impl->version = 4;
|
||||
IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl,
|
||||
IDirectDraw4,
|
||||
IDirectDraw7,
|
||||
This));
|
||||
IDirectDraw4_AddRef(This);
|
||||
impl->ifaceToRelease = (IUnknown *) This;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
@ -43,10 +43,9 @@
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
|
||||
|
||||
/*****************************************************************************
|
||||
* IUnknown Methods. Common for Version 1, 2, 3 and 7
|
||||
* IDirect3D7::QueryInterface
|
||||
*
|
||||
* These are thunks which relay to IDirectDraw. See ddraw.c for
|
||||
* details
|
||||
* QueryInterface implementation with thunks to IDirectDraw7
|
||||
*
|
||||
*****************************************************************************/
|
||||
static HRESULT WINAPI
|
||||
@ -101,11 +100,30 @@ Thunk_IDirect3DImpl_1_QueryInterface(IDirect3D *iface,
|
||||
obj);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3D7::AddRef
|
||||
*
|
||||
* DirectDraw refcounting is a bit odd. Every version of the ddraw interface
|
||||
* has its own refcount, but IDirect3D 1/2/3 refcounts are linked to
|
||||
* IDirectDraw, and IDirect3D7 is linked to IDirectDraw7
|
||||
*
|
||||
* IDirect3D7 -> IDirectDraw7
|
||||
* IDirect3D3 -> IDirectDraw
|
||||
* IDirect3D2 -> IDirectDraw
|
||||
* IDirect3D -> IDirectDraw
|
||||
*
|
||||
* So every AddRef implementation thunks to a different interface, and the
|
||||
* IDirectDrawX::AddRef implementations have different counters...
|
||||
*
|
||||
* Returns
|
||||
* The new refcount
|
||||
*
|
||||
*****************************************************************************/
|
||||
static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_7_AddRef(IDirect3D7 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7\n", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7.\n", This);
|
||||
|
||||
return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
}
|
||||
@ -114,34 +132,42 @@ static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_3_AddRef(IDirect3D3 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7\n", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw.\n", This);
|
||||
|
||||
return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
return IDirectDraw_AddRef(ICOM_INTERFACE(This, IDirectDraw));
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_2_AddRef(IDirect3D2 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7\n", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw.\n", This);
|
||||
|
||||
return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
return IDirectDraw_AddRef(ICOM_INTERFACE(This, IDirectDraw));
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_1_AddRef(IDirect3D *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7\n", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw.\n", This);
|
||||
|
||||
return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
return IDirectDraw_AddRef(ICOM_INTERFACE(This, IDirectDraw));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3D7::Release
|
||||
*
|
||||
* Same story as IDirect3D7::AddRef
|
||||
*
|
||||
* Returns: The new refcount
|
||||
*
|
||||
*****************************************************************************/
|
||||
static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_7_Release(IDirect3D7 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7.\n", This);
|
||||
|
||||
return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
}
|
||||
@ -150,27 +176,27 @@ static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_3_Release(IDirect3D3 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw.\n", This);
|
||||
|
||||
return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
return IDirectDraw_Release(ICOM_INTERFACE(This, IDirectDraw));
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_2_Release(IDirect3D2 *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw.\n", This);
|
||||
|
||||
return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
return IDirectDraw_Release(ICOM_INTERFACE(This, IDirectDraw));
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
Thunk_IDirect3DImpl_1_Release(IDirect3D *iface)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
|
||||
TRACE("(%p) : Thunking to IDirectDraw7", This);
|
||||
TRACE("(%p) : Thunking to IDirectDraw.\n", This);
|
||||
|
||||
return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7));
|
||||
return IDirectDraw_Release(ICOM_INTERFACE(This, IDirectDraw));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -135,7 +135,6 @@ DDRAW_Create(GUID *guid,
|
||||
ICOM_INIT_INTERFACE(This, IDirect3D2, IDirect3D2_Vtbl);
|
||||
ICOM_INIT_INTERFACE(This, IDirect3D3, IDirect3D3_Vtbl);
|
||||
ICOM_INIT_INTERFACE(This, IDirect3D7, IDirect3D7_Vtbl);
|
||||
This->ref = 1;
|
||||
|
||||
/* See comments in IDirectDrawImpl_CreateNewSurface for a description
|
||||
* of this member.
|
||||
@ -285,9 +284,10 @@ DDRAW_Create(GUID *guid,
|
||||
This->next = ddraw_list;
|
||||
ddraw_list = This;
|
||||
|
||||
/* Call QueryInterface to get the pointer to the requested interface */
|
||||
/* Call QueryInterface to get the pointer to the requested interface. This also initializes
|
||||
* The required refcount
|
||||
*/
|
||||
hr = IDirectDraw7_QueryInterface( ICOM_INTERFACE(This, IDirectDraw7), iid, DD);
|
||||
IDirectDraw7_Release( ICOM_INTERFACE(This, IDirectDraw7) );
|
||||
if(SUCCEEDED(hr)) return DD_OK;
|
||||
|
||||
err_out:
|
||||
@ -843,9 +843,13 @@ DllMain(HINSTANCE hInstDLL,
|
||||
DDSURFACEDESC2 desc;
|
||||
int i;
|
||||
|
||||
WARN("DDraw %p has a refcount of %ld\n", ddraw, ddraw->ref);
|
||||
WARN("DDraw %p has a refcount of %ld\n", ddraw, ddraw->ref7 + ddraw->ref4 + ddraw->ref2 + ddraw->ref1);
|
||||
|
||||
ddraw->DoNotDestroy = TRUE; /* Avoid to destroy the object too early */
|
||||
/* Add references to each interface to avoid freeing them unexpectadely */
|
||||
IDirectDraw_AddRef(ICOM_INTERFACE(ddraw, IDirectDraw));
|
||||
IDirectDraw2_AddRef(ICOM_INTERFACE(ddraw, IDirectDraw2));
|
||||
IDirectDraw4_AddRef(ICOM_INTERFACE(ddraw, IDirectDraw4));
|
||||
IDirectDraw7_AddRef(ICOM_INTERFACE(ddraw, IDirectDraw7));
|
||||
|
||||
/* Does a D3D device exist? Destroy it
|
||||
* TODO: Destroy all Vertex buffers, Lights, Materials
|
||||
@ -877,12 +881,13 @@ DllMain(HINSTANCE hInstDLL,
|
||||
if(ddraw->surfaces > 0)
|
||||
ERR("DDraw %p still has %ld surfaces attached\n", ddraw, ddraw->surfaces);
|
||||
|
||||
/* Restore the cooperative level */
|
||||
IDirectDraw7_SetCooperativeLevel(ICOM_INTERFACE(ddraw, IDirectDraw7),
|
||||
NULL,
|
||||
DDSCL_NORMAL);
|
||||
ddraw->DoNotDestroy = FALSE;
|
||||
IDirectDrawImpl_Destroy(ddraw);
|
||||
/* Release all hanging references to destroy the objects. This
|
||||
* restores the screen mode too
|
||||
*/
|
||||
while(IDirectDraw_Release(ICOM_INTERFACE(ddraw, IDirectDraw)));
|
||||
while(IDirectDraw2_Release(ICOM_INTERFACE(ddraw, IDirectDraw2)));
|
||||
while(IDirectDraw4_Release(ICOM_INTERFACE(ddraw, IDirectDraw4)));
|
||||
while(IDirectDraw7_Release(ICOM_INTERFACE(ddraw, IDirectDraw7)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -291,6 +291,7 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface)
|
||||
|
||||
IDirectDrawSurfaceImpl *surf;
|
||||
IDirectDrawImpl *ddraw;
|
||||
IUnknown *ifaceToRelease = This->ifaceToRelease;
|
||||
|
||||
/* Destroy all complex attached surfaces
|
||||
* Therefore, start with the first surface,
|
||||
@ -385,7 +386,7 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface)
|
||||
IDirectDrawSurfaceImpl_Destroy(This);
|
||||
|
||||
/* Reduce the ddraw refcount */
|
||||
IDirectDraw7_Release(ICOM_INTERFACE(ddraw, IDirectDraw7));
|
||||
IUnknown_Release(ifaceToRelease);
|
||||
}
|
||||
|
||||
return ref;
|
||||
@ -1627,13 +1628,32 @@ IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7 *iface,
|
||||
{
|
||||
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n",This,DD);
|
||||
/* It is not quite correct to use the same lpVtable for the different
|
||||
* IDirectDrawSurface versions because the GetDDInterface return different interfaces
|
||||
*/
|
||||
FIXME("(%p)->(%p)\n",This,DD);
|
||||
|
||||
if(!DD)
|
||||
return DDERR_INVALIDPARAMS;
|
||||
|
||||
*((IDirectDraw7 **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
|
||||
IDirectDraw7_AddRef( (IDirectDraw7 *) *DD);
|
||||
switch(This->version)
|
||||
{
|
||||
case 7:
|
||||
*((IDirectDraw7 **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
|
||||
IDirectDraw7_AddRef(*(IDirectDraw7 **) DD);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*((IDirectDraw4 **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
|
||||
IDirectDraw4_AddRef(*(IDirectDraw4 **) DD);
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
*((IDirectDraw **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw);
|
||||
IDirectDraw_AddRef( *(IDirectDraw **) DD);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ unsigned long getRefcount(IUnknown *iface)
|
||||
return IUnknown_Release(iface);
|
||||
}
|
||||
|
||||
static void test_ddraw(void)
|
||||
static void test_ddraw_objects(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
unsigned long ref;
|
||||
@ -135,6 +135,248 @@ static void test_ddraw(void)
|
||||
IDirectDraw7_Release(DDraw);
|
||||
}
|
||||
|
||||
static void test_iface_refcnt(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
IDirectDraw *DDraw1;
|
||||
IDirectDraw2 *DDraw2;
|
||||
IDirectDraw4 *DDraw4;
|
||||
IDirectDraw7 *DDraw7;
|
||||
IDirect3D7 *D3D7;
|
||||
IDirect3D3 *D3D3;
|
||||
IDirect3D2 *D3D2;
|
||||
IDirect3D *D3D1;
|
||||
long ref;
|
||||
|
||||
hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
|
||||
ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %lx\n", hr);
|
||||
if(!DDraw7)
|
||||
{
|
||||
trace("Couldn't create DDraw interface, skipping tests\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ref = getRefcount( (IUnknown *) DDraw7);
|
||||
ok(ref == 1, "Initial IDirectDraw7 reference count is %ld\n", ref);
|
||||
|
||||
hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
|
||||
ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
|
||||
hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
|
||||
ok(hr == DD_OK, "IDirectDraw7_QueryInterf&ace returned %08lx\n", hr);
|
||||
hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
|
||||
ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
|
||||
|
||||
/* All interfaces now have refcount 1! */
|
||||
ref = getRefcount( (IUnknown *) DDraw7);
|
||||
ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw7);
|
||||
ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw4);
|
||||
ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw2);
|
||||
ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
|
||||
|
||||
hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D7, (void **) &D3D7);
|
||||
ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
|
||||
|
||||
/* Apparently IDirectDrawX and IDirect3DX are linked together */
|
||||
ref = getRefcount( (IUnknown *) D3D7);
|
||||
ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw7);
|
||||
ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
|
||||
|
||||
IDirectDraw7_AddRef(DDraw7);
|
||||
ref = getRefcount( (IUnknown *) D3D7);
|
||||
ok(ref == 3, "IDirect3D7 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw7);
|
||||
ok(ref == 3, "IDirectDraw7 reference count is %ld\n", ref);
|
||||
|
||||
IDirect3D7_Release(D3D7);
|
||||
ref = getRefcount( (IUnknown *) D3D7);
|
||||
ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw7);
|
||||
ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);
|
||||
|
||||
/* Can't get older d3d interfaces. WHY????? */
|
||||
hr = IDirectDraw7_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
|
||||
if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
|
||||
|
||||
hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
|
||||
if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);
|
||||
|
||||
hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D2, (void **) &D3D2);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
|
||||
if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
|
||||
|
||||
hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
|
||||
if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);
|
||||
|
||||
hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D, (void **) &D3D1);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08lx\n", hr);
|
||||
if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
|
||||
|
||||
hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
|
||||
|
||||
hr = IDirect3D7_QueryInterface(D3D7, &IID_IDirect3D, (void **) &D3D1);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirect3D7_QueryInterface returned %08lx\n", hr);
|
||||
if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);
|
||||
|
||||
/* Try an AddRef, it only affects the AddRefed interface */
|
||||
IDirectDraw4_AddRef(DDraw4);
|
||||
ref = getRefcount( (IUnknown *) DDraw7);
|
||||
ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* <-- From the d3d query */
|
||||
ref = getRefcount( (IUnknown *) DDraw4);
|
||||
ok(ref == 2, "IDirectDraw4 reference count is %ld\n", ref); /* <-- The AddRef call */
|
||||
ref = getRefcount( (IUnknown *) DDraw2);
|
||||
ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) D3D7);
|
||||
ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); /* <-- From the d3d query */
|
||||
IDirectDraw4_Release(DDraw4);
|
||||
|
||||
/* Make sure that they are one object, not different ones */
|
||||
hr = IDirectDraw4_SetCooperativeLevel(DDraw4, GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
||||
ok(hr == DD_OK, "IDirectDraw4::SetCooperativeLevel returned %08lx\n", hr);
|
||||
/* After an window has been set, DDSCL_SETFOCUSWINDOW should return DDERR_HWNDALREADYSET, see the mode test */
|
||||
hr = IDirectDraw7_SetCooperativeLevel(DDraw7, NULL, DDSCL_SETFOCUSWINDOW);
|
||||
ok(hr == DDERR_HWNDALREADYSET, "IDirectDraw7::SetCooperativeLevel returned %08lx\n", hr);
|
||||
|
||||
/* All done, release all interfaces */
|
||||
IDirectDraw7_Release(DDraw7);
|
||||
IDirectDraw4_Release(DDraw4);
|
||||
IDirectDraw2_Release(DDraw2);
|
||||
IDirectDraw_Release(DDraw1);
|
||||
IDirect3D7_Release(D3D7);
|
||||
}
|
||||
|
||||
static void test_d3d_ifaces(void)
|
||||
{
|
||||
IDirectDraw *DDraw1;
|
||||
IDirectDraw2 *DDraw2;
|
||||
IDirectDraw4 *DDraw4;
|
||||
IDirect3D *D3D1;
|
||||
IDirect3D2 *D3D2;
|
||||
IDirect3D3 *D3D3;
|
||||
IDirect3D7 *D3D7;
|
||||
HRESULT hr;
|
||||
long ref;
|
||||
|
||||
hr = DirectDrawCreate(NULL, &DDraw1, NULL);
|
||||
ok(hr == DD_OK, "DirectDrawCreate returned %08lx\n", hr);
|
||||
if(!DDraw1)
|
||||
{
|
||||
trace("DirectDrawCreate failed with %08lx\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw2, (void **) &DDraw2);
|
||||
ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw4, (void **) &DDraw4);
|
||||
ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
|
||||
ref = getRefcount( (IUnknown *) DDraw4);
|
||||
ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw2);
|
||||
ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
|
||||
|
||||
hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
|
||||
ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
ref = getRefcount( (IUnknown *) DDraw4);
|
||||
ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw2);
|
||||
ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
|
||||
IDirect3D_Release(D3D1);
|
||||
|
||||
hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
|
||||
ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
ref = getRefcount( (IUnknown *) DDraw4);
|
||||
ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw2);
|
||||
ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
|
||||
IDirect3D2_Release(D3D2);
|
||||
|
||||
hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
|
||||
ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
ref = getRefcount( (IUnknown *) DDraw4);
|
||||
ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw2);
|
||||
ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
|
||||
IDirect3D3_Release(D3D3);
|
||||
|
||||
/* Try to AddRef the D3D3 interface that has been released already */
|
||||
IDirect3D3_AddRef(D3D3);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) D3D3);
|
||||
ok(ref == 2, "IDirect3D3 reference count is %ld\n", ref);
|
||||
/* The newer interfaces remain untouched */
|
||||
ref = getRefcount( (IUnknown *) DDraw4);
|
||||
ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw2);
|
||||
ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
|
||||
IDirect3D3_Release(D3D3);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
|
||||
ref = getRefcount( (IUnknown *) DDraw1);
|
||||
ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
|
||||
|
||||
/* It is possible to query any IDirect3D interfaces from any IDirectDraw interface,
|
||||
* Except IDirect3D7, it can only be returned by IDirectDraw7(which can't return older ifaces)
|
||||
*/
|
||||
hr = IDirectDraw_QueryInterface(DDraw2, &IID_IDirect3D, (void **) &D3D1);
|
||||
ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
|
||||
IDirect3D_Release(D3D1);
|
||||
hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D, (void **) &D3D1);
|
||||
ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
|
||||
IDirect3D_Release(D3D1);
|
||||
|
||||
hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D2, (void **) &D3D2);
|
||||
ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
IDirect3D_Release(D3D2);
|
||||
hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D2, (void **) &D3D2);
|
||||
ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
|
||||
IDirect3D_Release(D3D2);
|
||||
|
||||
hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D3, (void **) &D3D3);
|
||||
ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
IDirect3D_Release(D3D3);
|
||||
hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D3, (void **) &D3D3);
|
||||
ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
|
||||
IDirect3D_Release(D3D3);
|
||||
|
||||
/* This does NOT work */
|
||||
hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D7, (void **) &D3D7);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08lx\n", hr);
|
||||
if(D3D7) IDirect3D_Release(D3D7);
|
||||
hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D7, (void **) &D3D7);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08lx\n", hr);
|
||||
if(D3D7) IDirect3D_Release(D3D7);
|
||||
hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D7, (void **) &D3D7);
|
||||
todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08lx\n", hr);
|
||||
if(D3D7) IDirect3D_Release(D3D7);
|
||||
|
||||
/* Release the interfaces */
|
||||
IDirectDraw4_Release(DDraw4);
|
||||
IDirectDraw2_Release(DDraw2);
|
||||
IDirectDraw_Release(DDraw1);
|
||||
}
|
||||
|
||||
START_TEST(refcount)
|
||||
{
|
||||
init_function_pointers();
|
||||
@ -143,5 +385,7 @@ START_TEST(refcount)
|
||||
trace("function DirectDrawCreateEx not available, skipping tests\n");
|
||||
return;
|
||||
}
|
||||
test_ddraw();
|
||||
test_ddraw_objects();
|
||||
test_iface_refcnt();
|
||||
test_d3d_ifaces();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user