Commit 1a14a6ef authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

ddraw: Avoid destroying ddraw objects from DllMain().

It's not clear we're supposed to clean up after the application like this, and it seems questionable whether it makes things better in general. Signed-off-by: 's avatarHenri Verbeet <hverbeet@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 3b0e37a0
......@@ -792,52 +792,6 @@ HRESULT WINAPI DllUnregisterServer(void)
return __wine_unregister_resources( instance );
}
/*******************************************************************************
* DestroyCallback
*
* Callback function for the EnumSurfaces call in DllMain.
* Dumps some surface info and releases the surface
*
* Params:
* surf: The enumerated surface
* desc: its description
* context: Pointer to the ddraw impl
*
* Returns:
* DDENUMRET_OK;
*******************************************************************************/
static HRESULT WINAPI
DestroyCallback(IDirectDrawSurface7 *surf,
DDSURFACEDESC2 *desc,
void *context)
{
struct ddraw_surface *Impl = impl_from_IDirectDrawSurface7(surf);
ULONG ref7, ref4, ref3, ref2, ref1, gamma_count, iface_count;
ref7 = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */
ref4 = Impl->ref4;
ref3 = Impl->ref3;
ref2 = Impl->ref2;
ref1 = Impl->ref1;
gamma_count = Impl->gamma_count;
WARN("Surface %p has an reference counts of 7: %u 4: %u 3: %u 2: %u 1: %u gamma: %u\n",
Impl, ref7, ref4, ref3, ref2, ref1, gamma_count);
/* Skip surfaces which are attached somewhere or which are
* part of a complex compound. They will get released when destroying
* the root
*/
if( (!Impl->is_complex_root) || (Impl->first_attached != Impl) )
return DDENUMRET_OK;
/* Destroy the surface */
iface_count = ddraw_surface_release_iface(Impl);
while (iface_count) iface_count = ddraw_surface_release_iface(Impl);
return DDENUMRET_OK;
}
/***********************************************************************
* DllMain (DDRAW.0)
*
......@@ -923,66 +877,26 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
}
case DLL_PROCESS_DETACH:
if(!list_empty(&global_ddraw_list))
if (WARN_ON(ddraw))
{
struct list *entry, *entry2;
WARN("There are still existing DirectDraw interfaces. Wine bug or buggy application?\n");
struct ddraw *ddraw;
/* We remove elements from this loop */
LIST_FOR_EACH_SAFE(entry, entry2, &global_ddraw_list)
LIST_FOR_EACH_ENTRY(ddraw, &global_ddraw_list, struct ddraw, ddraw_list_entry)
{
struct ddraw *ddraw = LIST_ENTRY(entry, struct ddraw, ddraw_list_entry);
HRESULT hr;
DDSURFACEDESC2 desc;
int i;
WARN("DDraw %p has a refcount of %d\n", ddraw, ddraw->ref7 + ddraw->ref4 + ddraw->ref3 + ddraw->ref2 + ddraw->ref1);
/* Add references to each interface to avoid freeing them unexpectedly */
IDirectDraw_AddRef(&ddraw->IDirectDraw_iface);
IDirectDraw2_AddRef(&ddraw->IDirectDraw2_iface);
IDirectDraw4_AddRef(&ddraw->IDirectDraw4_iface);
IDirectDraw7_AddRef(&ddraw->IDirectDraw7_iface);
/* Does a D3D device exist? Destroy it
* TODO: Destroy all Vertex buffers, Lights, Materials
* and execute buffers too
*/
if(ddraw->d3ddevice)
{
WARN("DDraw %p has d3ddevice %p attached\n", ddraw, ddraw->d3ddevice);
while(IDirect3DDevice7_Release(&ddraw->d3ddevice->IDirect3DDevice7_iface));
}
struct ddraw_surface *surface;
/* Destroy the swapchain after any 3D device. The 3D device
* cleanup code needs a swapchain. Specifically, it tries to
* set the current render target to the front buffer. */
if (ddraw->wined3d_swapchain)
ddraw_destroy_swapchain(ddraw);
/* Try to release the objects
* Do an EnumSurfaces to find any hanging surfaces
*/
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
for(i = 0; i <= 1; i++)
{
hr = IDirectDraw7_EnumSurfaces(&ddraw->IDirectDraw7_iface, DDENUMSURFACES_ALL,
&desc, ddraw, DestroyCallback);
if(hr != D3D_OK)
ERR("(%p) EnumSurfaces failed, prepare for trouble\n", ddraw);
}
WARN("DirectDraw object %p has reference counts {%u, %u, %u, %u, %u}.\n",
ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1);
if (!list_empty(&ddraw->surface_list))
ERR("DDraw %p still has surfaces attached.\n", ddraw);
if (ddraw->d3ddevice)
WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice);
/* Release all hanging references to destroy the objects. This
* restores the screen mode too
*/
while(IDirectDraw_Release(&ddraw->IDirectDraw_iface));
while(IDirectDraw2_Release(&ddraw->IDirectDraw2_iface));
while(IDirectDraw4_Release(&ddraw->IDirectDraw4_iface));
while(IDirectDraw7_Release(&ddraw->IDirectDraw7_iface));
LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry)
{
WARN("Surface %p has reference counts {%u, %u, %u, %u, %u, %u}.\n",
surface, surface->ref7, surface->ref4, surface->ref3,
surface->ref2, surface->ref1, surface->gamma_count);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment