ddraw: Store the wined3d swapchain reference in the ddraw object instead of the primary surface.

This commit is contained in:
Henri Verbeet 2011-09-19 21:50:24 +02:00 committed by Alexandre Julliard
parent cc45316d02
commit 4228bbc5bf
3 changed files with 64 additions and 71 deletions

View File

@ -2533,23 +2533,6 @@ static HRESULT ddraw_attach_d3d_device(IDirectDrawImpl *ddraw, IDirectDrawSurfac
return DD_OK;
}
static HRESULT ddraw_create_gdi_swapchain(IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *primary,
WINED3DPRESENT_PARAMETERS *presentation_parameters)
{
HRESULT hr;
ddraw->d3d_target = primary;
hr = wined3d_device_init_gdi(ddraw->wined3d_device, presentation_parameters);
ddraw->d3d_target = NULL;
if (FAILED(hr))
{
WARN("Failed to initialize GDI ddraw implementation, hr %#x.\n", hr);
primary->wined3d_swapchain = NULL;
}
return hr;
}
static HRESULT ddraw_create_swapchain(IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *surface)
{
WINED3DPRESENT_PARAMETERS presentation_parameters;
@ -2596,7 +2579,18 @@ static HRESULT ddraw_create_swapchain(IDirectDrawImpl *ddraw, IDirectDrawSurface
}
else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
hr = ddraw_create_gdi_swapchain(ddraw, target, &presentation_parameters);
hr = wined3d_device_init_gdi(ddraw->wined3d_device, &presentation_parameters);
if (FAILED(hr))
WARN("Failed to initialize GDI ddraw implementation, hr %#x.\n", hr);
}
if (SUCCEEDED(hr))
{
if (FAILED(hr = wined3d_device_get_swapchain(ddraw->wined3d_device, 0, &ddraw->wined3d_swapchain)))
{
ERR("Failed to get swapchain, hr %#x.\n", hr);
ddraw->wined3d_swapchain = NULL;
}
}
return hr;
@ -5341,27 +5335,20 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent
WINED3DPRESENT_PARAMETERS *present_parameters, struct wined3d_swapchain **swapchain)
{
struct IDirectDrawImpl *ddraw = ddraw_from_device_parent(device_parent);
IDirectDrawSurfaceImpl *iterator;
HRESULT hr;
TRACE("device_parent %p, present_parameters %p, swapchain %p.\n", device_parent, present_parameters, swapchain);
if (ddraw->wined3d_swapchain)
{
ERR("Swapchain already created.\n");
return E_FAIL;
}
hr = wined3d_swapchain_create(ddraw->wined3d_device, present_parameters,
DefaultSurfaceType, NULL, &ddraw_null_wined3d_parent_ops, swapchain);
if (FAILED(hr))
{
WARN("Failed to create swapchain, hr %#x.\n", hr);
*swapchain = NULL;
return hr;
}
ddraw->d3d_target->wined3d_swapchain = *swapchain;
iterator = ddraw->d3d_target->complex_array[0];
while (iterator)
{
iterator->wined3d_swapchain = *swapchain;
iterator = iterator->complex_array[0];
}
return hr;
}

View File

@ -90,6 +90,7 @@ struct IDirectDrawImpl
IDirectDrawSurfaceImpl *primary;
struct wined3d_surface *wined3d_frontbuffer;
struct wined3d_swapchain *wined3d_swapchain;
/* DirectDraw things, which are not handled by WineD3D */
DWORD cooperative_level;
@ -160,7 +161,6 @@ struct IDirectDrawSurfaceImpl
IDirectDrawImpl *ddraw;
struct wined3d_surface *wined3d_surface;
struct wined3d_texture *wined3d_texture;
struct wined3d_swapchain *wined3d_swapchain;
/* This implementation handles attaching surfaces to other surfaces */
IDirectDrawSurfaceImpl *next_attached;

View File

@ -385,21 +385,57 @@ void ddraw_surface_destroy(IDirectDrawSurfaceImpl *This)
static void ddraw_surface_cleanup(IDirectDrawSurfaceImpl *surface)
{
IDirectDrawImpl *ddraw = surface->ddraw;
BOOL destroy_swapchain = FALSE;
IDirectDrawSurfaceImpl *surf;
IUnknown *ifaceToRelease;
UINT i;
TRACE("surface %p.\n", surface);
if (surface->wined3d_swapchain)
if ((ddraw->d3d_initialized && surface == ddraw->d3d_target
&& DefaultSurfaceType == SURFACE_OPENGL)
|| ((surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
&& DefaultSurfaceType != SURFACE_OPENGL))
destroy_swapchain = TRUE;
/* The refcount test shows that the palette is detached when the surface
* is destroyed. */
IDirectDrawSurface7_SetPalette(&surface->IDirectDrawSurface7_iface, NULL);
/* Loop through all complex attached surfaces and destroy them.
*
* Yet again, only the root can have more than one complexly attached
* surface, all the others have a total of one. */
for (i = 0; i < MAX_COMPLEX_ATTACHED; ++i)
{
IDirectDrawImpl *ddraw = surface->ddraw;
if (!surface->complex_array[i])
break;
/* If it's the render target, destroy the D3D device. */
if (ddraw->d3d_initialized && surface == ddraw->d3d_target)
surf = surface->complex_array[i];
surface->complex_array[i] = NULL;
while (surf)
{
TRACE("Destroying the render target, uninitializing D3D.\n");
IDirectDrawSurfaceImpl *destroy = surf;
surf = surf->complex_array[0]; /* Iterate through the "tree" */
ddraw_surface_destroy(destroy); /* Destroy it */
}
}
ifaceToRelease = surface->ifaceToRelease;
/* Destroy the root surface. */
ddraw_surface_destroy(surface);
if (ddraw->wined3d_swapchain && destroy_swapchain)
{
TRACE("Destroying the swapchain.\n");
wined3d_swapchain_decref(ddraw->wined3d_swapchain);
ddraw->wined3d_swapchain = NULL;
if (DefaultSurfaceType == SURFACE_OPENGL)
{
for (i = 0; i < ddraw->numConvertedDecls; ++i)
{
wined3d_vertex_declaration_decref(ddraw->decls[i].decl);
@ -430,39 +466,9 @@ static void ddraw_surface_cleanup(IDirectDrawSurfaceImpl *surface)
wined3d_device_uninit_gdi(ddraw->wined3d_device);
}
surface->wined3d_swapchain = NULL;
TRACE("D3D unloaded.\n");
TRACE("Swapchain destroyed.\n");
}
/* The refcount test shows that the palette is detached when the surface
* is destroyed. */
IDirectDrawSurface7_SetPalette(&surface->IDirectDrawSurface7_iface, NULL);
/* Loop through all complex attached surfaces and destroy them.
*
* Yet again, only the root can have more than one complexly attached
* surface, all the others have a total of one. */
for (i = 0; i < MAX_COMPLEX_ATTACHED; ++i)
{
if (!surface->complex_array[i])
break;
surf = surface->complex_array[i];
surface->complex_array[i] = NULL;
while (surf)
{
IDirectDrawSurfaceImpl *destroy = surf;
surf = surf->complex_array[0]; /* Iterate through the "tree" */
ddraw_surface_destroy(destroy); /* Destroy it */
}
}
ifaceToRelease = surface->ifaceToRelease;
/* Destroy the root surface. */
ddraw_surface_destroy(surface);
/* Reduce the ddraw refcount */
if (ifaceToRelease)
IUnknown_Release(ifaceToRelease);
@ -3859,7 +3865,7 @@ static HRESULT WINAPI ddraw_surface7_SetClipper(IDirectDrawSurface7 *iface,
hr = wined3d_surface_set_clipper(This->wined3d_surface,
This->clipper ? This->clipper->wineD3DClipper : NULL);
if (This->wined3d_swapchain)
if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && This->ddraw->wined3d_swapchain)
{
clipWindow = NULL;
if(clipper) {
@ -3867,9 +3873,9 @@ static HRESULT WINAPI ddraw_surface7_SetClipper(IDirectDrawSurface7 *iface,
}
if (clipWindow)
wined3d_swapchain_set_window(This->wined3d_swapchain, clipWindow);
wined3d_swapchain_set_window(This->ddraw->wined3d_swapchain, clipWindow);
else
wined3d_swapchain_set_window(This->wined3d_swapchain, This->ddraw->d3d_window);
wined3d_swapchain_set_window(This->ddraw->wined3d_swapchain, This->ddraw->d3d_window);
}
LeaveCriticalSection(&ddraw_cs);