Module: wine Branch: master Commit: 0d2fa879d735cd39e72c15014686001c13a089b8 URL: https://gitlab.winehq.org/wine/wine/-/commit/0d2fa879d735cd39e72c15014686001...
Author: Rémi Bernon rbernon@codeweavers.com Date: Thu Apr 11 16:58:49 2024 +0200
win32u: Remove surface recursive locking requirement.
---
dlls/win32u/dce.c | 36 +++++++++++++++++++++++------------- dlls/win32u/dibdrv/dc.c | 4 ++-- 2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 5c4f691b460..d304074c427 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1140,7 +1140,7 @@ 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 ) + const RECT *dst, const RECT *src, BOOL same ) { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; @@ -1149,13 +1149,23 @@ static void copy_bits_from_surface( HWND hwnd, struct window_surface *surface, HRGN rgn = get_update_region( hwnd, &flags, NULL ); HDC hdc = NtUserGetDCEx( hwnd, rgn, DCX_CACHE | DCX_WINDOW | DCX_EXCLUDERGN );
- bits = surface->funcs->get_info( surface, info ); - surface->funcs->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 ); - surface->funcs->unlock( surface ); + 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 ); + surface->funcs->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 ); + surface->funcs->unlock( surface ); + } + NtUserReleaseDC( hwnd, hdc ); }
@@ -1177,9 +1187,10 @@ void move_window_bits( HWND hwnd, struct window_surface *old_surface, src.top - old_visible_rect->top != dst.top - visible_rect->top) { TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); - OffsetRect( &src, -old_visible_rect->left, -old_visible_rect->top ); + 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( &dst, -window_rect->left, -window_rect->top ); - copy_bits_from_surface( hwnd, old_surface, &dst, &src ); + copy_bits_from_surface( hwnd, old_surface, &dst, &src, new_surface == old_surface ); } }
@@ -1208,13 +1219,12 @@ void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, c
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, win->client_rect.left - win->visible_rect.left, - win->client_rect.top - win->visible_rect.top ); + 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 );
- copy_bits_from_surface( hwnd, surface, &dst, &src ); + copy_bits_from_surface( hwnd, surface, &dst, &src, TRUE ); window_surface_release( surface ); }
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index e1b2f66cb25..48cbe51d708 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -749,9 +749,9 @@ static inline void lock_surface( struct windrv_physdev *dev ) { struct window_surface *surface = dev->surface;
- surface->funcs->lock( surface ); if (!dev->lock_count++) { + surface->funcs->lock( surface ); if (IsRectEmpty( dev->dibdrv->bounds ) || !surface->draw_start_ticks) surface->draw_start_ticks = NtGetTickCount(); } @@ -761,10 +761,10 @@ static inline void unlock_surface( struct windrv_physdev *dev ) { struct window_surface *surface = dev->surface;
- surface->funcs->unlock( surface ); if (!--dev->lock_count) { DWORD ticks = NtGetTickCount() - surface->draw_start_ticks; + surface->funcs->unlock( surface ); if (ticks > FLUSH_PERIOD) surface->funcs->flush( dev->surface ); } }