Module: wine Branch: master Commit: feff51071726c1b543ed6cabd997a52b5d93304a URL: https://gitlab.winehq.org/wine/wine/-/commit/feff51071726c1b543ed6cabd997a52...
Author: Rémi Bernon rbernon@codeweavers.com Date: Tue Jun 4 09:14:04 2024 +0200
win32u: Use a dedicated helper to move bits from a previous surface.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56766
---
dlls/win32u/dce.c | 98 ++++++++++++++++++++++---------------------- dlls/win32u/win32u_private.h | 6 +-- dlls/win32u/window.c | 6 ++- 3 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 34acb1d10f6..04c0fdfa248 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1194,62 +1194,72 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, * * Copy bits from a window surface; helper for move_window_bits and move_window_bits_parent. */ -static void copy_bits_from_surface( HWND hwnd, struct window_surface *surface, - const RECT *dst, const RECT *src, BOOL same ) +static void copy_bits_from_surface( HWND hwnd, const RECT *dst, const RECT *src ) { - char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; - BITMAPINFO *info = (BITMAPINFO *)buffer; - void *bits; UINT flags = UPDATE_NOCHILDREN | UPDATE_CLIPCHILDREN; HRGN rgn = get_update_region( hwnd, &flags, NULL ); HDC hdc = NtUserGetDCEx( hwnd, rgn, DCX_CACHE | DCX_WINDOW | DCX_EXCLUDERGN );
- if (same) - { - RECT rect = *src; - NtGdiStretchBlt( hdc, dst->left, dst->top, dst->right - dst->left, dst->bottom - dst->top, - hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SRCCOPY, 0 ); - } - else - { - bits = surface->funcs->get_info( surface, info ); - window_surface_lock( surface ); - NtGdiSetDIBitsToDeviceInternal( hdc, dst->left, dst->top, dst->right - dst->left, dst->bottom - dst->top, - src->left - surface->rect.left, surface->rect.bottom - src->bottom, - 0, surface->rect.bottom - surface->rect.top, - bits, info, DIB_RGB_COLORS, 0, 0, FALSE, NULL ); - window_surface_unlock( surface ); - } - + NtGdiStretchBlt( hdc, dst->left, dst->top, dst->right - dst->left, dst->bottom - dst->top, + hdc, src->left, src->top, src->right - src->left, src->bottom - src->top, SRCCOPY, 0 ); NtUserReleaseDC( hwnd, hdc ); }
/*********************************************************************** * move_window_bits * - * Move the window bits when a window is resized or its surface recreated. + * Move the window bits when a window is resized. */ -void move_window_bits( HWND hwnd, struct window_surface *old_surface, - struct window_surface *new_surface, - const RECT *visible_rect, const RECT *old_visible_rect, +void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, const RECT *window_rect, const RECT *valid_rects ) { RECT dst = valid_rects[0]; RECT src = valid_rects[1];
- if (new_surface != old_surface || - src.left - old_visible_rect->left != dst.left - visible_rect->left || + if (src.left - old_visible_rect->left != dst.left - visible_rect->left || src.top - old_visible_rect->top != dst.top - visible_rect->top) { TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); - if (new_surface != old_surface) OffsetRect( &src, -old_visible_rect->left, -old_visible_rect->top ); - else OffsetRect( &src, -window_rect->left, -window_rect->top ); + OffsetRect( &src, -window_rect->left, -window_rect->top ); OffsetRect( &dst, -window_rect->left, -window_rect->top ); - copy_bits_from_surface( hwnd, old_surface, &dst, &src, new_surface == old_surface ); + copy_bits_from_surface( hwnd, &dst, &src ); } }
+/*********************************************************************** + * move_window_bits_surface + * + * Move the window bits from a previous window surface when its surface is recreated. + */ +void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct window_surface *old_surface, + const RECT *old_visible_rect, const RECT *valid_rects ) +{ + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + UINT flags = UPDATE_NOCHILDREN | UPDATE_CLIPCHILDREN; + HRGN rgn = get_update_region( hwnd, &flags, NULL ); + HDC hdc = NtUserGetDCEx( hwnd, rgn, DCX_CACHE | DCX_WINDOW | DCX_EXCLUDERGN ); + void *bits; + + RECT dst = valid_rects[0]; + RECT src = valid_rects[1]; + + TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); + OffsetRect( &src, -old_visible_rect->left, -old_visible_rect->top ); + OffsetRect( &dst, -window_rect->left, -window_rect->top ); + + bits = old_surface->funcs->get_info( old_surface, info ); + window_surface_lock( old_surface ); + NtGdiSetDIBitsToDeviceInternal( hdc, dst.left, dst.top, dst.right - dst.left, dst.bottom - dst.top, + src.left - old_surface->rect.left, old_surface->rect.bottom - src.bottom, + 0, old_surface->rect.bottom - old_surface->rect.top, + bits, info, DIB_RGB_COLORS, 0, 0, FALSE, NULL ); + window_surface_unlock( old_surface ); + NtUserReleaseDC( hwnd, hdc ); +} + + /*********************************************************************** * move_window_bits_parent * @@ -1257,30 +1267,18 @@ void move_window_bits( HWND hwnd, struct window_surface *old_surface, */ void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, const RECT *valid_rects ) { - struct window_surface *surface; RECT dst = valid_rects[0]; RECT src = valid_rects[1]; - WND *win; - - if (src.left == dst.left && src.top == dst.top) return;
- if (!(win = get_win_ptr( parent ))) return; - if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) return; - if (!(surface = win->surface)) + if (src.left != dst.left || src.top != dst.top) { - release_win_ptr( win ); - return; - } - - TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); - map_window_points( NtUserGetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2, get_thread_dpi() ); - OffsetRect( &src, -window_rect->left, -window_rect->top ); - OffsetRect( &dst, -window_rect->left, -window_rect->top ); - window_surface_add_ref( surface ); - release_win_ptr( win ); + TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); + map_window_points( NtUserGetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2, get_thread_dpi() ); + OffsetRect( &src, -window_rect->left, -window_rect->top ); + OffsetRect( &dst, -window_rect->left, -window_rect->top );
- copy_bits_from_surface( hwnd, surface, &dst, &src, TRUE ); - window_surface_release( surface ); + copy_bits_from_surface( hwnd, &dst, &src ); + } }
/*********************************************************************** diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 8aed662d2d8..54b3798d8fb 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -49,10 +49,10 @@ extern void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect struct window_surface **surface ); extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void flush_window_surfaces( BOOL idle ); -extern void move_window_bits( HWND hwnd, struct window_surface *old_surface, - struct window_surface *new_surface, - const RECT *visible_rect, const RECT *old_visible_rect, +extern void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, const RECT *window_rect, const RECT *valid_rects ); +extern void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct window_surface *old_surface, + const RECT *old_visible_rect, const RECT *valid_rects ); extern void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, const RECT *valid_rects ); extern void register_window_surface( struct window_surface *old, diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 12f2a9027f0..22e9e326d6e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1929,8 +1929,10 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, { if (valid_rects) { - move_window_bits( hwnd, old_surface, new_surface, &visible_rect, - &old_visible_rect, window_rect, valid_rects ); + if (old_surface != new_surface) + move_window_bits_surface( hwnd, window_rect, old_surface, &old_visible_rect, valid_rects ); + else + move_window_bits( hwnd, &visible_rect, &old_visible_rect, window_rect, valid_rects ); valid_rects = NULL; /* prevent the driver from trying to also move the bits */ } window_surface_release( old_surface );