Henri Verbeet : wined3d: Make context_create() work if the window is already destroyed.

Alexandre Julliard julliard at winehq.org
Wed Jul 6 13:31:06 CDT 2011


Module: wine
Branch: master
Commit: 590505c0a472badcecc1767d3be11eededa3651c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=590505c0a472badcecc1767d3be11eededa3651c

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Jul  5 22:30:53 2011 +0200

wined3d: Make context_create() work if the window is already destroyed.

---

 dlls/wined3d/context.c         |   61 ++++++++++++++-------------------------
 dlls/wined3d/swapchain.c       |   25 ++++++++++++++++
 dlls/wined3d/wined3d_private.h |    1 +
 3 files changed, 48 insertions(+), 39 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 7895156..9329977 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -713,58 +713,36 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
 
     if (!pwglMakeCurrent(ctx->hdc, ctx->glCtx))
     {
+        HDC dc;
+
         WARN("Failed to make GL context %p current on device context %p, last error %#x.\n",
                 ctx->glCtx, ctx->hdc, GetLastError());
         ctx->valid = 0;
         WARN("Trying fallback to the backup window.\n");
 
-        if (!swapchain->backup_dc)
+        if (!(dc = swapchain_get_backup_dc(swapchain)))
         {
-            TRACE("Creating the backup window for swapchain %p.\n", swapchain);
-            swapchain->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
-                    WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
-            if (!swapchain->backup_wnd)
-            {
-                ERR("Failed to create a window.\n");
-                goto fail;
-            }
-            swapchain->backup_dc = GetDC(swapchain->backup_wnd);
-            if (!swapchain->backup_dc)
-            {
-                ERR("Failed to get a DC.\n");
-                goto fail;
-            }
-            if (!context_set_pixel_format(ctx->gl_info, swapchain->backup_dc, ctx->pixel_format))
-            {
-                ERR("Failed to set pixel format %d on device context %p.\n",
-                        ctx->pixel_format, swapchain->backup_dc);
-                goto fail;
-            }
+            context_set_current(NULL);
+            return FALSE;
+        }
+
+        if (!context_set_pixel_format(ctx->gl_info, dc, ctx->pixel_format))
+        {
+            ERR("Failed to set pixel format %d on device context %p.\n",
+                    ctx->pixel_format, dc);
+            context_set_current(NULL);
+            return FALSE;
         }
 
-        if (!pwglMakeCurrent(swapchain->backup_dc, ctx->glCtx))
+        if (!pwglMakeCurrent(dc, ctx->glCtx))
         {
             ERR("Fallback to backup window (dc %p) failed too, last error %#x.\n",
-                    swapchain->backup_dc, GetLastError());
+                    dc, GetLastError());
             context_set_current(NULL);
             return FALSE;
         }
     }
     return TRUE;
-
-fail:
-    if (swapchain->backup_dc)
-    {
-        ReleaseDC(swapchain->backup_wnd, swapchain->backup_dc);
-        swapchain->backup_dc = NULL;
-    }
-    if (swapchain->backup_wnd)
-    {
-        DestroyWindow(swapchain->backup_wnd);
-        swapchain->backup_wnd = NULL;
-    }
-    context_set_current(NULL);
-    return FALSE;
 }
 
 static void context_restore_gl_context(HDC dc, HGLRC gl_ctx)
@@ -1272,8 +1250,13 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
 
     if (!(hdc = GetDC(swapchain->win_handle)))
     {
-        ERR("Failed to retrieve a device context.\n");
-        goto out;
+        WARN("Failed to retireve device context, trying swapchain backup.\n");
+
+        if (!(hdc = swapchain_get_backup_dc(swapchain)))
+        {
+            ERR("Failed to retrieve a device context.\n");
+            goto out;
+        }
     }
 
     color_format = target->resource.format;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index dc1800a..5848f37 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1197,3 +1197,28 @@ void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, U
     *width = context->current_rt->resource.width;
     *height = context->current_rt->resource.height;
 }
+
+HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain)
+{
+    if (!swapchain->backup_dc)
+    {
+        TRACE("Creating the backup window for swapchain %p.\n", swapchain);
+
+        if (!(swapchain->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
+                WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL)))
+        {
+            ERR("Failed to create a window.\n");
+            return NULL;
+        }
+
+        if (!(swapchain->backup_dc = GetDC(swapchain->backup_wnd)))
+        {
+            ERR("Failed to get a DC.\n");
+            DestroyWindow(swapchain->backup_wnd);
+            swapchain->backup_wnd = NULL;
+            return NULL;
+        }
+    }
+
+    return swapchain->backup_dc;
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1fedc9c..7025faa 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2455,6 +2455,7 @@ void x11_copy_to_screen(struct wined3d_swapchain *swapchain, const RECT *rect) D
 
 struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 
 #define DEFAULT_REFRESH_RATE 0
 




More information about the wine-cvs mailing list