[PATCH 0/1] MR9637: wined3d: Create / release the window DCs with the swapchains.
Wine-Bug: http://bugs.winehq.org/show_bug.cgi?id=58491 This fixes a regression introduced with a085746bbe3594e4ea01ea578823383e6447b6b6, as contrary to what I thought wined3d aren't specific to a given window but may be used alternatively on different windows, with `wined3d_context_gl_update_window` called when they switch. This causes DCs to be released / acquired every time window is switched and it triggers destruction and recreation of the underlying D3D OpenGL drawables. Keeping the DCs with the swapchains is probably a better fit anyway, and they already need some for fallback GDI blits. The GL contexts does not own its DC anymore, but simply uses either its active swapchain DC or the device backup DC. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9637
From: Rémi Bernon <rbernon(a)codeweavers.com> Wine-Bug: http://bugs.winehq.org/show_bug.cgi?id=58491 --- dlls/wined3d/context_gl.c | 17 ++--------------- dlls/wined3d/swapchain.c | 29 +++++++++++++++++++---------- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index ac1b9370fc1..a13718bba92 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -1286,7 +1286,6 @@ static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context return FALSE; } - wined3d_release_dc(context_gl->window, context_gl->dc); if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(device_gl))) { wined3d_context_gl_set_current(NULL); @@ -1341,21 +1340,13 @@ static void wined3d_context_gl_update_window(struct wined3d_context_gl *context_ TRACE("Updating context %p window from %p to %p.\n", context_gl, context_gl->window, context_gl->c.swapchain->win_handle); - if (context_gl->dc) - wined3d_release_dc(context_gl->window, context_gl->dc); - context_gl->window = context_gl->c.swapchain->win_handle; + context_gl->dc = context_gl->c.swapchain->dc; context_gl->dc_is_private = FALSE; context_gl->dc_has_format = FALSE; context_gl->needs_set = 1; context_gl->valid = 1; context_gl->internal_format_set = 0; - - if (!(context_gl->dc = GetDCEx(context_gl->window, 0, DCX_USESTYLE | DCX_CACHE))) - { - ERR("Failed to get a device context for window %p.\n", context_gl->window); - context_gl->valid = 0; - } } static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl) @@ -1542,8 +1533,6 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl) else if (wglGetCurrentContext() && !wglMakeCurrent(NULL, NULL)) ERR("Failed to disable GL context.\n"); - wined3d_release_dc(context_gl->window, context_gl->dc); - if (!wglDeleteContext(context_gl->gl_ctx)) { unsigned int err = GetLastError(); @@ -1981,7 +1970,6 @@ static BOOL wined3d_context_gl_create_wgl_ctx(struct wined3d_context_gl *context WARN("Failed to set pixel format %d on device context %p, trying backup DC.\n", context_gl->pixel_format, context_gl->dc); - wined3d_release_dc(context_gl->window, context_gl->dc); if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(wined3d_device_gl(device)))) { ERR("Failed to retrieve the backup device context.\n"); @@ -2054,7 +2042,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi TRACE("Swapchain is created on the desktop window, trying backup device context.\n"); context_gl->dc = NULL; } - else if (!(context_gl->dc = GetDCEx(context_gl->window, 0, DCX_USESTYLE | DCX_CACHE))) + else if (!(context_gl->dc = swapchain_gl->s.dc)) WARN("Failed to retrieve device context, trying swapchain backup.\n"); if (!context_gl->dc) @@ -2301,7 +2289,6 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi fail: free(context_gl->texture_type); - wined3d_release_dc(context_gl->window, context_gl->dc); return E_FAIL; } diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index a1000ec2393..2384a3d03d2 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -158,6 +158,9 @@ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain) wined3d_device_uninit_3d(device); wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (swapchain->dc) + wined3d_release_dc(swapchain->win_handle, swapchain->dc); + swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent); swapchain->device->adapter->adapter_ops->adapter_destroy_swapchain(swapchain); @@ -186,7 +189,13 @@ void CDECL wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWN wined3d_cs_finish(swapchain->device->cs, WINED3D_CS_QUEUE_DEFAULT); + if (swapchain->dc) + wined3d_release_dc(swapchain->win_handle, swapchain->dc); + swapchain->win_handle = window; + + if (!(swapchain->dc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE))) + WARN("Failed to retrieve device context, trying swapchain backup.\n"); } HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, @@ -404,9 +413,9 @@ static void swapchain_blit_gdi(struct wined3d_swapchain *swapchain, D3DKMT_CREATEDCFROMMEMORY create_desc; const struct wined3d_format *format; unsigned int row_pitch, slice_pitch; - HDC src_dc, dst_dc; NTSTATUS status; HBITMAP bitmap; + HDC src_dc; static unsigned int once; @@ -447,15 +456,11 @@ static void swapchain_blit_gdi(struct wined3d_swapchain *swapchain, TRACE("Created source DC %p, bitmap %p for backbuffer %p.\n", src_dc, bitmap, back_buffer); - if (!(dst_dc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE))) - ERR("Failed to get destination DC.\n"); - - if (!StretchBlt(dst_dc, dst_rect->left, dst_rect->top, dst_rect->right - dst_rect->left, + if (!StretchBlt(swapchain->dc, dst_rect->left, dst_rect->top, dst_rect->right - dst_rect->left, dst_rect->bottom - dst_rect->top, src_dc, src_rect->left, src_rect->top, src_rect->right - src_rect->left, src_rect->bottom - src_rect->top, SRCCOPY)) ERR("Failed to blit.\n"); - ReleaseDC(swapchain->win_handle, dst_dc); destroy_desc.hDc = src_dc; destroy_desc.hBitmap = bitmap; if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc))) @@ -1276,9 +1281,9 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai { struct wined3d_dc_info *front; POINT offset = {0, 0}; - HDC src_dc, dst_dc; RECT draw_rect; HWND window; + HDC src_dc; TRACE("swapchain %p.\n", swapchain); @@ -1293,7 +1298,6 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai src_dc = front->dc; window = swapchain->win_handle; - dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE); /* Front buffer coordinates are screen coordinates. Map them to the * destination window if not fullscreened. */ @@ -1306,10 +1310,9 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai swapchain->front_buffer->resource.height); IntersectRect(&draw_rect, &draw_rect, &swapchain->front_buffer_update); - BitBlt(dst_dc, draw_rect.left - offset.x, draw_rect.top - offset.y, + BitBlt(swapchain->dc, draw_rect.left - offset.x, draw_rect.top - offset.y, draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top, src_dc, draw_rect.left, draw_rect.top, SRCCOPY); - ReleaseDC(window, dst_dc); SetRectEmpty(&swapchain->front_buffer_update); } @@ -1551,6 +1554,9 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT; swapchain_set_max_frame_latency(swapchain, device); + if (!(swapchain->dc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE))) + WARN("Failed to retrieve device context, trying swapchain backup.\n"); + if (!swapchain->state.desc.windowed) { if (FAILED(hr = wined3d_output_get_desc(desc->output, &output_desc))) @@ -1681,6 +1687,9 @@ err: wined3d_texture_decref(swapchain->front_buffer); } + if (swapchain->dc) + wined3d_release_dc(swapchain->win_handle, swapchain->dc); + wined3d_swapchain_state_cleanup(&swapchain->state); wined3d_mutex_unlock(); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7b955d798f8..d9e06c79ece 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4120,6 +4120,7 @@ struct wined3d_swapchain struct wined3d_swapchain_state state; HWND win_handle; + HDC dc; }; void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9637
This merge request was approved by Elizabeth Figura. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9637
participants (2)
-
Elizabeth Figura (@zfigura) -
Rémi Bernon