ddraw: Cope with Init3D failures.

oldstable
Stefan Dösinger 2007-10-09 14:42:06 +02:00 committed by Alexandre Julliard
parent 8fc4e3cec7
commit c5055fb3eb
3 changed files with 26 additions and 6 deletions

View File

@ -2519,10 +2519,6 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
return hr;
}
/* 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
* a primary surface (2D app in 3D mode) or a 3DDEVICE surface (3D app)
@ -2555,10 +2551,32 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
hr = IDirectDrawImpl_AttachD3DDevice(This, target);
if(hr != D3D_OK)
{
IDirectDrawSurfaceImpl *release_surf;
ERR("IDirectDrawImpl_AttachD3DDevice failed, hr = %x\n", hr);
*Surf = NULL;
/* The before created surface structures are in an incomplete state here.
* WineD3D holds the reference on the IParents, and it released them on the failure
* already. So the regular release method implementation would fail on the attempt
* to destroy either the IParents or the swapchain. So free the surface here.
* The surface structure here is a list, not a tree, because onscreen targets
* cannot be cube textures
*/
while(object)
{
release_surf = object;
object = object->complex_array[0];
IDirectDrawSurfaceImpl_Destroy(release_surf);
}
LeaveCriticalSection(&ddraw_cs);
return hr;
}
}
/* Addref the ddraw interface to keep an reference for each surface */
IDirectDraw7_AddRef(iface);
object->ifaceToRelease = (IUnknown *) iface;
/* Create a WineD3DTexture if a texture was requested */
if(desc2.ddsCaps.dwCaps & DDSCAPS_TEXTURE)
{
@ -3077,7 +3095,8 @@ IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This,
D3D7CB_CreateAdditionalSwapChain);
if(FAILED(hr))
{
This->wineD3DDevice = NULL;
This->d3d_target = NULL;
This->d3d_initialized = FALSE;
return hr;
}

View File

@ -273,6 +273,7 @@ const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl;
const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl;
HRESULT WINAPI IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *Surf);
void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This);
/* Get the number of bytes per pixel for a given surface */
#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.dwRGBBitCount+7)/8))

View File

@ -178,7 +178,7 @@ IDirectDrawSurfaceImpl_AddRef(IDirectDrawSurface7 *iface)
* This: Surface to free
*
*****************************************************************************/
static void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This)
void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This)
{
TRACE("(%p)\n", This);