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.
-- v5: win32u: Get rid of window internal pixel format. win32u: Keep the D3D internal OpenGL surfaces on the DCs. 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/dce.c | 14 +++++++++ dlls/win32u/ntgdi_private.h | 2 ++ dlls/win32u/ntuser_private.h | 4 +++ dlls/win32u/opengl.c | 59 +++++++++++++++++++++--------------- dlls/win32u/window.c | 2 +- 6 files changed, 78 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/dce.c b/dlls/win32u/dce.c index 4dcddd2059a..c70482d4522 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1102,6 +1102,7 @@ void free_dce( struct dce *dce, HWND hwnd ) { WARN( "GetDC() without ReleaseDC() for window %p\n", hwnd ); dce->count = 0; + set_dc_pixel_format_internal( dce->hdc, 0 ); set_dce_flags( dce->hdc, DCHF_DISABLEDC ); } } @@ -1117,6 +1118,18 @@ void free_dce( struct dce *dce, HWND hwnd ) } }
+BOOL is_cache_dc( HDC hdc ) +{ + BOOL ret = FALSE; + struct dce *dce; + + user_lock(); + if ((dce = get_dc_dce( hdc ))) ret = !!(dce->flags & DCX_CACHE); + user_unlock(); + + return ret; +} + /*********************************************************************** * make_dc_dirty * @@ -1224,6 +1237,7 @@ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint ) if (dce->flags & DCX_CACHE) { dce->count = 0; + set_dc_pixel_format_internal( hdc, 0 ); set_dce_flags( dce->hdc, DCHF_DISABLEDC ); } ret = TRUE; 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/ntuser_private.h b/dlls/win32u/ntuser_private.h index 1d0131e5886..f62b7691ba2 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -211,6 +211,7 @@ HICON alloc_cursoricon_handle( BOOL is_icon ); /* dce.c */ extern void free_dce( struct dce *dce, HWND hwnd ); extern void invalidate_dce( WND *win, const RECT *old_rect ); +extern BOOL is_cache_dc( HDC hdc );
/* message.c */ extern void check_for_events( UINT flags ); @@ -218,6 +219,9 @@ extern void check_for_events( UINT flags ); /* systray.c */ extern LRESULT system_tray_call( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, void *data );
+/* opengl.c */ +extern BOOL set_dc_pixel_format_internal( HDC hdc, int format ); + /* vulkan.c */ extern PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr; extern PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index fc0be5795d4..4ceffe35b07 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; }
@@ -1509,9 +1497,26 @@ static BOOL win32u_wglSetPixelFormat( HDC hdc, int format, const PIXELFORMATDESC return set_dc_pixel_format( hdc, format, FALSE ); }
+BOOL set_dc_pixel_format_internal( HDC hdc, int format ) +{ + DC *dc; + + if (!(dc = get_dc_ptr( hdc ))) return FALSE; + dc->pixel_format = format; + release_dc_ptr( dc ); + + return TRUE; +} + static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) { - return set_dc_pixel_format( hdc, format, TRUE ); + HWND hwnd; + + if (!(hwnd = NtUserWindowFromDC( hdc )) || !is_cache_dc( hdc )) return FALSE; + if (format && get_window_pixel_format( hwnd, FALSE ) == format) return TRUE; + + if (!set_dc_pixel_format( hdc, format, TRUE )) return FALSE; + return set_dc_pixel_format_internal( hdc, format ); }
static PROC win32u_wglGetProcAddress( const char *name ) @@ -1684,10 +1689,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 +2151,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
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846 --- dlls/win32u/dce.c | 10 ++++++-- dlls/win32u/ntuser_private.h | 2 +- dlls/win32u/opengl.c | 49 ++++++++++++++++++++++++++---------- 3 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index c70482d4522..c84ba693509 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1070,6 +1070,7 @@ static struct dce *get_window_dce( HWND hwnd ) */ void free_dce( struct dce *dce, HWND hwnd ) { + struct opengl_drawable *drawable = NULL; struct dce *dce_to_free = NULL;
user_lock(); @@ -1102,7 +1103,7 @@ void free_dce( struct dce *dce, HWND hwnd ) { WARN( "GetDC() without ReleaseDC() for window %p\n", hwnd ); dce->count = 0; - set_dc_pixel_format_internal( dce->hdc, 0 ); + set_dc_pixel_format_internal( dce->hdc, 0, &drawable ); set_dce_flags( dce->hdc, DCHF_DISABLEDC ); } } @@ -1116,6 +1117,8 @@ void free_dce( struct dce *dce, HWND hwnd ) NtGdiDeleteObjectApp( dce_to_free->hdc ); free( dce_to_free ); } + + if (drawable) opengl_drawable_release( drawable ); }
BOOL is_cache_dc( HDC hdc ) @@ -1223,6 +1226,7 @@ void invalidate_dce( WND *win, const RECT *old_rect ) */ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint ) { + struct opengl_drawable *drawable = NULL; struct dce *dce; BOOL ret = FALSE;
@@ -1237,12 +1241,14 @@ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint ) if (dce->flags & DCX_CACHE) { dce->count = 0; - set_dc_pixel_format_internal( hdc, 0 ); + set_dc_pixel_format_internal( hdc, 0, &drawable ); set_dce_flags( dce->hdc, DCHF_DISABLEDC ); } ret = TRUE; } user_unlock(); + + if (drawable) opengl_drawable_release( drawable ); return ret; }
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index f62b7691ba2..2e03f0d732a 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -220,7 +220,7 @@ extern void check_for_events( UINT flags ); extern LRESULT system_tray_call( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, void *data );
/* opengl.c */ -extern BOOL set_dc_pixel_format_internal( HDC hdc, int format ); +extern BOOL set_dc_pixel_format_internal( HDC hdc, int format, struct opengl_drawable **drawable );
/* vulkan.c */ extern PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 4ceffe35b07..2c12c0da6ea 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,24 +1485,21 @@ 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 ); -} - -BOOL set_dc_pixel_format_internal( HDC hdc, int format ) +BOOL set_dc_pixel_format_internal( HDC hdc, int format, struct opengl_drawable **drawable ) { DC *dc;
if (!(dc = get_dc_ptr( hdc ))) return FALSE; dc->pixel_format = format; + *drawable = dc->opengl_drawable; + dc->opengl_drawable = NULL; release_dc_ptr( dc );
return TRUE; @@ -1510,13 +1507,35 @@ BOOL set_dc_pixel_format_internal( HDC hdc, int format )
static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) { + const struct opengl_funcs *funcs = &display_funcs; + struct opengl_drawable *drawable; + UINT total, onscreen; HWND hwnd;
if (!(hwnd = NtUserWindowFromDC( hdc )) || !is_cache_dc( hdc )) return FALSE; if (format && get_window_pixel_format( hwnd, FALSE ) == format) return TRUE;
- if (!set_dc_pixel_format( hdc, format, TRUE )) return FALSE; - return set_dc_pixel_format_internal( hdc, format ); + 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) return FALSE; + + if (!set_dc_pixel_format_internal( hdc, format, &drawable )) return FALSE; + + 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; }
static PROC win32u_wglGetProcAddress( const char *name ) @@ -1586,6 +1605,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 | 12 ++++++------ dlls/win32u/win32u_private.h | 4 ++-- dlls/win32u/window.c | 18 ++++++------------ 4 files changed, 14 insertions(+), 21 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 2e03f0d732a..6cbee3b3da3 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 2c12c0da6ea..a3cad3f89cb 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 ); @@ -1513,7 +1513,7 @@ static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) HWND hwnd;
if (!(hwnd = NtUserWindowFromDC( hdc )) || !is_cache_dc( hdc )) return FALSE; - if (format && get_window_pixel_format( hwnd, FALSE ) == format) return TRUE; + if (format && get_window_pixel_format( hwnd ) == format) return TRUE;
TRACE( "%p/%p format %d\n", hdc, hwnd, format );
@@ -1713,7 +1713,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 ); @@ -2175,7 +2175,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 )))
v3: Keep the logic entirely in win32u, limiting support for internal pixel formats on cached window DCs, and releasing the OpenGL drawables when the DCs are released. The wined3d pixel format restoration could then be dropped but that would be done in a separate MR.
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.
I forgot that ReleaseDC() is different from DeleteDC(). I know that there's caching involved, but I thought it was of a form (mostly? entirely?) invisible to the application, and that the actual properties of a DC were always reset between GetDC() calls. Thanks for bearing with me while I recall how this works.
With that knowledge it makes more sense to reset the pixel format between calls on the d3d side. But I'm still confused, now because as I understand, part of the point of this patch is to separate the internal pixel format and entirely hide it. Why do we need to unset it when we're not using it, anywhere at all?
Because we need to release the D3D drawables at some point, and I thought it was good to do it explicitly the same way D3D explicitly requests internal format and drawable with the wglSetPixelFormatWINE calls.
Anyway, it's not needed anymore, I moved the cleanup to ReleaseDC, limited to the kind of DCs that wined3d uses, it should be good enough for now.