Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846
Wine D3D resets the window pixel format to its original value when an internal pixel format was requested and the context done being used, and requests the internal pixel format again before it is used again. When internal pixel format and window pixel format don't match this causes any previously created OpenGL surface with a different format to be released (and destroyed as no context is current with it), creating a new one with the new format, back and forth.
What we actually need here, is to keep the wined3d OpenGL client surface, with the internal pixel format, alive as long as it is being referenced by wined3d, as well as any OpenGL client surface that may have been created, with the window pixel format, by the application itself.
It's not possible to rely on DCs for application-created OpenGL surfaces, as the application is free to release its DC and retrieve another one later on for the same window while still expecting it to use the same OpenGL surface. However with wined3d, we know that the DCs are being kept referenced until the context is being destroyed so we can safely use them to store the wined3d OpenGL surface.
-- v4: wined3d: Remove now unnecessary pixel format restoration. win32u: Get rid of window internal pixel format. win32u: Keep D3D internal OpenGL surfaces on the DCs. wined3d: Call wglSetPixelFormatWINE before releasing context DC. win32u: Set the DC pixel format too in wglSetPixelFormatWINE.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846 --- dlls/win32u/dc.c | 23 +++++++++++++++++ dlls/win32u/ntgdi_private.h | 2 ++ dlls/win32u/opengl.c | 50 ++++++++++++++++++------------------- dlls/win32u/window.c | 2 +- 4 files changed, 51 insertions(+), 26 deletions(-)
diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c index 553be987946..839fd821175 100644 --- a/dlls/win32u/dc.c +++ b/dlls/win32u/dc.c @@ -326,6 +326,29 @@ void release_dc_ptr( DC *dc ) if (ref) dc->thread = GetCurrentThreadId(); /* we still own it */ }
+BOOL is_dc_display( HDC hdc ) +{ + int ret; + DC *dc; + + if (!(dc = get_dc_ptr( hdc ))) return FALSE; + ret = dc->is_display; + release_dc_ptr( dc ); + + return ret; +} + +int get_dc_pixel_format( HDC hdc ) +{ + int ret; + DC *dc; + + if (!(dc = get_dc_ptr( hdc ))) return -1; + ret = dc->pixel_format; + release_dc_ptr( dc ); + + return ret; +}
static void set_bk_color( DC *dc, COLORREF color ) { diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index ba61a7369b5..fcfbce58fea 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -181,6 +181,8 @@ extern DC *alloc_dc_ptr( DWORD magic ); extern void free_dc_ptr( DC *dc ); extern DC *get_dc_ptr( HDC hdc ); extern void release_dc_ptr( DC *dc ); +extern BOOL is_dc_display( HDC hdc ); +extern int get_dc_pixel_format( HDC hdc ); extern struct dce *get_dc_dce( HDC hdc ); extern void set_dc_dce( HDC hdc, struct dce *dce ); extern WORD set_dce_flags( HDC hdc, WORD flags ); diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index fc0be5795d4..2c028625faf 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1269,39 +1269,27 @@ static const char *win32u_wglGetExtensionsStringEXT(void) return wgl_extensions; }
-static int get_dc_pixel_format( HDC hdc, BOOL internal ) +static int win32u_wglGetPixelFormat( HDC hdc ) { - int ret = 0; + BOOL is_display = is_dc_display( hdc ); + int format; HWND hwnd; - DC *dc;
if ((hwnd = NtUserWindowFromDC( hdc ))) - ret = get_window_pixel_format( hwnd, internal ); - else if ((dc = get_dc_ptr( hdc ))) - { - BOOL is_display = dc->is_display; - ret = dc->pixel_format; - release_dc_ptr( dc ); - - /* Offscreen formats can't be used with traditional WGL calls. As has been - * verified on Windows GetPixelFormat doesn't fail but returns 1. - */ - if (is_display && ret >= 0 && ret > onscreen_count) ret = 1; - } - else + format = get_window_pixel_format( hwnd, FALSE ); + else if ((format = get_dc_pixel_format( hdc )) < 0) { WARN( "Invalid DC handle %p\n", hdc ); RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return -1; }
- TRACE( "%p/%p -> %d\n", hdc, hwnd, ret ); - return ret; -} + /* Offscreen formats can't be used with traditional WGL calls. As has been + * verified on Windows GetPixelFormat doesn't fail but returns 1. + */ + if (is_display && format > onscreen_count) format = 1;
-static int win32u_wglGetPixelFormat( HDC hdc ) -{ - int format = get_dc_pixel_format( hdc, FALSE ); + TRACE( "%p/%p -> %d\n", hdc, hwnd, format ); return format > 0 ? format : 0; }
@@ -1511,7 +1499,15 @@ static BOOL win32u_wglSetPixelFormat( HDC hdc, int format, const PIXELFORMATDESC
static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) { - return set_dc_pixel_format( hdc, format, TRUE ); + DC *dc; + + if (format && !set_dc_pixel_format( hdc, format, TRUE )) return FALSE; + + if (!(dc = get_dc_ptr( hdc ))) return FALSE; + dc->pixel_format = format; + release_dc_ptr( dc ); + + return TRUE; }
static PROC win32u_wglGetProcAddress( const char *name ) @@ -1684,10 +1680,12 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct return TRUE; }
- if ((format = get_dc_pixel_format( draw_hdc, TRUE )) <= 0) + if ((format = get_dc_pixel_format( draw_hdc )) <= 0 && + (format = get_window_pixel_format( NtUserWindowFromDC( draw_hdc ), FALSE )) <= 0) { WARN( "Invalid draw_hdc %p format %u\n", draw_hdc, format ); if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); + else RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } if (context->format != format) @@ -2144,9 +2142,11 @@ static BOOL win32u_wgl_context_reset( struct wgl_context *context, HDC hdc, stru context->driver_private = NULL; if (!hdc) return TRUE;
- if ((format = get_dc_pixel_format( hdc, TRUE )) <= 0) + if ((format = get_dc_pixel_format( hdc )) <= 0 && + (format = get_window_pixel_format( NtUserWindowFromDC( hdc ), FALSE )) <= 0) { if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); + else RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } if (!driver_funcs->p_context_create( format, share_private, attribs, &context->driver_private )) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index c5c5d0522c8..8a026a3c189 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1568,7 +1568,7 @@ int get_window_pixel_format( HWND hwnd, BOOL internal ) if (!win || win == WND_DESKTOP || win == WND_OTHER_PROCESS) { WARN( "getting format on win %p not supported\n", hwnd ); - return 0; + return -1; }
ret = internal && win->internal_pixel_format ? win->internal_pixel_format : win->pixel_format;
From: Rémi Bernon rbernon@codeweavers.com
With format == 0 if internal pixel format was previously requested.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846 --- dlls/wined3d/context_gl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index ac1b9370fc1..ad2a50a66f1 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -1260,6 +1260,7 @@ success:
static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context_gl) { + const struct wined3d_gl_info *gl_info = context_gl->gl_info; struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); BOOL backup = FALSE;
@@ -1286,7 +1287,10 @@ static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context return FALSE; }
+ if (context_gl->internal_format_set) + GL_EXTCALL(wglSetPixelFormatWINE(context_gl->dc, 0)); 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); @@ -1332,6 +1336,8 @@ static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HD
static void wined3d_context_gl_update_window(struct wined3d_context_gl *context_gl) { + const struct wined3d_gl_info *gl_info = context_gl->gl_info; + if (!context_gl->c.swapchain) return;
@@ -1342,7 +1348,11 @@ static void wined3d_context_gl_update_window(struct wined3d_context_gl *context_ context_gl, context_gl->window, context_gl->c.swapchain->win_handle);
if (context_gl->dc) + { + if (context_gl->internal_format_set) + GL_EXTCALL(wglSetPixelFormatWINE(context_gl->dc, 0)); wined3d_release_dc(context_gl->window, context_gl->dc); + }
context_gl->window = context_gl->c.swapchain->win_handle; context_gl->dc_is_private = FALSE; @@ -1542,6 +1552,8 @@ 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");
+ if (context_gl->internal_format_set) + GL_EXTCALL(wglSetPixelFormatWINE(context_gl->dc, 0)); wined3d_release_dc(context_gl->window, context_gl->dc);
if (!wglDeleteContext(context_gl->gl_ctx))
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846 --- dlls/win32u/opengl.c | 49 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 2c028625faf..6b1a005f92b 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1454,7 +1454,7 @@ static BOOL flush_memory_dc( struct wgl_context *context, HDC hdc, BOOL write, v return ret; }
-static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) +static BOOL win32u_wglSetPixelFormat( HDC hdc, int new_format, const PIXELFORMATDESCRIPTOR *pfd ) { const struct opengl_funcs *funcs = &display_funcs; UINT total, onscreen; @@ -1474,9 +1474,9 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) return FALSE; }
- TRACE( "%p/%p format %d, internal %u\n", hdc, hwnd, new_format, internal ); + TRACE( "%p/%p format %d\n", hdc, hwnd, new_format );
- if ((old_format = get_window_pixel_format( hwnd, FALSE )) && !internal) return old_format == new_format; + if ((old_format = get_window_pixel_format( hwnd, FALSE ))) return old_format == new_format;
if ((drawable = get_window_unused_drawable( hwnd, new_format ))) { @@ -1485,28 +1485,51 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) opengl_drawable_release( drawable ); }
- return set_window_pixel_format( hwnd, new_format, internal ); + return set_window_pixel_format( hwnd, new_format, FALSE ); }
- TRACE( "%p/%p format %d, internal %u\n", hdc, hwnd, new_format, internal ); + TRACE( "%p/%p format %d\n", hdc, hwnd, new_format ); return NtGdiSetPixelFormat( hdc, new_format ); }
-static BOOL win32u_wglSetPixelFormat( HDC hdc, int format, const PIXELFORMATDESCRIPTOR *pfd ) -{ - return set_dc_pixel_format( hdc, format, FALSE ); -} - static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) { + const struct opengl_funcs *funcs = &display_funcs; + struct opengl_drawable *drawable; + UINT total, onscreen; + HWND hwnd; DC *dc;
- if (format && !set_dc_pixel_format( hdc, format, TRUE )) return FALSE; + if (!(hwnd = NtUserWindowFromDC( hdc ))) return FALSE; + + TRACE( "%p/%p format %d\n", hdc, hwnd, format ); + + funcs->p_get_pixel_formats( NULL, 0, &total, &onscreen ); + if (format < 0 || format > total) return FALSE; + if (format > onscreen) + { + WARN( "Invalid format %d for %p/%p\n", format, hdc, hwnd ); + return FALSE; + }
if (!(dc = get_dc_ptr( hdc ))) return FALSE; dc->pixel_format = format; + drawable = dc->opengl_drawable; + dc->opengl_drawable = NULL; release_dc_ptr( dc );
+ if (drawable && drawable->format != format) + { + opengl_drawable_release( drawable ); + drawable = NULL; + } + if (format && (drawable || (drawable = get_window_unused_drawable( hwnd, format )))) + { + set_window_opengl_drawable( hwnd, drawable, TRUE ); + set_dc_opengl_drawable( hdc, drawable ); + opengl_drawable_release( drawable ); + } + return TRUE; }
@@ -1577,6 +1600,10 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H struct wgl_context *previous = NtCurrentTeb()->glContext; BOOL ret = FALSE;
+ /* retrieve the D3D internal drawables from the DCs if they have any */ + if (draw_hdc && !context->draw) context->draw = get_dc_opengl_drawable( draw_hdc ); + if (read_hdc && !context->read) context->read = get_dc_opengl_drawable( read_hdc ); + new_draw = get_updated_drawable( draw_hdc, context->format, context->draw ); if (!draw_hdc && context->draw == context->read) opengl_drawable_add_ref( (new_read = new_draw) ); else if (draw_hdc && draw_hdc == read_hdc) opengl_drawable_add_ref( (new_read = new_draw) );
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846 --- dlls/win32u/ntuser_private.h | 1 - dlls/win32u/opengl.c | 10 +++++----- dlls/win32u/win32u_private.h | 4 ++-- dlls/win32u/window.c | 18 ++++++------------ 4 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 1d0131e5886..a9540abb576 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -72,7 +72,6 @@ typedef struct tagWND struct tagDIALOGINFO *dlgInfo; /* Dialog additional info (dialogs only) */ int swap_interval; /* OpenGL surface swap interval */ int pixel_format; /* Pixel format set by the graphics driver */ - int internal_pixel_format; /* Internal pixel format set via WGL_WINE_pixel_format_passthrough */ int cbWndExtra; /* class cbWndExtra at window creation */ DWORD_PTR userdata; /* User private data */ DWORD wExtra[1]; /* Window extra bytes */ diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 6b1a005f92b..67baaf31bb1 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1276,7 +1276,7 @@ static int win32u_wglGetPixelFormat( HDC hdc ) HWND hwnd;
if ((hwnd = NtUserWindowFromDC( hdc ))) - format = get_window_pixel_format( hwnd, FALSE ); + format = get_window_pixel_format( hwnd ); else if ((format = get_dc_pixel_format( hdc )) < 0) { WARN( "Invalid DC handle %p\n", hdc ); @@ -1476,7 +1476,7 @@ static BOOL win32u_wglSetPixelFormat( HDC hdc, int new_format, const PIXELFORMAT
TRACE( "%p/%p format %d\n", hdc, hwnd, new_format );
- if ((old_format = get_window_pixel_format( hwnd, FALSE ))) return old_format == new_format; + if ((old_format = get_window_pixel_format( hwnd ))) return old_format == new_format;
if ((drawable = get_window_unused_drawable( hwnd, new_format ))) { @@ -1485,7 +1485,7 @@ static BOOL win32u_wglSetPixelFormat( HDC hdc, int new_format, const PIXELFORMAT opengl_drawable_release( drawable ); }
- return set_window_pixel_format( hwnd, new_format, FALSE ); + return set_window_pixel_format( hwnd, new_format ); }
TRACE( "%p/%p format %d\n", hdc, hwnd, new_format ); @@ -1708,7 +1708,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct }
if ((format = get_dc_pixel_format( draw_hdc )) <= 0 && - (format = get_window_pixel_format( NtUserWindowFromDC( draw_hdc ), FALSE )) <= 0) + (format = get_window_pixel_format( NtUserWindowFromDC( draw_hdc ) )) <= 0) { WARN( "Invalid draw_hdc %p format %u\n", draw_hdc, format ); if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); @@ -2170,7 +2170,7 @@ static BOOL win32u_wgl_context_reset( struct wgl_context *context, HDC hdc, stru if (!hdc) return TRUE;
if ((format = get_dc_pixel_format( hdc )) <= 0 && - (format = get_window_pixel_format( NtUserWindowFromDC( hdc ), FALSE )) <= 0) + (format = get_window_pixel_format( NtUserWindowFromDC( hdc ) )) <= 0) { if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); else RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index ba0a9834d9f..3cc25d90d5b 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -275,8 +275,8 @@ extern BOOL is_window_enabled( HWND hwnd ); extern BOOL is_window_unicode( HWND hwnd ); extern BOOL is_window_visible( HWND hwnd ); extern BOOL is_zoomed( HWND hwnd ); -extern BOOL set_window_pixel_format( HWND hwnd, int format, BOOL internal ); -extern int get_window_pixel_format( HWND hwnd, BOOL internal ); +extern BOOL set_window_pixel_format( HWND hwnd, int format ); +extern int get_window_pixel_format( HWND hwnd ); extern DWORD get_window_long( HWND hwnd, INT offset ); extern ULONG_PTR get_window_long_ptr( HWND hwnd, INT offset, BOOL ansi ); extern BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 8a026a3c189..c4ca7e8169f 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1538,7 +1538,7 @@ LONG_PTR WINAPI NtUserSetWindowLongPtr( HWND hwnd, INT offset, LONG_PTR newval, return set_window_long( hwnd, offset, sizeof(LONG_PTR), newval, ansi ); }
-BOOL set_window_pixel_format( HWND hwnd, int format, BOOL internal ) +BOOL set_window_pixel_format( HWND hwnd, int format ) { WND *win = get_win_ptr( hwnd );
@@ -1547,20 +1547,14 @@ BOOL set_window_pixel_format( HWND hwnd, int format, BOOL internal ) WARN( "setting format %d on win %p not supported\n", format, hwnd ); return FALSE; } - if (internal) - win->internal_pixel_format = format; - else - { - win->internal_pixel_format = 0; - win->pixel_format = format; - } + win->pixel_format = format; release_win_ptr( win );
update_window_state( hwnd ); return TRUE; }
-int get_window_pixel_format( HWND hwnd, BOOL internal ) +int get_window_pixel_format( HWND hwnd ) { WND *win = get_win_ptr( hwnd ); int ret; @@ -1571,7 +1565,7 @@ int get_window_pixel_format( HWND hwnd, BOOL internal ) return -1; }
- ret = internal && win->internal_pixel_format ? win->internal_pixel_format : win->pixel_format; + ret = win->pixel_format; release_win_ptr( win );
return ret; @@ -1584,7 +1578,7 @@ static int window_has_client_surface( HWND hwnd ) BOOL ret;
if (!win || win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE; - ret = win->pixel_format || win->internal_pixel_format; + ret = win->pixel_format || win->current_drawable; release_win_ptr( win ); if (ret) return TRUE;
@@ -2210,7 +2204,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru } if (new_surface) req->paint_flags |= SET_WINPOS_PAINT_SURFACE; if (is_layered) req->paint_flags |= SET_WINPOS_LAYERED_WINDOW; - if (win->pixel_format || win->internal_pixel_format) + if (win->pixel_format || win->current_drawable) req->paint_flags |= SET_WINPOS_PIXEL_FORMAT;
if ((ret = !wine_server_call( req )))
From: Rémi Bernon rbernon@codeweavers.com
Internal pixel format is now fully hidden from applications and local to the context DC.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846 --- dlls/wined3d/context_gl.c | 42 --------------------------------------- dlls/wined3d/wined3d_gl.h | 2 -- 2 files changed, 44 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index ad2a50a66f1..61bf38cdafc 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -1162,38 +1162,6 @@ void wined3d_context_gl_texture_update(struct wined3d_context_gl *context_gl, } }
-static BOOL wined3d_context_gl_restore_pixel_format(struct wined3d_context_gl *context_gl) -{ - const struct wined3d_gl_info *gl_info = context_gl->gl_info; - BOOL ret = FALSE; - - if (context_gl->restore_pf && IsWindow(context_gl->restore_pf_win)) - { - if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) - { - HDC dc = GetDCEx(context_gl->restore_pf_win, 0, DCX_USESTYLE | DCX_CACHE); - if (dc) - { - if (!(ret = GL_EXTCALL(wglSetPixelFormatWINE(dc, context_gl->restore_pf)))) - { - ERR("Failed to restore pixel format %d on window %p.\n", - context_gl->restore_pf, context_gl->restore_pf_win); - } - ReleaseDC(context_gl->restore_pf_win, dc); - } - } - else - { - ERR("Unable to restore pixel format %d on window %p.\n", - context_gl->restore_pf, context_gl->restore_pf_win); - } - } - - context_gl->restore_pf = 0; - context_gl->restore_pf_win = NULL; - return ret; -} - static BOOL wined3d_context_gl_set_pixel_format(struct wined3d_context_gl *context_gl) { const struct wined3d_gl_info *gl_info = context_gl->gl_info; @@ -1201,7 +1169,6 @@ static BOOL wined3d_context_gl_set_pixel_format(struct wined3d_context_gl *conte int format = context_gl->pixel_format; HDC dc = context_gl->dc; int current; - HWND win;
if (private && context_gl->dc_has_format) return TRUE; @@ -1246,12 +1213,6 @@ static BOOL wined3d_context_gl_set_pixel_format(struct wined3d_context_gl *conte return FALSE; }
- win = private ? NULL : WindowFromDC(dc); - if (win != context_gl->restore_pf_win) - wined3d_context_gl_restore_pixel_format(context_gl); - context_gl->restore_pf = private ? 0 : current; - context_gl->restore_pf_win = win; - success: if (private) context_gl->dc_has_format = TRUE; @@ -1546,7 +1507,6 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
free(context_gl->texture_type);
- wined3d_context_gl_restore_pixel_format(context_gl); if (restore_ctx) context_restore_gl_context(gl_info, restore_dc, restore_ctx); else if (wglGetCurrentContext() && !wglMakeCurrent(NULL, NULL)) @@ -1654,8 +1614,6 @@ void wined3d_context_gl_release(struct wined3d_context_gl *context_gl)
if (!--context_gl->level) { - if (wined3d_context_gl_restore_pixel_format(context_gl)) - context_gl->needs_set = 1; if (context_gl->restore_ctx) { TRACE("Restoring GL context %p on device context %p.\n", context_gl->restore_ctx, context_gl->restore_dc); diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 5e35e723958..a3d54fe5c19 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -644,8 +644,6 @@ struct wined3d_context_gl unsigned int level; HGLRC restore_ctx; HDC restore_dc; - int restore_pf; - HWND restore_pf_win; HGLRC gl_ctx; HDC dc; int pixel_format;
We just failed to set the pixel format, so I don't think there's any reason to unset it here.
We can get there if setting pixel format succeeded but somehow wglMakeCurrent didn't, in which case we need to undo what we did.
Eh, okay. I'd prefer to clean it up in wined3d_context_gl_set_gl_context() then though; it's more idiomatic to have functions leave state alone on failure.
Before 2/4 this is just illegal, and after 2/4 the pixel format is per-DC, and we're releasing the DCs here, so this should have no effect?
But that's the point? `wglSetPixelFormatWINE(dc, 0)` is meant to be an explicit request to undo what was done in `wglSetPixelFormatWINE(dc, format)` and reset the DC internal pixel format and drawable, to avoid doing it `ReleaseDC` which has proven problematic in the past.
Wait, what? That's the first I've heard about it; what's the problem with doing it in ReleaseDC()? Or even, how can it be a problem to not reset the pixel format for a DC we're about to destroy?
Wait, what? That's the first I've heard about it; what's the problem with doing it in ReleaseDC()? Or even, how can it be a problem to not reset the pixel format for a DC we're about to destroy?
ReleaseDC does not destroy the DC, it adds it back to some cache which has some complicated logic I don't really want to mess with. The issue then comes from the internal OpenGL surfaces, when they are owned by window DCs, as their creation / destruction might require other GDI calls involving all sorts of convoluted locking.
It was not a problem until the recent refactoring to move OpenGL surface management out of the display drivers, and also ReleaseDC didn't cause any problem because it simply never had to do anything like this.
Now, we need to support multiple OpenGL surfaces alive because of wined3d requirements, we have a Wine-specific extension for that, I think tweaking that extension to make wined3d / win32u cooperation more explicit should be alright?
Eh, okay. I'd prefer to clean it up in wined3d_context_gl_set_gl_context() then though; it's more idiomatic to have functions leave state alone on failure.
I don't get it, it's what is being done? wined3d_context_gl_set_gl_context() already cleans things up by releasing the context DCs it previously acquired to try the backup one (https://gitlab.winehq.org/wine/wine/-/merge_requests/9382/diffs?commit_id=89...), this only adds an extra call to reset the internal pixel format it may have changed too.