From: Rémi Bernon rbernon@codeweavers.com
Instead of when it is reset, so that releasing a window DC then acquiring it again will keep its allocated OpenGL surface or update it to the latest window surface when acquiring a DC previously associated with another window.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58448 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58459 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58488 --- dlls/win32u/dc.c | 6 +----- dlls/win32u/dce.c | 8 ++++++++ dlls/win32u/win32u_private.h | 7 +++++++ 3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c index 94946d9ad23..47981dd867d 100644 --- a/dlls/win32u/dc.c +++ b/dlls/win32u/dc.c @@ -248,6 +248,7 @@ DC *alloc_dc_ptr( DWORD magic ) */ static void free_dc_state( DC *dc ) { + if (dc->opengl_drawable) opengl_drawable_release( dc->opengl_drawable ); if (dc->hClipRgn) NtGdiDeleteObjectApp( dc->hClipRgn ); if (dc->hMetaRgn) NtGdiDeleteObjectApp( dc->hMetaRgn ); if (dc->hVisRgn) NtGdiDeleteObjectApp( dc->hVisRgn ); @@ -458,7 +459,6 @@ void DC_UpdateXforms( DC *dc ) */ static BOOL reset_dc_state( HDC hdc ) { - struct opengl_drawable *drawable; DC *dc, *dcs, *next;
if (!(dc = get_dc_ptr( hdc ))) return FALSE; @@ -487,12 +487,8 @@ static BOOL reset_dc_state( HDC hdc ) } dc->saved_dc = NULL; dc->attr->save_level = 0; - - drawable = dc->opengl_drawable; - dc->opengl_drawable = NULL; release_dc_ptr( dc );
- if (drawable) opengl_drawable_release( drawable ); return TRUE; }
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 3e258d837dd..29f11e18256 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -29,6 +29,7 @@ #define WIN32_NO_STATUS #include "ntgdi_private.h" #include "ntuser_private.h" +#include "wine/opengl_driver.h" #include "wine/server.h" #include "wine/debug.h"
@@ -885,6 +886,7 @@ static void release_dce( struct dce *dce )
set_visible_region( dce->hdc, 0, &dummy_surface.rect, &dummy_surface.rect, &dummy_surface ); user_driver->pReleaseDC( dce->hwnd, dce->hdc ); + set_dc_opengl_drawable( dce->hdc, NULL );
if (dce->clip_rgn) NtGdiDeleteObjectApp( dce->clip_rgn ); dce->clip_rgn = 0; @@ -1362,6 +1364,12 @@ HDC WINAPI NtUserGetDCEx( HWND hwnd, HRGN clip_rgn, DWORD flags ) if (get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) NtGdiSetLayout( dce->hdc, -1, LAYOUT_RTL );
+ if (dce->hwnd != hwnd) + { + struct opengl_drawable *drawable = get_window_opengl_drawable( hwnd ); + set_dc_opengl_drawable( dce->hdc, drawable ); + if (drawable) opengl_drawable_release( drawable ); + } dce->hwnd = hwnd; dce->flags = (dce->flags & ~user_flags) | (flags & user_flags);
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 3018321c3ed..780e8cd26cc 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -190,6 +190,13 @@ extern void user_lock(void); extern void user_unlock(void); extern void user_check_not_lock(void);
+/* opengl.c */ + +struct opengl_drawable; +void set_dc_opengl_drawable( HDC hdc, struct opengl_drawable *new_drawable ); + +/* d3dkmtc. */ + struct vulkan_gpu { struct list entry;