Module: wine Branch: master Commit: a3c12c5be426ac9ac19b7760eeeec1f2c1dbe551 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a3c12c5be426ac9ac19b7760ee...
Author: Matteo Bruni mbruni@codeweavers.com Date: Tue Apr 12 22:27:54 2011 +0200
wined3d: Fallback to our private window when context activation fails otherwise.
---
dlls/wined3d/context.c | 51 ++++++++++++++++++++++++++++++++++++++- dlls/wined3d/swapchain.c | 8 ++++++ dlls/wined3d/wined3d_private.h | 3 ++ 3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 544d662..18c9438 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -795,15 +795,62 @@ static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC
static BOOL context_set_gl_context(struct wined3d_context *ctx) { + struct wined3d_swapchain *swapchain = ctx->swapchain; + if (!pwglMakeCurrent(ctx->hdc, ctx->glCtx)) { WARN("Failed to make GL context %p current on device context %p, last error %#x.\n", ctx->glCtx, ctx->hdc, GetLastError()); ctx->valid = 0; - context_set_current(NULL); - return FALSE; + WARN("Trying fallback to the backup window.\n"); + + if (!swapchain->backup_dc) + { + 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; + } + } + + if (!pwglMakeCurrent(swapchain->backup_dc, ctx->glCtx)) + { + ERR("Fallback to backup window (dc %p) failed too, last error %#x.\n", + swapchain->backup_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) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 21d518f..275084b 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -80,6 +80,14 @@ static void swapchain_cleanup(struct wined3d_swapchain *swapchain) mode.Format = swapchain->orig_fmt; IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)swapchain->device, 0, &mode); } + + if (swapchain->backup_dc) + { + TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain->backup_wnd, swapchain->backup_dc); + + ReleaseDC(swapchain->backup_wnd, swapchain->backup_dc); + DestroyWindow(swapchain->backup_wnd); + } }
ULONG CDECL wined3d_swapchain_incref(struct wined3d_swapchain *swapchain) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8c90464..1b1fcec 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2543,6 +2543,9 @@ struct wined3d_swapchain
HWND win_handle; HWND device_window; + + HDC backup_dc; + HWND backup_wnd; };
void x11_copy_to_screen(struct wined3d_swapchain *swapchain, const RECT *rect) DECLSPEC_HIDDEN;