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