[PATCH 2/5] ddraw: Store the wined3d swapchain reference in the ddraw object instead of the primary surface.
Henri Verbeet
hverbeet at codeweavers.com
Mon Sep 19 14:50:24 CDT 2011
The idea behind this (and the previous patch) is that we'd like to create the
wined3d swapchain before the ddraw primary is created.
---
dlls/ddraw/ddraw.c | 49 +++++++++----------------
dlls/ddraw/ddraw_private.h | 2 +-
dlls/ddraw/surface.c | 84 +++++++++++++++++++++++--------------------
3 files changed, 64 insertions(+), 71 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 5b3b0e2..18fe07f 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -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;
}
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index bc48ad1..0572172 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -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;
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 96caa3f..4cd1452 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -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);
--
1.7.3.4
More information about the wine-patches
mailing list