From 242cdaee822f0533f5c84932c7be460e332f14ca Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Fri, 25 Nov 2022 19:20:57 +0100 Subject: [PATCH] wined3d: Move backup window / DC handling from the swapchain to the device. --- dlls/wined3d/context_gl.c | 16 +++++++-------- dlls/wined3d/device.c | 35 +++++++++++++++++++++++++++++++++ dlls/wined3d/swapchain.c | 36 ++-------------------------------- dlls/wined3d/wined3d_private.h | 8 ++++---- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index c790157fd0a..66e4321dd12 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -1258,7 +1258,7 @@ success: static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context_gl) { - struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(context_gl->c.swapchain); + struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); BOOL backup = FALSE; if (!wined3d_context_gl_set_pixel_format(context_gl)) @@ -1275,23 +1275,20 @@ static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context context_gl->valid = 0; WARN("Trying fallback to the backup window.\n"); - /* FIXME: If the context is destroyed it's no longer associated with - * a swapchain, so we can't use the swapchain to get a backup dc. To - * make this work windowless contexts would need to be handled by the - * device. */ - if (context_gl->c.destroyed || !swapchain_gl) + if (context_gl->c.destroyed) { FIXME("Unable to get backup dc for destroyed context %p.\n", context_gl); wined3d_context_gl_set_current(NULL); return FALSE; } - if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(device_gl))) { wined3d_context_gl_set_current(NULL); return FALSE; } + TRACE("Using backup DC %p.\n", context_gl->dc); context_gl->dc_is_private = TRUE; context_gl->dc_has_format = FALSE; @@ -2032,7 +2029,7 @@ static BOOL wined3d_context_gl_create_wgl_ctx(struct wined3d_context_gl *context context_gl->pixel_format, context_gl->dc); wined3d_release_dc(context_gl->window, context_gl->dc); - if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(wined3d_device_gl(device)))) { ERR("Failed to retrieve the backup device context.\n"); return FALSE; @@ -2109,7 +2106,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi if (!context_gl->dc) { - if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(wined3d_device_gl(device)))) { ERR("Failed to retrieve a device context.\n"); return E_FAIL; @@ -2354,6 +2351,7 @@ void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) context_gl->c.destroy_delayed = 1; /* FIXME: Get rid of a pointer to swapchain from wined3d_context. */ context_gl->c.swapchain = NULL; + context_gl->c.device = NULL; return; } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b7d0b1adebc..7d2d9a61552 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1225,6 +1225,14 @@ void wined3d_device_gl_delete_opengl_contexts_cs(void *object) else wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); } + + if (device_gl->backup_dc) + { + TRACE("Destroying backup wined3d window %p, dc %p.\n", device_gl->backup_wnd, device_gl->backup_dc); + + wined3d_release_dc(device_gl->backup_wnd, device_gl->backup_dc); + DestroyWindow(device_gl->backup_wnd); + } } void wined3d_device_gl_create_primary_opengl_context_cs(void *object) @@ -5913,6 +5921,33 @@ void CDECL wined3d_device_get_gamma_ramp(const struct wined3d_device *device, wined3d_swapchain_get_gamma_ramp(swapchain, ramp); } +HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl) +{ + TRACE("device_gl %p.\n", device_gl); + + if (!device_gl->backup_dc) + { + TRACE("Creating the backup window for device %p.\n", device_gl); + + if (!(device_gl->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 (!(device_gl->backup_dc = GetDC(device_gl->backup_wnd))) + { + ERR("Failed to get a DC.\n"); + DestroyWindow(device_gl->backup_wnd); + device_gl->backup_wnd = NULL; + return NULL; + } + } + + return device_gl->backup_dc; +} + void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) { TRACE("device %p, resource %p.\n", device, resource); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 1712cda2373..79ee427572f 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -98,14 +98,6 @@ void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) wined3d_cs_destroy_object(cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); - - if (swapchain_gl->backup_dc) - { - TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain_gl->backup_wnd, swapchain_gl->backup_dc); - - wined3d_release_dc(swapchain_gl->backup_wnd, swapchain_gl->backup_dc); - DestroyWindow(swapchain_gl->backup_wnd); - } } static void wined3d_swapchain_vk_destroy_vulkan_swapchain(struct wined3d_swapchain_vk *swapchain_vk) @@ -610,7 +602,8 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, TRACE("Presenting DC %p.\n", context_gl->dc); pixel_format = &wined3d_adapter_gl(swapchain->device->adapter)->pixel_formats[context_gl->pixel_format]; - if (context_gl->dc == swapchain_gl->backup_dc || (pixel_format->swap_method != WGL_SWAP_COPY_ARB + if (context_gl->dc == wined3d_device_gl(swapchain->device)->backup_dc + || (pixel_format->swap_method != WGL_SWAP_COPY_ARB && swapchain_present_is_partial_copy(swapchain, dst_rect))) { swapchain_blit_gdi(swapchain, context, src_rect, dst_rect); @@ -1842,31 +1835,6 @@ struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapc return wined3d_swapchain_gl_create_context(swapchain_gl); } -HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) -{ - if (!swapchain_gl->backup_dc) - { - TRACE("Creating the backup window for swapchain %p.\n", swapchain_gl); - - if (!(swapchain_gl->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_gl->backup_dc = GetDC(swapchain_gl->backup_wnd))) - { - ERR("Failed to get a DC.\n"); - DestroyWindow(swapchain_gl->backup_wnd); - swapchain_gl->backup_wnd = NULL; - return NULL; - } - } - - return swapchain_gl->backup_dc; -} - void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) { UINT i; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index cbee46740b1..47904390ed3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4294,6 +4294,9 @@ struct wined3d_device_gl } *retired_blocks; SIZE_T retired_blocks_size; SIZE_T retired_block_count; + + HWND backup_wnd; + HDC backup_dc; }; static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device *device) @@ -4331,6 +4334,7 @@ bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN; void wined3d_device_gl_create_primary_opengl_context_cs(void *object) DECLSPEC_HIDDEN; void wined3d_device_gl_delete_opengl_contexts_cs(void *object) DECLSPEC_HIDDEN; +HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl) DECLSPEC_HIDDEN; GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx) DECLSPEC_HIDDEN; static inline float wined3d_alpha_ref(const struct wined3d_state *state) @@ -5708,9 +5712,6 @@ struct wined3d_swapchain_gl struct wined3d_context_gl **contexts; SIZE_T contexts_size; SIZE_T context_count; - - HDC backup_dc; - HWND backup_wnd; }; static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_swapchain *swapchain) @@ -5720,7 +5721,6 @@ static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_s void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; -HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_device *device, struct wined3d_swapchain_desc *desc,