[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